NFSv4.1 mark qualified async operations as MOVEABLE tasks

[ Upstream commit 118f09eda2 ]

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

Fixes: 85e39feead ("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>
This commit is contained in:
Olga Kornievskaia 2022-05-25 12:12:59 -04:00 коммит произвёл Greg Kroah-Hartman
Родитель c5665c29dd
Коммит 54c408800f
5 изменённых файлов: 30 добавлений и 12 удалений

Просмотреть файл

@ -1165,7 +1165,7 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
{ {
unsigned short task_flags = 0; unsigned short task_flags = 0;
if (server->nfs_client->cl_minorversion) if (server->caps & NFS_CAP_MOVEABLE)
task_flags = RPC_TASK_MOVEABLE; task_flags = RPC_TASK_MOVEABLE;
return nfs4_do_call_sync(clnt, server, msg, args, res, task_flags); return nfs4_do_call_sync(clnt, server, msg, args, res, task_flags);
} }
@ -2578,7 +2578,7 @@ static int nfs4_run_open_task(struct nfs4_opendata *data,
}; };
int status; int status;
if (server->nfs_client->cl_minorversion) if (nfs_server_capable(dir, NFS_CAP_MOVEABLE))
task_setup_data.flags |= RPC_TASK_MOVEABLE; task_setup_data.flags |= RPC_TASK_MOVEABLE;
kref_get(&data->kref); kref_get(&data->kref);
@ -3761,7 +3761,7 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait)
}; };
int status = -ENOMEM; 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; task_setup_data.flags |= RPC_TASK_MOVEABLE;
nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_CLEANUP, nfs4_state_protect(server->nfs_client, NFS_SP4_MACH_CRED_CLEANUP,
@ -4381,7 +4381,7 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
}; };
unsigned short task_flags = 0; unsigned short task_flags = 0;
if (server->nfs_client->cl_minorversion) if (nfs_server_capable(dir, NFS_CAP_MOVEABLE))
task_flags = RPC_TASK_MOVEABLE; task_flags = RPC_TASK_MOVEABLE;
/* Is this is an attribute revalidation, subject to softreval? */ /* Is this is an attribute revalidation, subject to softreval? */
@ -6617,10 +6617,13 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred,
.rpc_client = server->client, .rpc_client = server->client,
.rpc_message = &msg, .rpc_message = &msg,
.callback_ops = &nfs4_delegreturn_ops, .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; int status = 0;
if (nfs_server_capable(inode, NFS_CAP_MOVEABLE))
task_setup_data.flags |= RPC_TASK_MOVEABLE;
data = kzalloc(sizeof(*data), GFP_KERNEL); data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL) if (data == NULL)
return -ENOMEM; return -ENOMEM;
@ -6935,10 +6938,8 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
.workqueue = nfsiod_workqueue, .workqueue = nfsiod_workqueue,
.flags = RPC_TASK_ASYNC, .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; task_setup_data.flags |= RPC_TASK_MOVEABLE;
nfs4_state_protect(NFS_SERVER(lsp->ls_state->inode)->nfs_client, nfs4_state_protect(NFS_SERVER(lsp->ls_state->inode)->nfs_client,
@ -7214,9 +7215,8 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f
.flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF, .flags = RPC_TASK_ASYNC | RPC_TASK_CRED_NOREF,
}; };
int ret; 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; task_setup_data.flags |= RPC_TASK_MOVEABLE;
dprintk("%s: begin!\n", __func__); dprintk("%s: begin!\n", __func__);
@ -10414,7 +10414,8 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
| NFS_CAP_POSIX_LOCK | NFS_CAP_POSIX_LOCK
| NFS_CAP_STATEID_NFSV41 | NFS_CAP_STATEID_NFSV41
| NFS_CAP_ATOMIC_OPEN_V1 | NFS_CAP_ATOMIC_OPEN_V1
| NFS_CAP_LGOPEN, | NFS_CAP_LGOPEN
| NFS_CAP_MOVEABLE,
.init_client = nfs41_init_client, .init_client = nfs41_init_client,
.shutdown_client = nfs41_shutdown_client, .shutdown_client = nfs41_shutdown_client,
.match_stateid = nfs41_match_stateid, .match_stateid = nfs41_match_stateid,
@ -10449,7 +10450,8 @@ static const struct nfs4_minor_version_ops nfs_v4_2_minor_ops = {
| NFS_CAP_LAYOUTSTATS | NFS_CAP_LAYOUTSTATS
| NFS_CAP_CLONE | NFS_CAP_CLONE
| NFS_CAP_LAYOUTERROR | NFS_CAP_LAYOUTERROR
| NFS_CAP_READ_PLUS, | NFS_CAP_READ_PLUS
| NFS_CAP_MOVEABLE,
.init_client = nfs41_init_client, .init_client = nfs41_init_client,
.shutdown_client = nfs41_shutdown_client, .shutdown_client = nfs41_shutdown_client,
.match_stateid = nfs41_match_stateid, .match_stateid = nfs41_match_stateid,

Просмотреть файл

@ -773,6 +773,9 @@ int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
.flags = RPC_TASK_ASYNC | flags, .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); hdr->rw_ops->rw_initiate(hdr, &msg, rpc_ops, &task_setup_data, how);
dprintk("NFS: initiated pgio call " dprintk("NFS: initiated pgio call "

Просмотреть файл

@ -102,6 +102,10 @@ static void nfs_do_call_unlink(struct inode *inode, struct nfs_unlinkdata *data)
}; };
struct rpc_task *task; struct rpc_task *task;
struct inode *dir = d_inode(data->dentry->d_parent); 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); nfs_sb_active(dir->i_sb);
data->args.fh = NFS_FH(dir); data->args.fh = NFS_FH(dir);
nfs_fattr_init(data->res.dir_attr); 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, .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); data = kzalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL) if (data == NULL)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);

Просмотреть файл

@ -1684,6 +1684,10 @@ int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data,
.flags = RPC_TASK_ASYNC | flags, .flags = RPC_TASK_ASYNC | flags,
.priority = priority, .priority = priority,
}; };
if (nfs_server_capable(data->inode, NFS_CAP_MOVEABLE))
task_setup_data.flags |= RPC_TASK_MOVEABLE;
/* Set up the initial task struct. */ /* Set up the initial task struct. */
nfs_ops->commit_setup(data, &msg, &task_setup_data.rpc_client); nfs_ops->commit_setup(data, &msg, &task_setup_data.rpc_client);
trace_nfs_initiate_commit(data); trace_nfs_initiate_commit(data);

Просмотреть файл

@ -288,4 +288,5 @@ struct nfs_server {
#define NFS_CAP_XATTR (1U << 28) #define NFS_CAP_XATTR (1U << 28)
#define NFS_CAP_READ_PLUS (1U << 29) #define NFS_CAP_READ_PLUS (1U << 29)
#define NFS_CAP_FS_LOCATIONS (1U << 30) #define NFS_CAP_FS_LOCATIONS (1U << 30)
#define NFS_CAP_MOVEABLE (1U << 31)
#endif #endif