SUNRPC: Allow RPC calls to return ETIMEDOUT instead of EIO
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Sun, 24 Apr 2011 18:28:45 +0000 (14:28 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Sun, 24 Apr 2011 18:28:45 +0000 (14:28 -0400)
On occasion, it is useful for the NFS layer to distinguish between
soft timeouts and other EIO errors due to (say) encoding errors,
or authentication errors.

The following patch ensures that the default behaviour of the RPC
layer remains to return EIO on soft timeouts (until we have
audited all the callers).

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
include/linux/sunrpc/sched.h
net/sunrpc/clnt.c

index 3b94f804b85293b478b80f6d72714111c9af7bfb..f73c482ec9c6080cc5201c047546928c53c8b723 100644 (file)
@@ -128,12 +128,13 @@ struct rpc_task_setup {
 #define RPC_TASK_SOFT          0x0200          /* Use soft timeouts */
 #define RPC_TASK_SOFTCONN      0x0400          /* Fail if can't connect */
 #define RPC_TASK_SENT          0x0800          /* message was sent */
+#define RPC_TASK_TIMEOUT       0x1000          /* fail with ETIMEDOUT on timeout */
 
 #define RPC_IS_ASYNC(t)                ((t)->tk_flags & RPC_TASK_ASYNC)
 #define RPC_IS_SWAPPER(t)      ((t)->tk_flags & RPC_TASK_SWAPPER)
 #define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS)
 #define RPC_ASSASSINATED(t)    ((t)->tk_flags & RPC_TASK_KILLED)
-#define RPC_IS_SOFT(t)         ((t)->tk_flags & RPC_TASK_SOFT)
+#define RPC_IS_SOFT(t)         ((t)->tk_flags & (RPC_TASK_SOFT|RPC_TASK_TIMEOUT))
 #define RPC_IS_SOFTCONN(t)     ((t)->tk_flags & RPC_TASK_SOFTCONN)
 #define RPC_WAS_SENT(t)                ((t)->tk_flags & RPC_TASK_SENT)
 
index e7a96e478f63a74da8e90e0f80748857f5c18fb0..8d83f9d487130bb7789fe0dc53201ec3aedc5a95 100644 (file)
@@ -1508,7 +1508,10 @@ call_timeout(struct rpc_task *task)
                if (clnt->cl_chatty)
                        printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
                                clnt->cl_protname, clnt->cl_server);
-               rpc_exit(task, -EIO);
+               if (task->tk_flags & RPC_TASK_TIMEOUT)
+                       rpc_exit(task, -ETIMEDOUT);
+               else
+                       rpc_exit(task, -EIO);
                return;
        }