-static int nfs4_wait_bit_interruptible(void *word)
-{
- if (signal_pending(current))
- return -ERESTARTSYS;
- schedule();
- return 0;
-}
-
-static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs_client *clp)
-{
- sigset_t oldset;
- int res;
-
- might_sleep();
-
- rwsem_acquire(&clp->cl_sem.dep_map, 0, 0, _RET_IP_);
-
- rpc_clnt_sigmask(clnt, &oldset);
- res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER,
- nfs4_wait_bit_interruptible,
- TASK_INTERRUPTIBLE);
- rpc_clnt_sigunmask(clnt, &oldset);
-
- rwsem_release(&clp->cl_sem.dep_map, 1, _RET_IP_);
- return res;
-}
-
-static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
-{
- sigset_t oldset;
- int res = 0;
-
- might_sleep();
-
- if (*timeout <= 0)
- *timeout = NFS4_POLL_RETRY_MIN;
- if (*timeout > NFS4_POLL_RETRY_MAX)
- *timeout = NFS4_POLL_RETRY_MAX;
- rpc_clnt_sigmask(clnt, &oldset);
- if (clnt->cl_intr) {
- schedule_timeout_interruptible(*timeout);
- if (signalled())
- res = -ERESTARTSYS;
- } else
- schedule_timeout_uninterruptible(*timeout);
- rpc_clnt_sigunmask(clnt, &oldset);
- *timeout <<= 1;
- return res;
-}
-
-/* This is the error handling routine for processes that are allowed
- * to sleep.
- */
-static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
-{
- struct nfs_client *clp = server->nfs_client;
- int ret = errorcode;
-
- exception->retry = 0;
- switch(errorcode) {
- case 0:
- return 0;
- case -NFS4ERR_STALE_CLIENTID:
- case -NFS4ERR_STALE_STATEID:
- case -NFS4ERR_EXPIRED:
- nfs4_schedule_state_recovery(clp);
- ret = nfs4_wait_clnt_recover(server->client, clp);
- if (ret == 0)
- exception->retry = 1;
- break;
- case -NFS4ERR_FILE_OPEN:
- case -NFS4ERR_GRACE:
- case -NFS4ERR_DELAY:
- ret = nfs4_delay(server->client, &exception->timeout);
- if (ret != 0)
- break;
- case -NFS4ERR_OLD_STATEID:
- exception->retry = 1;
- }
- /* We failed to handle the error */
- return nfs4_map_errors(ret);
-}
-