]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
NFSv4: Refactor NFSv4 error handling
authorTrond Myklebust <trond.myklebust@primarydata.com>
Sun, 20 Sep 2015 18:32:45 +0000 (14:32 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Thu, 8 Oct 2015 14:45:51 +0000 (10:45 -0400)
Prepare for unification of the synchronous and asynchronous error
handling.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/nfs4_fs.h
fs/nfs/nfs4proc.c

index 50cfc4ca7a02a06d383c05325ecbdd166ff25b8c..4afdee420d253862e7dded0d84f6743b00de337f 100644 (file)
@@ -183,10 +183,12 @@ struct nfs4_state {
 
 
 struct nfs4_exception {
-       long timeout;
-       int retry;
        struct nfs4_state *state;
        struct inode *inode;
+       long timeout;
+       unsigned char delay : 1,
+                     recovering : 1,
+                     retry : 1;
 };
 
 struct nfs4_state_recovery_ops {
index 5133bb18830e8c8b97e68e8f2c55d617ff92a321..d5c2a461f28185485e640358663b862c5670b71b 100644 (file)
@@ -344,13 +344,16 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
 /* This is the error handling routine for processes that are allowed
  * to sleep.
  */
-int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
+static int nfs4_do_handle_exception(struct nfs_server *server,
+               int errorcode, struct nfs4_exception *exception)
 {
        struct nfs_client *clp = server->nfs_client;
        struct nfs4_state *state = exception->state;
        struct inode *inode = exception->inode;
        int ret = errorcode;
 
+       exception->delay = 0;
+       exception->recovering = 0;
        exception->retry = 0;
        switch(errorcode) {
                case 0:
@@ -411,9 +414,9 @@ int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_
                        }
                case -NFS4ERR_GRACE:
                case -NFS4ERR_DELAY:
-                       ret = nfs4_delay(server->client, &exception->timeout);
-                       if (ret != 0)
-                               break;
+                       exception->delay = 1;
+                       return 0;
+
                case -NFS4ERR_RETRY_UNCACHED_REP:
                case -NFS4ERR_OLD_STATEID:
                        exception->retry = 1;
@@ -434,9 +437,31 @@ int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_
        /* We failed to handle the error */
        return nfs4_map_errors(ret);
 wait_on_recovery:
-       ret = nfs4_wait_clnt_recover(clp);
-       if (test_bit(NFS_MIG_FAILED, &server->mig_status))
-               return -EIO;
+       exception->recovering = 1;
+       return 0;
+}
+
+/* This is the error handling routine for processes that are allowed
+ * to sleep.
+ */
+int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
+{
+       struct nfs_client *clp = server->nfs_client;
+       int ret;
+
+       ret = nfs4_do_handle_exception(server, errorcode, exception);
+       if (exception->delay) {
+               ret = nfs4_delay(server->client, &exception->timeout);
+               goto out_retry;
+       }
+       if (exception->recovering) {
+               ret = nfs4_wait_clnt_recover(clp);
+               if (test_bit(NFS_MIG_FAILED, &server->mig_status))
+                       return -EIO;
+               goto out_retry;
+       }
+       return ret;
+out_retry:
        if (ret == 0)
                exception->retry = 1;
        return ret;