]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
NFSv4.1 mark qualified async operations as MOVEABLE tasks
authorOlga Kornievskaia <kolga@netapp.com>
Wed, 25 May 2022 16:12:59 +0000 (12:12 -0400)
committerStefan Bader <stefan.bader@canonical.com>
Wed, 10 Aug 2022 07:25:05 +0000 (09:25 +0200)
BugLink: https://bugs.launchpad.net/bugs/1981864
[ Upstream commit 118f09eda21d392e1eeb9f8a4bee044958cccf20 ]

Mark async operations such as RENAME, REMOVE, COMMIT MOVEABLE
for the nfsv4.1+ sessions.

Fixes: 85e39feead948 ("NFSv4.1 identify and mark RPC tasks that can move between transports")
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
fs/nfs/nfs4proc.c
fs/nfs/pagelist.c
fs/nfs/unlink.c
fs/nfs/write.c
include/linux/nfs_fs_sb.h

index b53bc0495ccb5ca84a2cb22cc0a0f4e0b42f1fd1..ce759f7e7f2d666c625101a5d0418abb4e95a4c0 100644 (file)
@@ -1169,7 +1169,7 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
 {
        unsigned short task_flags = 0;
 
-       if (server->nfs_client->cl_minorversion)
+       if (server->caps & NFS_CAP_MOVEABLE)
                task_flags = RPC_TASK_MOVEABLE;
        return nfs4_do_call_sync(clnt, server, msg, args, res, task_flags);
 }
@@ -2582,7 +2582,7 @@ static int nfs4_run_open_task(struct nfs4_opendata *data,
        };
        int status;
 
-       if (server->nfs_client->cl_minorversion)
+       if (nfs_server_capable(dir, NFS_CAP_MOVEABLE))
                task_setup_data.flags |= RPC_TASK_MOVEABLE;
 
        kref_get(&data->kref);
@@ -3765,7 +3765,7 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait)
        };
        int status = -ENOMEM;
 
-       if (server->nfs_client->cl_minorversion)
+       if (nfs_server_capable(state->inode, NFS_CAP_MOVEABLE))
                task_setup_data.flags |= RPC_TASK_MOVEABLE;
 
        nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_CLEANUP,
@@ -4385,7 +4385,7 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
        };
        unsigned short task_flags = 0;
 
-       if (server->nfs_client->cl_minorversion)
+       if (nfs_server_capable(dir, NFS_CAP_MOVEABLE))
                task_flags = RPC_TASK_MOVEABLE;
 
        /* Is this is an attribute revalidation, subject to softreval? */
@@ -6621,10 +6621,13 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred,
                .rpc_client = server->client,
                .rpc_message = &msg,
                .callback_ops = &nfs4_delegreturn_ops,
-               .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT | RPC_TASK_MOVEABLE,
+               .flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT,
        };
        int status = 0;
 
+       if (nfs_server_capable(inode, NFS_CAP_MOVEABLE))
+               task_setup_data.flags |= RPC_TASK_MOVEABLE;
+
        data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (data == NULL)
                return -ENOMEM;
@@ -6939,10 +6942,8 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
                .workqueue = nfsiod_workqueue,
                .flags = RPC_TASK_ASYNC,
        };
-       struct nfs_client *client =
-               NFS_SERVER(lsp->ls_state->inode)->nfs_client;
 
-       if (client->cl_minorversion)
+       if (nfs_server_capable(lsp->ls_state->inode, NFS_CAP_MOVEABLE))
                task_setup_data.flags |= RPC_TASK_MOVEABLE;
 
        nfs4_state_protect(NFS_SERVER(lsp->ls_state->inode)->nfs_client,
@@ -7218,9 +7219,8 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
                .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
        };
        int ret;
-       struct nfs_client *client = NFS_SERVER(state->inode)->nfs_client;
 
-       if (client->cl_minorversion)
+       if (nfs_server_capable(state->inode, NFS_CAP_MOVEABLE))
                task_setup_data.flags |= RPC_TASK_MOVEABLE;
 
        dprintk("%s: begin!\n", __func__);
@@ -10418,7 +10418,8 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
                | NFS_CAP_POSIX_LOCK
                | NFS_CAP_STATEID_NFSV41
                | NFS_CAP_ATOMIC_OPEN_V1
-               | NFS_CAP_LGOPEN,
+               | NFS_CAP_LGOPEN
+               | NFS_CAP_MOVEABLE,
        .init_client = nfs41_init_client,
        .shutdown_client = nfs41_shutdown_client,
        .match_stateid = nfs41_match_stateid,
@@ -10453,7 +10454,8 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
                | NFS_CAP_LAYOUTSTATS
                | NFS_CAP_CLONE
                | NFS_CAP_LAYOUTERROR
-               | NFS_CAP_READ_PLUS,
+               | NFS_CAP_READ_PLUS
+               | NFS_CAP_MOVEABLE,
        .init_client = nfs41_init_client,
        .shutdown_client = nfs41_shutdown_client,
        .match_stateid = nfs41_match_stateid,
index f2fe23e6c51f40a8f112d6cfda9a8db4cc56b2ef..fdecf729fa92b9ae0e3ad507e19674511ef14f2b 100644 (file)
@@ -773,6 +773,9 @@ int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
                .flags = RPC_TASK_ASYNC | flags,
        };
 
+       if (nfs_server_capable(hdr->inode, NFS_CAP_MOVEABLE))
+               task_setup_data.flags |= RPC_TASK_MOVEABLE;
+
        hdr->rw_ops->rw_initiate(hdr, &msg, rpc_ops, &task_setup_data, how);
 
        dprintk("NFS: initiated pgio call "
index 5fa11e1aca4c2759358aa37c7c36691c1bc4bcd4..d5ccf095b2a7dab17c3af9c395d16ac5aec050db 100644 (file)
@@ -102,6 +102,10 @@ static void nfs_do_call_unlink(struct inode *inode, struct nfs_unlinkdata *data)
        };
        struct rpc_task *task;
        struct inode *dir = d_inode(data->dentry->d_parent);
+
+       if (nfs_server_capable(inode, NFS_CAP_MOVEABLE))
+               task_setup_data.flags |= RPC_TASK_MOVEABLE;
+
        nfs_sb_active(dir->i_sb);
        data->args.fh = NFS_FH(dir);
        nfs_fattr_init(data->res.dir_attr);
@@ -344,6 +348,10 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
                .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
        };
 
+       if (nfs_server_capable(old_dir, NFS_CAP_MOVEABLE) &&
+           nfs_server_capable(new_dir, NFS_CAP_MOVEABLE))
+               task_setup_data.flags |= RPC_TASK_MOVEABLE;
+
        data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (data == NULL)
                return ERR_PTR(-ENOMEM);
index 33c88cd5c5660c318b9984646c421d904aadaef9..e751d88077a0cc1587cbfe6c8293c91ebad1619c 100644 (file)
@@ -1699,6 +1699,10 @@ int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data,
                .flags = RPC_TASK_ASYNC | flags,
                .priority = priority,
        };
+
+       if (nfs_server_capable(data->inode, NFS_CAP_MOVEABLE))
+               task_setup_data.flags |= RPC_TASK_MOVEABLE;
+
        /* Set up the initial task struct.  */
        nfs_ops->commit_setup(data, &msg, &task_setup_data.rpc_client);
        trace_nfs_initiate_commit(data);
index 9a6e70ccde56ef8dcd8203089d6d07e278228c5d..da9ef0ab9b4b68d1e4a4bc1549b987be25176771 100644 (file)
@@ -288,4 +288,5 @@ struct nfs_server {
 #define NFS_CAP_XATTR          (1U << 28)
 #define NFS_CAP_READ_PLUS      (1U << 29)
 #define NFS_CAP_FS_LOCATIONS   (1U << 30)
+#define NFS_CAP_MOVEABLE       (1U << 31)
 #endif