Commit 5d36d77c authored by Trond Myklebust's avatar Trond Myklebust

Lockd: Fix waiting on the server grace period.

  The old code was wrong in that it assumed that we are out the grace
  period as soon as the client is finished doing lock recovery.
  Also ensure that we respect signals when waiting for the server grace
  period to end.
parent 0a496096
......@@ -228,7 +228,6 @@ reclaimer(void *ptr)
}
host->h_reclaiming = 0;
wake_up(&host->h_gracewait);
/* Now, wake up all processes that sleep on a blocked lock */
for (block = nlm_blocked; block; block = block->b_next) {
......
......@@ -217,6 +217,21 @@ nlmclnt_alloc_call(void)
return NULL;
}
static int nlm_wait_on_grace(wait_queue_head_t *queue)
{
DEFINE_WAIT(wait);
int status = -EINTR;
prepare_to_wait(queue, &wait, TASK_INTERRUPTIBLE);
if (!signalled ()) {
schedule_timeout(NLMCLNT_GRACE_WAIT);
if (!signalled ())
status = 0;
}
finish_wait(queue, &wait);
return status;
}
/*
* Generic NLM call
*/
......@@ -241,10 +256,8 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc)
msg.rpc_cred = nfs_file_cred(filp);
do {
if (host->h_reclaiming && !argp->reclaim) {
interruptible_sleep_on(&host->h_gracewait);
continue;
}
if (host->h_reclaiming && !argp->reclaim)
goto in_grace_period;
/* If we have no RPC client yet, create one. */
if ((clnt = nlm_bind_host(host)) == NULL)
......@@ -279,22 +292,23 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc)
return -ENOLCK;
}
} else {
if (!argp->reclaim) {
/* We appear to be out of the grace period */
wake_up_all(&host->h_gracewait);
}
dprintk("lockd: server returns status %d\n", resp->status);
return 0; /* Okay, call complete */
}
/* Back off a little and try again */
interruptible_sleep_on_timeout(&host->h_gracewait, 15*HZ);
/* When the lock requested by F_SETLKW isn't available,
we will wait until the request can be satisfied. If
a signal is received during wait, we should return
-EINTR. */
if (signalled ()) {
status = -EINTR;
break;
}
} while (1);
in_grace_period:
/*
* The server has rebooted and appears to be in the grace
* period during which locks are only allowed to be
* reclaimed.
* We can only back off and try again later.
*/
status = nlm_wait_on_grace(&host->h_gracewait);
} while (status == 0);
return status;
}
......
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