From 9f79fb4825cd336ba9efbb0d9468f2ef3fd3cbf6 Mon Sep 17 00:00:00 2001 From: Andy Adamson Date: Tue, 10 Sep 2013 12:56:29 -0400 Subject: NFSv4.1 fix decode_free_stateid The operation status is decoded in decode_op_hdr. Stop the print_overflow message that is always hit without this patch: nfs: decode_free_stateid: prematurely hit end of receive buffer. Remaining buffer length is 0 words. Signed-off-by: Andy Adamson Signed-off-by: Trond Myklebust --- fs/nfs/nfs4xdr.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) (limited to 'fs') diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index fbdad9e1719f..79210d23f607 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -414,7 +414,7 @@ static int nfs4_stat_to_errno(int); #define decode_test_stateid_maxsz (op_decode_hdr_maxsz + 2 + 1) #define encode_free_stateid_maxsz (op_encode_hdr_maxsz + 1 + \ XDR_QUADLEN(NFS4_STATEID_SIZE)) -#define decode_free_stateid_maxsz (op_decode_hdr_maxsz + 1) +#define decode_free_stateid_maxsz (op_decode_hdr_maxsz) #else /* CONFIG_NFS_V4_1 */ #define encode_sequence_maxsz 0 #define decode_sequence_maxsz 0 @@ -5966,21 +5966,8 @@ out: static int decode_free_stateid(struct xdr_stream *xdr, struct nfs41_free_stateid_res *res) { - __be32 *p; - int status; - - status = decode_op_hdr(xdr, OP_FREE_STATEID); - if (status) - return status; - - p = xdr_inline_decode(xdr, 4); - if (unlikely(!p)) - goto out_overflow; - res->status = be32_to_cpup(p++); + res->status = decode_op_hdr(xdr, OP_FREE_STATEID); return res->status; -out_overflow: - print_overflow_msg(__func__, xdr); - return -EIO; } #endif /* CONFIG_NFS_V4_1 */ -- cgit v1.2.3 From a02796250fe3e5fd053f33d90c1b3471617188a9 Mon Sep 17 00:00:00 2001 From: Weston Andros Adamson Date: Tue, 10 Sep 2013 18:44:30 -0400 Subject: NFSv4.1: sp4_mach_cred: ask for WRITE and COMMIT Request SP4_MACH_CRED WRITE and COMMIT support in spo_must_allow list -- they're already supported by the client. Signed-off-by: Weston Andros Adamson Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index e1212914bc03..4aeb14e902d9 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -6153,11 +6153,13 @@ static const struct nfs41_state_protection nfs4_sp4_mach_cred_request = { }, .allow.u.words = { [0] = 1 << (OP_CLOSE) | - 1 << (OP_LOCKU), + 1 << (OP_LOCKU) | + 1 << (OP_COMMIT), [1] = 1 << (OP_SECINFO - 32) | 1 << (OP_SECINFO_NO_NAME - 32) | 1 << (OP_TEST_STATEID - 32) | - 1 << (OP_FREE_STATEID - 32) + 1 << (OP_FREE_STATEID - 32) | + 1 << (OP_WRITE - 32) } }; -- cgit v1.2.3 From 7cb852dfc858e9ab092cbbfcb3e57bae4aa7f56a Mon Sep 17 00:00:00 2001 From: Weston Andros Adamson Date: Tue, 10 Sep 2013 18:44:31 -0400 Subject: NFSv4.1: fix SECINFO* use of put_rpccred Recent SP4_MACH_CRED changes allows rpc_message.rpc_cred to change, so keep a separate pointer to the machine cred for put_rpccred. Signed-off-by: Weston Andros Adamson Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'fs') diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 4aeb14e902d9..4b6a2f05b335 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -6003,10 +6003,12 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct .rpc_resp = &res, }; struct rpc_clnt *clnt = NFS_SERVER(dir)->client; + struct rpc_cred *cred = NULL; if (use_integrity) { clnt = NFS_SERVER(dir)->nfs_client->cl_rpcclient; - msg.rpc_cred = nfs4_get_clid_cred(NFS_SERVER(dir)->nfs_client); + cred = nfs4_get_clid_cred(NFS_SERVER(dir)->nfs_client); + msg.rpc_cred = cred; } dprintk("NFS call secinfo %s\n", name->name); @@ -6018,8 +6020,8 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct &res.seq_res, 0); dprintk("NFS reply secinfo: %d\n", status); - if (msg.rpc_cred) - put_rpccred(msg.rpc_cred); + if (cred) + put_rpccred(cred); return status; } @@ -7500,11 +7502,13 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle, .rpc_resp = &res, }; struct rpc_clnt *clnt = server->client; + struct rpc_cred *cred = NULL; int status; if (use_integrity) { clnt = server->nfs_client->cl_rpcclient; - msg.rpc_cred = nfs4_get_clid_cred(server->nfs_client); + cred = nfs4_get_clid_cred(server->nfs_client); + msg.rpc_cred = cred; } dprintk("--> %s\n", __func__); @@ -7512,8 +7516,8 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle, &res.seq_res, 0); dprintk("<-- %s status=%d\n", __func__, status); - if (msg.rpc_cred) - put_rpccred(msg.rpc_cred); + if (cred) + put_rpccred(cred); return status; } -- cgit v1.2.3 From ade33ff58ed3efb4a069f7256f5a92ccf8634413 Mon Sep 17 00:00:00 2001 From: Weston Andros Adamson Date: Tue, 10 Sep 2013 18:44:32 -0400 Subject: NFSv4.1: sp4_mach_cred: no need to ref count creds The cl_machine_cred doesn't need to be reference counted here - a reference is held is for the lifetime of the struct nfs_client. Also, no need to put_rpccred the rpc_message.rpc_cred. Signed-off-by: Weston Andros Adamson Signed-off-by: Trond Myklebust --- fs/nfs/nfs4_fs.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'fs') diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index f520a1113b38..07a8aa9cd7ee 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -279,10 +279,10 @@ _nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode, if (test_bit(sp4_mode, &clp->cl_sp4_flags)) { spin_lock(&clp->cl_lock); if (clp->cl_machine_cred != NULL) - newcred = get_rpccred(clp->cl_machine_cred); + /* don't call get_rpccred on the machine cred - + * a reference will be held for life of clp */ + newcred = clp->cl_machine_cred; spin_unlock(&clp->cl_lock); - if (msg->rpc_cred) - put_rpccred(msg->rpc_cred); msg->rpc_cred = newcred; flavor = clp->cl_rpcclient->cl_auth->au_flavor; -- cgit v1.2.3 From 312cd958a7433feef9c6f3ce6b06471e760e452f Mon Sep 17 00:00:00 2001 From: Weston Andros Adamson Date: Tue, 10 Sep 2013 18:44:33 -0400 Subject: NFSv4.1: sp4_mach_cred: WARN_ON -> WARN_ON_ONCE No need to spam the logs Signed-off-by: Weston Andros Adamson Signed-off-by: Trond Myklebust --- fs/nfs/nfs4_fs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs') diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 07a8aa9cd7ee..28842abafab4 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -286,8 +286,8 @@ _nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode, msg->rpc_cred = newcred; flavor = clp->cl_rpcclient->cl_auth->au_flavor; - WARN_ON(flavor != RPC_AUTH_GSS_KRB5I && - flavor != RPC_AUTH_GSS_KRB5P); + WARN_ON_ONCE(flavor != RPC_AUTH_GSS_KRB5I && + flavor != RPC_AUTH_GSS_KRB5P); *clntp = clp->cl_rpcclient; return true; -- cgit v1.2.3