Commit b0ea262a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'nfs-for-5.6-3' of git://git.linux-nfs.org/projects/anna/linux-nfs

Pull NFS client bugfixes from Anna Schumaker:
 "These are mostly fscontext fixes, but there is also one that fixes
  collisions seen in fscache:

   - Ensure the fs_context has the correct fs_type when mounting and
     submounting

   - Fix leaking of ctx->nfs_server.hostname

   - Add minor version to fscache key to prevent collisions"

* tag 'nfs-for-5.6-3' of git://git.linux-nfs.org/projects/anna/linux-nfs:
  nfs: add minor version to nfs_server_key for fscache
  NFS: Fix leak of ctx->nfs_server.hostname
  NFS: Don't hard-code the fs_type when submounting
  NFS: Ensure the fs_context has the correct fs_type before mounting
parents 7e6d869f 55dee1bc
...@@ -153,6 +153,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) ...@@ -153,6 +153,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
goto error_0; goto error_0;
clp->cl_minorversion = cl_init->minorversion;
clp->cl_nfs_mod = cl_init->nfs_mod; clp->cl_nfs_mod = cl_init->nfs_mod;
if (!try_module_get(clp->cl_nfs_mod->owner)) if (!try_module_get(clp->cl_nfs_mod->owner))
goto error_dealloc; goto error_dealloc;
......
...@@ -832,6 +832,8 @@ static int nfs_parse_source(struct fs_context *fc, ...@@ -832,6 +832,8 @@ static int nfs_parse_source(struct fs_context *fc,
if (len > maxnamlen) if (len > maxnamlen)
goto out_hostname; goto out_hostname;
kfree(ctx->nfs_server.hostname);
/* N.B. caller will free nfs_server.hostname in all cases */ /* N.B. caller will free nfs_server.hostname in all cases */
ctx->nfs_server.hostname = kmemdup_nul(dev_name, len, GFP_KERNEL); ctx->nfs_server.hostname = kmemdup_nul(dev_name, len, GFP_KERNEL);
if (!ctx->nfs_server.hostname) if (!ctx->nfs_server.hostname)
...@@ -1240,6 +1242,13 @@ static int nfs_fs_context_validate(struct fs_context *fc) ...@@ -1240,6 +1242,13 @@ static int nfs_fs_context_validate(struct fs_context *fc)
} }
ctx->nfs_mod = nfs_mod; ctx->nfs_mod = nfs_mod;
} }
/* Ensure the filesystem context has the correct fs_type */
if (fc->fs_type != ctx->nfs_mod->nfs_fs) {
module_put(fc->fs_type->owner);
__module_get(ctx->nfs_mod->nfs_fs->owner);
fc->fs_type = ctx->nfs_mod->nfs_fs;
}
return 0; return 0;
out_no_device_name: out_no_device_name:
......
...@@ -31,6 +31,7 @@ static DEFINE_SPINLOCK(nfs_fscache_keys_lock); ...@@ -31,6 +31,7 @@ static DEFINE_SPINLOCK(nfs_fscache_keys_lock);
struct nfs_server_key { struct nfs_server_key {
struct { struct {
uint16_t nfsversion; /* NFS protocol version */ uint16_t nfsversion; /* NFS protocol version */
uint32_t minorversion; /* NFSv4 minor version */
uint16_t family; /* address family */ uint16_t family; /* address family */
__be16 port; /* IP port */ __be16 port; /* IP port */
} hdr; } hdr;
...@@ -55,6 +56,7 @@ void nfs_fscache_get_client_cookie(struct nfs_client *clp) ...@@ -55,6 +56,7 @@ void nfs_fscache_get_client_cookie(struct nfs_client *clp)
memset(&key, 0, sizeof(key)); memset(&key, 0, sizeof(key));
key.hdr.nfsversion = clp->rpc_ops->version; key.hdr.nfsversion = clp->rpc_ops->version;
key.hdr.minorversion = clp->cl_minorversion;
key.hdr.family = clp->cl_addr.ss_family; key.hdr.family = clp->cl_addr.ss_family;
switch (clp->cl_addr.ss_family) { switch (clp->cl_addr.ss_family) {
......
...@@ -153,7 +153,7 @@ struct vfsmount *nfs_d_automount(struct path *path) ...@@ -153,7 +153,7 @@ struct vfsmount *nfs_d_automount(struct path *path)
/* Open a new filesystem context, transferring parameters from the /* Open a new filesystem context, transferring parameters from the
* parent superblock, including the network namespace. * parent superblock, including the network namespace.
*/ */
fc = fs_context_for_submount(&nfs_fs_type, path->dentry); fc = fs_context_for_submount(path->mnt->mnt_sb->s_type, path->dentry);
if (IS_ERR(fc)) if (IS_ERR(fc))
return ERR_CAST(fc); return ERR_CAST(fc);
......
...@@ -216,7 +216,6 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init) ...@@ -216,7 +216,6 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
INIT_LIST_HEAD(&clp->cl_ds_clients); INIT_LIST_HEAD(&clp->cl_ds_clients);
rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client");
clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
clp->cl_minorversion = cl_init->minorversion;
clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion]; clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
clp->cl_mig_gen = 1; clp->cl_mig_gen = 1;
#if IS_ENABLED(CONFIG_NFS_V4_1) #if IS_ENABLED(CONFIG_NFS_V4_1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment