aboutsummaryrefslogtreecommitdiff
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust2016-11-19 08:48:47 -0500
committerTrond Myklebust2016-12-01 17:21:48 -0500
commit53e6fc86abbbd7338f16267846a58de7ee24e839 (patch)
tree9f2e7aa86a7750f71b9c082ab78b77be75c90301 /fs/nfs
parent1c5bd76d17cca6836e9d9913e4a0356cd8a36598 (diff)
pNFS: Prevent unnecessary layoutreturns after delegreturn
If we cannot grab the inode or superblock, then we cannot pin the layout header, and so we cannot send a layoutreturn as part of an async delegreturn call. In this case, we currently end up sending an extra layoutreturn after the delegreturn. Since the layout was implicitly returned by the delegreturn, that just gets a BAD_STATEID. The fix is to simply complete the return-on-close immediately. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4proc.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 221d97de0e2c..5593b088c561 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -5744,14 +5744,16 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
nfs_fattr_init(data->res.fattr);
data->timestamp = jiffies;
data->rpc_status = 0;
+ data->lr.roc = pnfs_roc(inode, &data->lr.arg, &data->lr.res, cred);
data->inode = nfs_igrab_and_active(inode);
if (data->inode) {
- data->lr.roc = pnfs_roc(inode, &data->lr.arg, &data->lr.res,
- cred);
if (data->lr.roc) {
data->args.lr_args = &data->lr.arg;
data->res.lr_res = &data->lr.res;
}
+ } else if (data->lr.roc) {
+ pnfs_roc_release(&data->lr.arg, &data->lr.res, 0);
+ data->lr.roc = false;
}
task_setup_data.callback_data = data;