NFSv4: Clean up pNFS return-on-close error handling
authorTrond Myklebust <trondmy@gmail.com>
Fri, 20 Sep 2019 11:23:41 +0000 (07:23 -0400)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Fri, 20 Sep 2019 19:27:51 +0000 (15:27 -0400)
Both close and delegreturn have identical code to handle pNFS
return-on-close. This patch refactors that code and places it
in pnfs.c

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
fs/nfs/nfs4proc.c
fs/nfs/pnfs.c
fs/nfs/pnfs.h

index 00c7a92..a7cecac 100644 (file)
@@ -3363,32 +3363,11 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
        trace_nfs4_close(state, &calldata->arg, &calldata->res, task->tk_status);
 
        /* Handle Layoutreturn errors */
-       if (calldata->arg.lr_args && task->tk_status != 0) {
-               switch (calldata->res.lr_ret) {
-               default:
-                       calldata->res.lr_ret = -NFS4ERR_NOMATCHING_LAYOUT;
-                       break;
-               case 0:
-                       calldata->arg.lr_args = NULL;
-                       calldata->res.lr_res = NULL;
-                       break;
-               case -NFS4ERR_OLD_STATEID:
-                       if (nfs4_layoutreturn_refresh_stateid(&calldata->arg.lr_args->stateid,
-                                               &calldata->arg.lr_args->range,
-                                               calldata->inode))
-                               goto lr_restart;
-                       /* Fallthrough */
-               case -NFS4ERR_ADMIN_REVOKED:
-               case -NFS4ERR_DELEG_REVOKED:
-               case -NFS4ERR_EXPIRED:
-               case -NFS4ERR_BAD_STATEID:
-               case -NFS4ERR_UNKNOWN_LAYOUTTYPE:
-               case -NFS4ERR_WRONG_CRED:
-                       calldata->arg.lr_args = NULL;
-                       calldata->res.lr_res = NULL;
-                       goto lr_restart;
-               }
-       }
+       if (pnfs_roc_done(task, calldata->inode,
+                               &calldata->arg.lr_args,
+                               &calldata->res.lr_res,
+                               &calldata->res.lr_ret) == -EAGAIN)
+               goto out_restart;
 
        /* hmm. we are done with the inode, and in the process of freeing
         * the state_owner. we keep this around to process errors
@@ -3435,8 +3414,6 @@ out_release:
        nfs_refresh_inode(calldata->inode, &calldata->fattr);
        dprintk("%s: done, ret = %d!\n", __func__, task->tk_status);
        return;
-lr_restart:
-       calldata->res.lr_ret = 0;
 out_restart:
        task->tk_status = 0;
        rpc_restart_call_prepare(task);
@@ -6128,32 +6105,11 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
        trace_nfs4_delegreturn_exit(&data->args, &data->res, task->tk_status);
 
        /* Handle Layoutreturn errors */
-       if (data->args.lr_args && task->tk_status != 0) {
-               switch(data->res.lr_ret) {
-               default:
-                       data->res.lr_ret = -NFS4ERR_NOMATCHING_LAYOUT;
-                       break;
-               case 0:
-                       data->args.lr_args = NULL;
-                       data->res.lr_res = NULL;
-                       break;
-               case -NFS4ERR_OLD_STATEID:
-                       if (nfs4_layoutreturn_refresh_stateid(&data->args.lr_args->stateid,
-                                               &data->args.lr_args->range,
-                                               data->inode))
-                               goto lr_restart;
-                       /* Fallthrough */
-               case -NFS4ERR_ADMIN_REVOKED:
-               case -NFS4ERR_DELEG_REVOKED:
-               case -NFS4ERR_EXPIRED:
-               case -NFS4ERR_BAD_STATEID:
-               case -NFS4ERR_UNKNOWN_LAYOUTTYPE:
-               case -NFS4ERR_WRONG_CRED:
-                       data->args.lr_args = NULL;
-                       data->res.lr_res = NULL;
-                       goto lr_restart;
-               }
-       }
+       if (pnfs_roc_done(task, data->inode,
+                               &data->args.lr_args,
+                               &data->res.lr_res,
+                               &data->res.lr_ret) == -EAGAIN)
+               goto out_restart;
 
        switch (task->tk_status) {
        case 0:
@@ -6191,8 +6147,6 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
        }
        data->rpc_status = task->tk_status;
        return;
-lr_restart:
-       data->res.lr_ret = 0;
 out_restart:
        task->tk_status = 0;
        rpc_restart_call_prepare(task);
index 0418b19..8769422 100644 (file)
@@ -1440,6 +1440,33 @@ out_noroc:
        return false;
 }
 
+int pnfs_roc_done(struct rpc_task *task, struct inode *inode,
+               struct nfs4_layoutreturn_args **argpp,
+               struct nfs4_layoutreturn_res **respp,
+               int *ret)
+{
+       struct nfs4_layoutreturn_args *arg = *argpp;
+       int retval = -EAGAIN;
+
+       if (!arg)
+               return 0;
+       /* Handle Layoutreturn errors */
+       switch (*ret) {
+       case 0:
+               retval = 0;
+               break;
+       case -NFS4ERR_OLD_STATEID:
+               if (!nfs4_layoutreturn_refresh_stateid(&arg->stateid,
+                                       &arg->range, inode))
+                       break;
+               *ret = -NFS4ERR_NOMATCHING_LAYOUT;
+               return -EAGAIN;
+       }
+       *argpp = NULL;
+       *respp = NULL;
+       return retval;
+}
+
 void pnfs_roc_release(struct nfs4_layoutreturn_args *args,
                struct nfs4_layoutreturn_res *res,
                int ret)
index f15609c..3ef3756 100644 (file)
@@ -282,6 +282,10 @@ bool pnfs_roc(struct inode *ino,
                struct nfs4_layoutreturn_args *args,
                struct nfs4_layoutreturn_res *res,
                const struct cred *cred);
+int pnfs_roc_done(struct rpc_task *task, struct inode *inode,
+               struct nfs4_layoutreturn_args **argpp,
+               struct nfs4_layoutreturn_res **respp,
+               int *ret);
 void pnfs_roc_release(struct nfs4_layoutreturn_args *args,
                struct nfs4_layoutreturn_res *res,
                int ret);
@@ -701,6 +705,15 @@ pnfs_roc(struct inode *ino,
        return false;
 }
 
+static inline int
+pnfs_roc_done(struct rpc_task *task, struct inode *inode,
+               struct nfs4_layoutreturn_args **argpp,
+               struct nfs4_layoutreturn_res **respp,
+               int *ret)
+{
+       return 0;
+}
+
 static inline void
 pnfs_roc_release(struct nfs4_layoutreturn_args *args,
                struct nfs4_layoutreturn_res *res,