-/*
- * Called with dp->dl_count incremented
- */
-static void
-nfs4_cb_recall_done(struct rpc_task *task)
-{
- struct nfs4_cb_recall *cbr = (struct nfs4_cb_recall *)task->tk_calldata;
- struct nfs4_delegation *dp = cbr->cbr_dp;
- int status;
-
- /* all is well... */
- if (task->tk_status == 0)
- goto out;
-
- /* network partition, retry nfsd4_cb_recall once. */
- if (task->tk_status == -EIO) {
- if (atomic_read(&dp->dl_recall_cnt) == 0)
- goto retry;
- else
- /* callback channel no longer available */
- atomic_set(&dp->dl_client->cl_callback.cb_set, 0);
- }
-
- /* Race: a recall occurred miliseconds after a delegation was granted.
- * Client may have received recall prior to delegation. retry recall
- * once.
- */
- if ((task->tk_status == -EBADHANDLE) || (task->tk_status == -NFS4ERR_BAD_STATEID)){
- if (atomic_read(&dp->dl_recall_cnt) == 0)
- goto retry;
- }
- atomic_set(&dp->dl_state, NFS4_RECALL_COMPLETE);
-
-out:
- if (atomic_dec_and_test(&dp->dl_count))
- atomic_set(&dp->dl_state, NFS4_REAP_DELEG);
- BUG_ON(atomic_read(&dp->dl_count) < 0);
- dprintk("NFSD: nfs4_cb_recall_done: dp %p dl_flock %p dl_count %d\n",dp, dp->dl_flock, atomic_read(&dp->dl_count));
- return;
-
-retry:
- atomic_inc(&dp->dl_recall_cnt);
- /* sleep 2 seconds before retrying recall */
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(2*HZ);
- status = nfsd4_cb_recall(dp);
- dprintk("NFSD: nfs4_cb_recall_done: retry status: %d dp %p dl_flock %p\n",status,dp, dp->dl_flock);
-}