aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/lockd/svc4proc.c12
-rw-r--r--fs/lockd/svcproc.c16
-rw-r--r--fs/lockd/svcsubs.c6
-rw-r--r--fs/nfsd/lockd.c14
-rw-r--r--include/linux/lockd/bind.h5
-rw-r--r--include/linux/lockd/xdr.h4
-rw-r--r--include/linux/sunrpc/msg_prot.h4
-rw-r--r--include/linux/sunrpc/xdr.h1
-rw-r--r--net/sunrpc/svc.c5
9 files changed, 41 insertions, 26 deletions
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index fa370f6..399ad11 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -96,7 +96,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Obtain client and file */
if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
- return rpc_success;
+ return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
/* Now check for conflicting locks */
resp->status = nlmsvc_testlock(file, &argp->lock, &resp->lock);
@@ -126,7 +126,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Obtain client and file */
if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
- return rpc_success;
+ return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
#if 0
/* If supplied state doesn't match current state, we assume it's
@@ -169,7 +169,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Obtain client and file */
if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
- return rpc_success;
+ return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
/* Try to cancel request. */
resp->status = nlmsvc_cancel_blocked(file, &argp->lock);
@@ -202,7 +202,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Obtain client and file */
if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
- return rpc_success;
+ return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
/* Now try to remove the lock */
resp->status = nlmsvc_unlock(file, &argp->lock);
@@ -339,7 +339,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Obtain client and file */
if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
- return rpc_success;
+ return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
/* Now try to create the share */
resp->status = nlmsvc_share_file(host, file, argp);
@@ -372,7 +372,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Obtain client and file */
if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
- return rpc_success;
+ return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
/* Now try to lock the file */
resp->status = nlmsvc_unshare_file(host, file, argp);
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 75b2c81..6a931f4 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -59,7 +59,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
struct nlm_host *host = NULL;
struct nlm_file *file = NULL;
struct nlm_lock *lock = &argp->lock;
- u32 error;
+ u32 error = 0;
/* nfsd callbacks must have been installed for this procedure */
if (!nlmsvc_ops)
@@ -88,6 +88,8 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
no_locks:
if (host)
nlm_release_host(host);
+ if (error)
+ return error;
return nlm_lck_denied_nolocks;
}
@@ -122,7 +124,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Obtain client and file */
if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
- return rpc_success;
+ return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
/* Now check for conflicting locks */
resp->status = cast_status(nlmsvc_testlock(file, &argp->lock, &resp->lock));
@@ -153,7 +155,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Obtain client and file */
if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
- return rpc_success;
+ return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
#if 0
/* If supplied state doesn't match current state, we assume it's
@@ -196,7 +198,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Obtain client and file */
if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
- return rpc_success;
+ return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
/* Try to cancel request. */
resp->status = cast_status(nlmsvc_cancel_blocked(file, &argp->lock));
@@ -229,7 +231,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Obtain client and file */
if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
- return rpc_success;
+ return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
/* Now try to remove the lock */
resp->status = cast_status(nlmsvc_unlock(file, &argp->lock));
@@ -368,7 +370,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Obtain client and file */
if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
- return rpc_success;
+ return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
/* Now try to create the share */
resp->status = cast_status(nlmsvc_share_file(host, file, argp));
@@ -401,7 +403,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp,
/* Obtain client and file */
if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file)))
- return rpc_success;
+ return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
/* Now try to unshare the file */
resp->status = cast_status(nlmsvc_unshare_file(host, file, argp));
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index c5f9113..7dac96e 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -135,12 +135,6 @@ out_unlock:
out_free:
kfree(file);
-#ifdef CONFIG_LOCKD_V4
- if (nfserr == 1)
- nfserr = nlm4_stale_fh;
- else
-#endif
- nfserr = nlm_lck_denied;
goto out_unlock;
}
diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c
index 7b889ff..9b9e7e1 100644
--- a/fs/nfsd/lockd.c
+++ b/fs/nfsd/lockd.c
@@ -39,18 +39,20 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp)
fh_put(&fh);
rqstp->rq_client = NULL;
exp_readunlock();
- /* nlm and nfsd don't share error codes.
- * we invent: 0 = no error
- * 1 = stale file handle
- * 2 = other error
+ /* We return nlm error codes as nlm doesn't know
+ * about nfsd, but nfsd does know about nlm..
*/
switch (nfserr) {
case nfs_ok:
return 0;
+ case nfserr_dropit:
+ return nlm_drop_reply;
+#ifdef CONFIG_LOCKD_V4
case nfserr_stale:
- return 1;
+ return nlm4_stale_fh;
+#endif
default:
- return 2;
+ return nlm_lck_denied;
}
}
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index 81e3a18..aa50d89 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -10,6 +10,11 @@
#define LINUX_LOCKD_BIND_H
#include <linux/lockd/nlm.h>
+/* need xdr-encoded error codes too, so... */
+#include <linux/lockd/xdr.h>
+#ifdef CONFIG_LOCKD_V4
+#include <linux/lockd/xdr4.h>
+#endif
/* Dummy declarations */
struct svc_rqst;
diff --git a/include/linux/lockd/xdr.h b/include/linux/lockd/xdr.h
index bb0a0f1..66fdae3 100644
--- a/include/linux/lockd/xdr.h
+++ b/include/linux/lockd/xdr.h
@@ -13,6 +13,8 @@
#include <linux/nfs.h>
#include <linux/sunrpc/xdr.h>
+struct svc_rqst;
+
#define NLM_MAXCOOKIELEN 32
#define NLM_MAXSTRLEN 1024
@@ -22,6 +24,8 @@
#define nlm_lck_blocked __constant_htonl(NLM_LCK_BLOCKED)
#define nlm_lck_denied_grace_period __constant_htonl(NLM_LCK_DENIED_GRACE_PERIOD)
+#define nlm_drop_reply __constant_htonl(30000)
+
/* Lock info passed via NLM */
struct nlm_lock {
char * caller;
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
index 1e65f2d..606cb21 100644
--- a/include/linux/sunrpc/msg_prot.h
+++ b/include/linux/sunrpc/msg_prot.h
@@ -56,7 +56,9 @@ enum rpc_accept_stat {
RPC_PROG_MISMATCH = 2,
RPC_PROC_UNAVAIL = 3,
RPC_GARBAGE_ARGS = 4,
- RPC_SYSTEM_ERR = 5
+ RPC_SYSTEM_ERR = 5,
+ /* internal use only */
+ RPC_DROP_REPLY = 60000,
};
enum rpc_reject_stat {
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 953723b..ac69e55 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -74,6 +74,7 @@ struct xdr_buf {
#define rpc_proc_unavail __constant_htonl(RPC_PROC_UNAVAIL)
#define rpc_garbage_args __constant_htonl(RPC_GARBAGE_ARGS)
#define rpc_system_err __constant_htonl(RPC_SYSTEM_ERR)
+#define rpc_drop_reply __constant_htonl(RPC_DROP_REPLY)
#define rpc_auth_ok __constant_htonl(RPC_AUTH_OK)
#define rpc_autherr_badcred __constant_htonl(RPC_AUTH_BADCRED)
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 2807fa0..eb44ec9 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -828,6 +828,11 @@ svc_process(struct svc_rqst *rqstp)
*statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
/* Encode reply */
+ if (*statp == rpc_drop_reply) {
+ if (procp->pc_release)
+ procp->pc_release(rqstp, NULL, rqstp->rq_resp);
+ goto dropit;
+ }
if (*statp == rpc_success && (xdr = procp->pc_encode)
&& !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) {
dprintk("svc: failed to encode reply\n");