Commit ef7306b4 authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: return all delegations we hold if the server issues a

   NFS4ERR_CB_PATH_DOWN error.
parent b42a8a16
...@@ -193,6 +193,30 @@ void nfs_return_all_delegations(struct super_block *sb) ...@@ -193,6 +193,30 @@ void nfs_return_all_delegations(struct super_block *sb)
spin_unlock(&clp->cl_lock); spin_unlock(&clp->cl_lock);
} }
/*
* Return all delegations following an NFS4ERR_CB_PATH_DOWN error.
*/
void nfs_handle_cb_pathdown(struct nfs4_client *clp)
{
struct nfs_delegation *delegation;
struct inode *inode;
if (clp == NULL)
return;
restart:
spin_lock(&clp->cl_lock);
list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
inode = igrab(delegation->inode);
if (inode == NULL)
continue;
spin_unlock(&clp->cl_lock);
nfs_inode_return_delegation(inode);
iput(inode);
goto restart;
}
spin_unlock(&clp->cl_lock);
}
struct recall_threadargs { struct recall_threadargs {
struct inode *inode; struct inode *inode;
struct nfs4_client *clp; struct nfs4_client *clp;
......
...@@ -30,6 +30,7 @@ int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *s ...@@ -30,6 +30,7 @@ int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *s
struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle); struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle);
void nfs_return_all_delegations(struct super_block *sb); void nfs_return_all_delegations(struct super_block *sb);
void nfs_handle_cb_pathdown(struct nfs4_client *clp);
void nfs_delegation_mark_reclaim(struct nfs4_client *clp); void nfs_delegation_mark_reclaim(struct nfs4_client *clp);
void nfs_delegation_reap_unclaimed(struct nfs4_client *clp); void nfs_delegation_reap_unclaimed(struct nfs4_client *clp);
......
...@@ -1940,9 +1940,11 @@ renew_done(struct rpc_task *task) ...@@ -1940,9 +1940,11 @@ renew_done(struct rpc_task *task)
if (task->tk_status < 0) { if (task->tk_status < 0) {
switch (task->tk_status) { switch (task->tk_status) {
case -NFS4ERR_STALE_CLIENTID: case -NFS4ERR_STALE_CLIENTID:
case -NFS4ERR_EXPIRED:
case -NFS4ERR_CB_PATH_DOWN:
nfs4_schedule_state_recovery(clp); nfs4_schedule_state_recovery(clp);
return;
} }
return;
} }
spin_lock(&clp->cl_lock); spin_lock(&clp->cl_lock);
if (time_before(clp->cl_last_renewal,timestamp)) if (time_before(clp->cl_last_renewal,timestamp))
...@@ -1975,11 +1977,13 @@ nfs4_proc_renew(struct nfs4_client *clp) ...@@ -1975,11 +1977,13 @@ nfs4_proc_renew(struct nfs4_client *clp)
int status; int status;
status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
if (status < 0)
return status;
spin_lock(&clp->cl_lock); spin_lock(&clp->cl_lock);
if (time_before(clp->cl_last_renewal,now)) if (time_before(clp->cl_last_renewal,now))
clp->cl_last_renewal = now; clp->cl_last_renewal = now;
spin_unlock(&clp->cl_lock); spin_unlock(&clp->cl_lock);
return status; return 0;
} }
/* /*
......
...@@ -842,7 +842,7 @@ static int reclaimer(void *ptr) ...@@ -842,7 +842,7 @@ static int reclaimer(void *ptr)
struct reclaimer_args *args = (struct reclaimer_args *)ptr; struct reclaimer_args *args = (struct reclaimer_args *)ptr;
struct nfs4_client *clp = args->clp; struct nfs4_client *clp = args->clp;
struct nfs4_state_owner *sp; struct nfs4_state_owner *sp;
int status; int status = 0;
daemonize("%u.%u.%u.%u-reclaim", NIPQUAD(clp->cl_addr)); daemonize("%u.%u.%u.%u-reclaim", NIPQUAD(clp->cl_addr));
allow_signal(SIGKILL); allow_signal(SIGKILL);
...@@ -858,7 +858,7 @@ static int reclaimer(void *ptr) ...@@ -858,7 +858,7 @@ static int reclaimer(void *ptr)
goto out; goto out;
restart_loop: restart_loop:
status = nfs4_proc_renew(clp); status = nfs4_proc_renew(clp);
if (status == 0) if (status == 0 || status == -NFS4ERR_CB_PATH_DOWN)
goto out; goto out;
status = nfs4_init_client(clp); status = nfs4_init_client(clp);
if (status) if (status)
...@@ -881,6 +881,8 @@ static int reclaimer(void *ptr) ...@@ -881,6 +881,8 @@ static int reclaimer(void *ptr)
unlock_kernel(); unlock_kernel();
wake_up_all(&clp->cl_waitq); wake_up_all(&clp->cl_waitq);
rpc_wake_up(&clp->cl_rpcwaitq); rpc_wake_up(&clp->cl_rpcwaitq);
if (status == -NFS4ERR_CB_PATH_DOWN)
nfs_handle_cb_pathdown(clp);
nfs4_put_client(clp); nfs4_put_client(clp);
return 0; return 0;
out_error: out_error:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment