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)
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 inode *inode;
struct nfs4_client *clp;
......
......@@ -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);
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_reap_unclaimed(struct nfs4_client *clp);
......
......@@ -1940,9 +1940,11 @@ renew_done(struct rpc_task *task)
if (task->tk_status < 0) {
switch (task->tk_status) {
case -NFS4ERR_STALE_CLIENTID:
case -NFS4ERR_EXPIRED:
case -NFS4ERR_CB_PATH_DOWN:
nfs4_schedule_state_recovery(clp);
return;
}
return;
}
spin_lock(&clp->cl_lock);
if (time_before(clp->cl_last_renewal,timestamp))
......@@ -1975,11 +1977,13 @@ nfs4_proc_renew(struct nfs4_client *clp)
int status;
status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
if (status < 0)
return status;
spin_lock(&clp->cl_lock);
if (time_before(clp->cl_last_renewal,now))
clp->cl_last_renewal = now;
spin_unlock(&clp->cl_lock);
return status;
return 0;
}
/*
......
......@@ -842,7 +842,7 @@ static int reclaimer(void *ptr)
struct reclaimer_args *args = (struct reclaimer_args *)ptr;
struct nfs4_client *clp = args->clp;
struct nfs4_state_owner *sp;
int status;
int status = 0;
daemonize("%u.%u.%u.%u-reclaim", NIPQUAD(clp->cl_addr));
allow_signal(SIGKILL);
......@@ -858,7 +858,7 @@ static int reclaimer(void *ptr)
goto out;
restart_loop:
status = nfs4_proc_renew(clp);
if (status == 0)
if (status == 0 || status == -NFS4ERR_CB_PATH_DOWN)
goto out;
status = nfs4_init_client(clp);
if (status)
......@@ -881,6 +881,8 @@ static int reclaimer(void *ptr)
unlock_kernel();
wake_up_all(&clp->cl_waitq);
rpc_wake_up(&clp->cl_rpcwaitq);
if (status == -NFS4ERR_CB_PATH_DOWN)
nfs_handle_cb_pathdown(clp);
nfs4_put_client(clp);
return 0;
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