|
@@ -763,11 +763,20 @@ callback:
|
|
|
dprintk("lockd: GRANTing blocked lock.\n");
|
|
|
block->b_granted = 1;
|
|
|
|
|
|
- /* Schedule next grant callback in 30 seconds */
|
|
|
- nlmsvc_insert_block(block, 30 * HZ);
|
|
|
+ /* keep block on the list, but don't reattempt until the RPC
|
|
|
+ * completes or the submission fails
|
|
|
+ */
|
|
|
+ nlmsvc_insert_block(block, NLM_NEVER);
|
|
|
+
|
|
|
+ /* Call the client -- use a soft RPC task since nlmsvc_retry_blocked
|
|
|
+ * will queue up a new one if this one times out
|
|
|
+ */
|
|
|
+ error = nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG,
|
|
|
+ &nlmsvc_grant_ops);
|
|
|
|
|
|
- /* Call the client */
|
|
|
- nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG, &nlmsvc_grant_ops);
|
|
|
+ /* RPC submission failed, wait a bit and retry */
|
|
|
+ if (error < 0)
|
|
|
+ nlmsvc_insert_block(block, 10 * HZ);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -786,6 +795,17 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
|
|
|
|
|
|
dprintk("lockd: GRANT_MSG RPC callback\n");
|
|
|
|
|
|
+ /* if the block is not on a list at this point then it has
|
|
|
+ * been invalidated. Don't try to requeue it.
|
|
|
+ *
|
|
|
+ * FIXME: it's possible that the block is removed from the list
|
|
|
+ * after this check but before the nlmsvc_insert_block. In that
|
|
|
+ * case it will be added back. Perhaps we need better locking
|
|
|
+ * for nlm_blocked?
|
|
|
+ */
|
|
|
+ if (list_empty(&block->b_list))
|
|
|
+ return;
|
|
|
+
|
|
|
/* Technically, we should down the file semaphore here. Since we
|
|
|
* move the block towards the head of the queue only, no harm
|
|
|
* can be done, though. */
|