summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/lockd/host.c10
-rw-r--r--fs/lockd/svclock.c28
-rw-r--r--include/linux/sunrpc/svc.h13
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_sendto.c3
4 files changed, 40 insertions, 14 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index ca6b16fc310..f1ef49fff11 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -243,10 +243,18 @@ nlm_bind_host(struct nlm_host *host)
.program = &nlm_program,
.version = host->h_version,
.authflavor = RPC_AUTH_UNIX,
- .flags = (RPC_CLNT_CREATE_HARDRTRY |
+ .flags = (RPC_CLNT_CREATE_NOPING |
RPC_CLNT_CREATE_AUTOBIND),
};
+ /*
+ * lockd retries server side blocks automatically so we want
+ * those to be soft RPC calls. Client side calls need to be
+ * hard RPC tasks.
+ */
+ if (!host->h_server)
+ args.flags |= RPC_CLNT_CREATE_HARDRTRY;
+
clnt = rpc_create(&args);
if (!IS_ERR(clnt))
host->h_rpcclnt = clnt;
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 2f4d8fa6668..fe9bdb4a220 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -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. */
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 64c77105618..64c97552964 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -409,16 +409,13 @@ char * svc_print_addr(struct svc_rqst *, char *, size_t);
* for all cases without actually generating the checksum, so we just use a
* static value.
*/
-static inline void
-svc_reserve_auth(struct svc_rqst *rqstp, int space)
+static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space)
{
- int added_space = 0;
+ int added_space = 0;
- switch(rqstp->rq_authop->flavour) {
- case RPC_AUTH_GSS:
- added_space = RPC_MAX_AUTH_SIZE;
- }
- return svc_reserve(rqstp, space + added_space);
+ if (rqstp->rq_authop->flavour)
+ added_space = RPC_MAX_AUTH_SIZE;
+ svc_reserve(rqstp, space + added_space);
}
#endif /* SUNRPC_SVC_H */
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 3e321949e1d..0598b229c11 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -159,7 +159,8 @@ static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp,
BUG_ON(sge_count >= 32);
dprintk("svcrdma: RDMA_WRITE rmr=%x, to=%llx, xdr_off=%d, "
"write_len=%d, xdr_sge=%p, sge_count=%d\n",
- rmr, to, xdr_off, write_len, xdr_sge, sge_count);
+ rmr, (unsigned long long)to, xdr_off,
+ write_len, xdr_sge, sge_count);
ctxt = svc_rdma_get_context(xprt);
ctxt->count = 0;