NFSv4: State recovery cleanup
Use wait_on_bit() when waiting for state recovery to complete. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
26e976a884
commit
433fbe4c88
@ -38,7 +38,7 @@ struct idmap;
|
|||||||
((err) != NFSERR_NOFILEHANDLE))
|
((err) != NFSERR_NOFILEHANDLE))
|
||||||
|
|
||||||
enum nfs4_client_state {
|
enum nfs4_client_state {
|
||||||
NFS4CLNT_OK = 0,
|
NFS4CLNT_STATE_RECOVER = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -76,7 +76,6 @@ struct nfs4_client {
|
|||||||
struct work_struct cl_renewd;
|
struct work_struct cl_renewd;
|
||||||
struct work_struct cl_recoverd;
|
struct work_struct cl_recoverd;
|
||||||
|
|
||||||
wait_queue_head_t cl_waitq;
|
|
||||||
struct rpc_wait_queue cl_rpcwaitq;
|
struct rpc_wait_queue cl_rpcwaitq;
|
||||||
|
|
||||||
/* used for the setclientid verifier */
|
/* used for the setclientid verifier */
|
||||||
|
@ -2736,7 +2736,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
|
|||||||
case -NFS4ERR_EXPIRED:
|
case -NFS4ERR_EXPIRED:
|
||||||
rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL, NULL);
|
rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL, NULL);
|
||||||
nfs4_schedule_state_recovery(clp);
|
nfs4_schedule_state_recovery(clp);
|
||||||
if (test_bit(NFS4CLNT_OK, &clp->cl_state))
|
if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0)
|
||||||
rpc_wake_up_task(task);
|
rpc_wake_up_task(task);
|
||||||
task->tk_status = 0;
|
task->tk_status = 0;
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
@ -2753,25 +2753,25 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 nfs4_client *clp)
|
static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp)
|
||||||
{
|
{
|
||||||
DEFINE_WAIT(wait);
|
|
||||||
sigset_t oldset;
|
sigset_t oldset;
|
||||||
int interruptible, res = 0;
|
int res;
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
||||||
rpc_clnt_sigmask(clnt, &oldset);
|
rpc_clnt_sigmask(clnt, &oldset);
|
||||||
interruptible = TASK_UNINTERRUPTIBLE;
|
res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER,
|
||||||
if (clnt->cl_intr)
|
nfs4_wait_bit_interruptible,
|
||||||
interruptible = TASK_INTERRUPTIBLE;
|
TASK_INTERRUPTIBLE);
|
||||||
prepare_to_wait(&clp->cl_waitq, &wait, interruptible);
|
|
||||||
nfs4_schedule_state_recovery(clp);
|
|
||||||
if (clnt->cl_intr && signalled())
|
|
||||||
res = -ERESTARTSYS;
|
|
||||||
else if (!test_bit(NFS4CLNT_OK, &clp->cl_state))
|
|
||||||
schedule();
|
|
||||||
finish_wait(&clp->cl_waitq, &wait);
|
|
||||||
rpc_clnt_sigunmask(clnt, &oldset);
|
rpc_clnt_sigunmask(clnt, &oldset);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -2814,6 +2814,7 @@ int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct
|
|||||||
case -NFS4ERR_STALE_CLIENTID:
|
case -NFS4ERR_STALE_CLIENTID:
|
||||||
case -NFS4ERR_STALE_STATEID:
|
case -NFS4ERR_STALE_STATEID:
|
||||||
case -NFS4ERR_EXPIRED:
|
case -NFS4ERR_EXPIRED:
|
||||||
|
nfs4_schedule_state_recovery(clp);
|
||||||
ret = nfs4_wait_clnt_recover(server->client, clp);
|
ret = nfs4_wait_clnt_recover(server->client, clp);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
exception->retry = 1;
|
exception->retry = 1;
|
||||||
|
@ -106,11 +106,10 @@ nfs4_alloc_client(struct in_addr *addr)
|
|||||||
INIT_WORK(&clp->cl_recoverd, nfs4_recover_state, clp);
|
INIT_WORK(&clp->cl_recoverd, nfs4_recover_state, clp);
|
||||||
INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp);
|
INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp);
|
||||||
INIT_LIST_HEAD(&clp->cl_superblocks);
|
INIT_LIST_HEAD(&clp->cl_superblocks);
|
||||||
init_waitqueue_head(&clp->cl_waitq);
|
|
||||||
rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
|
rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
|
||||||
clp->cl_rpcclient = ERR_PTR(-EINVAL);
|
clp->cl_rpcclient = ERR_PTR(-EINVAL);
|
||||||
clp->cl_boot_time = CURRENT_TIME;
|
clp->cl_boot_time = CURRENT_TIME;
|
||||||
clp->cl_state = 1 << NFS4CLNT_OK;
|
clp->cl_state = 0;
|
||||||
return clp;
|
return clp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +192,6 @@ nfs4_put_client(struct nfs4_client *clp)
|
|||||||
list_del(&clp->cl_servers);
|
list_del(&clp->cl_servers);
|
||||||
spin_unlock(&state_spinlock);
|
spin_unlock(&state_spinlock);
|
||||||
BUG_ON(!list_empty(&clp->cl_superblocks));
|
BUG_ON(!list_empty(&clp->cl_superblocks));
|
||||||
wake_up_all(&clp->cl_waitq);
|
|
||||||
rpc_wake_up(&clp->cl_rpcwaitq);
|
rpc_wake_up(&clp->cl_rpcwaitq);
|
||||||
nfs4_kill_renewd(clp);
|
nfs4_kill_renewd(clp);
|
||||||
nfs4_free_client(clp);
|
nfs4_free_client(clp);
|
||||||
@ -741,6 +739,15 @@ struct reclaimer_args {
|
|||||||
struct completion complete;
|
struct completion complete;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline void nfs4_clear_recover_bit(struct nfs4_client *clp)
|
||||||
|
{
|
||||||
|
smp_mb__before_clear_bit();
|
||||||
|
clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state);
|
||||||
|
smp_mb__after_clear_bit();
|
||||||
|
wake_up_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER);
|
||||||
|
rpc_wake_up(&clp->cl_rpcwaitq);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* State recovery routine
|
* State recovery routine
|
||||||
*/
|
*/
|
||||||
@ -760,9 +767,7 @@ nfs4_recover_state(void *data)
|
|||||||
wait_for_completion(&args.complete);
|
wait_for_completion(&args.complete);
|
||||||
return;
|
return;
|
||||||
out_failed_clear:
|
out_failed_clear:
|
||||||
set_bit(NFS4CLNT_OK, &clp->cl_state);
|
nfs4_clear_recover_bit(clp);
|
||||||
wake_up_all(&clp->cl_waitq);
|
|
||||||
rpc_wake_up(&clp->cl_rpcwaitq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -773,7 +778,7 @@ nfs4_schedule_state_recovery(struct nfs4_client *clp)
|
|||||||
{
|
{
|
||||||
if (!clp)
|
if (!clp)
|
||||||
return;
|
return;
|
||||||
if (test_and_clear_bit(NFS4CLNT_OK, &clp->cl_state))
|
if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0)
|
||||||
schedule_work(&clp->cl_recoverd);
|
schedule_work(&clp->cl_recoverd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -943,13 +948,11 @@ restart_loop:
|
|||||||
}
|
}
|
||||||
nfs_delegation_reap_unclaimed(clp);
|
nfs_delegation_reap_unclaimed(clp);
|
||||||
out:
|
out:
|
||||||
set_bit(NFS4CLNT_OK, &clp->cl_state);
|
|
||||||
up_write(&clp->cl_sem);
|
up_write(&clp->cl_sem);
|
||||||
unlock_kernel();
|
unlock_kernel();
|
||||||
wake_up_all(&clp->cl_waitq);
|
|
||||||
rpc_wake_up(&clp->cl_rpcwaitq);
|
|
||||||
if (status == -NFS4ERR_CB_PATH_DOWN)
|
if (status == -NFS4ERR_CB_PATH_DOWN)
|
||||||
nfs_handle_cb_pathdown(clp);
|
nfs_handle_cb_pathdown(clp);
|
||||||
|
nfs4_clear_recover_bit(clp);
|
||||||
nfs4_put_client(clp);
|
nfs4_put_client(clp);
|
||||||
return 0;
|
return 0;
|
||||||
out_error:
|
out_error:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user