pNFS: Prevent unnecessary layoutreturns after delegreturn
authorTrond Myklebust <trond.myklebust@primarydata.com>
Sat, 19 Nov 2016 13:48:47 +0000 (08:48 -0500)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Thu, 1 Dec 2016 22:21:48 +0000 (17:21 -0500)
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>
fs/nfs/nfs4proc.c

index 221d97de0e2c2f2a88d0af5d569f9275b539de02..5593b088c561957fab5c5397ea680949e7e8d8b4 100644 (file)
@@ -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;