nfs: fix regression in handling of fsc= option in NFSv4
authorChen Hanxiao <chenhx.fnst@fujitsu.com>
Wed, 31 Jan 2024 09:49:17 +0000 (17:49 +0800)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 28 Feb 2024 21:18:19 +0000 (16:18 -0500)
Setting the uniquifier for fscache via the fsc= mount
option is currently broken in NFSv4.

Fix this by passing fscache_uniq to root_fc if possible.

Signed-off-by: Chen Hanxiao <chenhx.fnst@fujitsu.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/nfs4super.c

index d09bcfd7db89488eec9291c4e985e13953f079d3..8da5a9c000f42c3eda0d3b1f35ca45be96a253ae 100644 (file)
@@ -145,6 +145,7 @@ static int do_nfs4_mount(struct nfs_server *server,
                         const char *export_path)
 {
        struct nfs_fs_context *root_ctx;
+       struct nfs_fs_context *ctx;
        struct fs_context *root_fc;
        struct vfsmount *root_mnt;
        struct dentry *dentry;
@@ -157,6 +158,12 @@ static int do_nfs4_mount(struct nfs_server *server,
                .dirfd  = -1,
        };
 
+       struct fs_parameter param_fsc = {
+               .key    = "fsc",
+               .type   = fs_value_is_string,
+               .dirfd  = -1,
+       };
+
        if (IS_ERR(server))
                return PTR_ERR(server);
 
@@ -168,9 +175,26 @@ static int do_nfs4_mount(struct nfs_server *server,
        kfree(root_fc->source);
        root_fc->source = NULL;
 
+       ctx = nfs_fc2context(fc);
        root_ctx = nfs_fc2context(root_fc);
        root_ctx->internal = true;
        root_ctx->server = server;
+
+       if (ctx->fscache_uniq) {
+               len = strlen(ctx->fscache_uniq);
+               param_fsc.size = len;
+               param_fsc.string = kmemdup_nul(ctx->fscache_uniq, len, GFP_KERNEL);
+               if (param_fsc.string == NULL) {
+                       put_fs_context(root_fc);
+                       return -ENOMEM;
+               }
+               ret = vfs_parse_fs_param(root_fc, &param_fsc);
+               kfree(param_fsc.string);
+               if (ret < 0) {
+                       put_fs_context(root_fc);
+                       return ret;
+               }
+       }
        /* We leave export_path unset as it's not used to find the root. */
 
        len = strlen(hostname) + 5;