aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-12 16:39:34 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-12 16:39:34 -0400
commit1d7b24ff335489dd7e864b71ba5b35eaa25b625a (patch)
treef27815967e44510a833cf0e017c2ecc004c14e8d /fs/nfs
parent68f0d9d92e5430e250f2bd2a1e7a350e880d776a (diff)
parent23c323af0375a7f63732bed0386aba5935b8de69 (diff)
Merge tag 'nfs-for-3.12-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfixes (part 2) from Trond Myklebust: "Bugfixes: - Fix a few credential reference leaks resulting from the SP4_MACH_CRED NFSv4.1 state protection code. - Fix the SUNRPC bloatometer footprint: convert a 256K hashtable into the intended 64 byte structure. - Fix a long standing XDR issue with FREE_STATEID - Fix a potential WARN_ON spamming issue - Fix a missing dprintk() kuid conversion New features: - Enable the NFSv4.1 state protection support for the WRITE and COMMIT operations" * tag 'nfs-for-3.12-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: SUNRPC: No, I did not intend to create a 256KiB hashtable sunrpc: Add missing kuids conversion for printing NFSv4.1: sp4_mach_cred: WARN_ON -> WARN_ON_ONCE NFSv4.1: sp4_mach_cred: no need to ref count creds NFSv4.1: fix SECINFO* use of put_rpccred NFSv4.1: sp4_mach_cred: ask for WRITE and COMMIT NFSv4.1 fix decode_free_stateid
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4_fs.h10
-rw-r--r--fs/nfs/nfs4proc.c22
-rw-r--r--fs/nfs/nfs4xdr.c17
3 files changed, 21 insertions, 28 deletions
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index f520a1113b38..28842abafab4 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -279,15 +279,15 @@ _nfs4_state_protect(struct nfs_client *clp, unsigned long sp4_mode,
279 if (test_bit(sp4_mode, &clp->cl_sp4_flags)) { 279 if (test_bit(sp4_mode, &clp->cl_sp4_flags)) {
280 spin_lock(&clp->cl_lock); 280 spin_lock(&clp->cl_lock);
281 if (clp->cl_machine_cred != NULL) 281 if (clp->cl_machine_cred != NULL)
282 newcred = get_rpccred(clp->cl_machine_cred); 282 /* don't call get_rpccred on the machine cred -
283 * a reference will be held for life of clp */
284 newcred = clp->cl_machine_cred;
283 spin_unlock(&clp->cl_lock); 285 spin_unlock(&clp->cl_lock);
284 if (msg->rpc_cred)
285 put_rpccred(msg->rpc_cred);
286 msg->rpc_cred = newcred; 286 msg->rpc_cred = newcred;
287 287
288 flavor = clp->cl_rpcclient->cl_auth->au_flavor; 288 flavor = clp->cl_rpcclient->cl_auth->au_flavor;
289 WARN_ON(flavor != RPC_AUTH_GSS_KRB5I && 289 WARN_ON_ONCE(flavor != RPC_AUTH_GSS_KRB5I &&
290 flavor != RPC_AUTH_GSS_KRB5P); 290 flavor != RPC_AUTH_GSS_KRB5P);
291 *clntp = clp->cl_rpcclient; 291 *clntp = clp->cl_rpcclient;
292 292
293 return true; 293 return true;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 39b6cf2d1683..989bb9d3074d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -6001,10 +6001,12 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
6001 .rpc_resp = &res, 6001 .rpc_resp = &res,
6002 }; 6002 };
6003 struct rpc_clnt *clnt = NFS_SERVER(dir)->client; 6003 struct rpc_clnt *clnt = NFS_SERVER(dir)->client;
6004 struct rpc_cred *cred = NULL;
6004 6005
6005 if (use_integrity) { 6006 if (use_integrity) {
6006 clnt = NFS_SERVER(dir)->nfs_client->cl_rpcclient; 6007 clnt = NFS_SERVER(dir)->nfs_client->cl_rpcclient;
6007 msg.rpc_cred = nfs4_get_clid_cred(NFS_SERVER(dir)->nfs_client); 6008 cred = nfs4_get_clid_cred(NFS_SERVER(dir)->nfs_client);
6009 msg.rpc_cred = cred;
6008 } 6010 }
6009 6011
6010 dprintk("NFS call secinfo %s\n", name->name); 6012 dprintk("NFS call secinfo %s\n", name->name);
@@ -6016,8 +6018,8 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
6016 &res.seq_res, 0); 6018 &res.seq_res, 0);
6017 dprintk("NFS reply secinfo: %d\n", status); 6019 dprintk("NFS reply secinfo: %d\n", status);
6018 6020
6019 if (msg.rpc_cred) 6021 if (cred)
6020 put_rpccred(msg.rpc_cred); 6022 put_rpccred(cred);
6021 6023
6022 return status; 6024 return status;
6023} 6025}
@@ -6151,11 +6153,13 @@ static const struct nfs41_state_protection nfs4_sp4_mach_cred_request = {
6151 }, 6153 },
6152 .allow.u.words = { 6154 .allow.u.words = {
6153 [0] = 1 << (OP_CLOSE) | 6155 [0] = 1 << (OP_CLOSE) |
6154 1 << (OP_LOCKU), 6156 1 << (OP_LOCKU) |
6157 1 << (OP_COMMIT),
6155 [1] = 1 << (OP_SECINFO - 32) | 6158 [1] = 1 << (OP_SECINFO - 32) |
6156 1 << (OP_SECINFO_NO_NAME - 32) | 6159 1 << (OP_SECINFO_NO_NAME - 32) |
6157 1 << (OP_TEST_STATEID - 32) | 6160 1 << (OP_TEST_STATEID - 32) |
6158 1 << (OP_FREE_STATEID - 32) 6161 1 << (OP_FREE_STATEID - 32) |
6162 1 << (OP_WRITE - 32)
6159 } 6163 }
6160}; 6164};
6161 6165
@@ -7496,11 +7500,13 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
7496 .rpc_resp = &res, 7500 .rpc_resp = &res,
7497 }; 7501 };
7498 struct rpc_clnt *clnt = server->client; 7502 struct rpc_clnt *clnt = server->client;
7503 struct rpc_cred *cred = NULL;
7499 int status; 7504 int status;
7500 7505
7501 if (use_integrity) { 7506 if (use_integrity) {
7502 clnt = server->nfs_client->cl_rpcclient; 7507 clnt = server->nfs_client->cl_rpcclient;
7503 msg.rpc_cred = nfs4_get_clid_cred(server->nfs_client); 7508 cred = nfs4_get_clid_cred(server->nfs_client);
7509 msg.rpc_cred = cred;
7504 } 7510 }
7505 7511
7506 dprintk("--> %s\n", __func__); 7512 dprintk("--> %s\n", __func__);
@@ -7508,8 +7514,8 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
7508 &res.seq_res, 0); 7514 &res.seq_res, 0);
7509 dprintk("<-- %s status=%d\n", __func__, status); 7515 dprintk("<-- %s status=%d\n", __func__, status);
7510 7516
7511 if (msg.rpc_cred) 7517 if (cred)
7512 put_rpccred(msg.rpc_cred); 7518 put_rpccred(cred);
7513 7519
7514 return status; 7520 return status;
7515} 7521}
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);
414#define decode_test_stateid_maxsz (op_decode_hdr_maxsz + 2 + 1) 414#define decode_test_stateid_maxsz (op_decode_hdr_maxsz + 2 + 1)
415#define encode_free_stateid_maxsz (op_encode_hdr_maxsz + 1 + \ 415#define encode_free_stateid_maxsz (op_encode_hdr_maxsz + 1 + \
416 XDR_QUADLEN(NFS4_STATEID_SIZE)) 416 XDR_QUADLEN(NFS4_STATEID_SIZE))
417#define decode_free_stateid_maxsz (op_decode_hdr_maxsz + 1) 417#define decode_free_stateid_maxsz (op_decode_hdr_maxsz)
418#else /* CONFIG_NFS_V4_1 */ 418#else /* CONFIG_NFS_V4_1 */
419#define encode_sequence_maxsz 0 419#define encode_sequence_maxsz 0
420#define decode_sequence_maxsz 0 420#define decode_sequence_maxsz 0
@@ -5966,21 +5966,8 @@ out:
5966static int decode_free_stateid(struct xdr_stream *xdr, 5966static int decode_free_stateid(struct xdr_stream *xdr,
5967 struct nfs41_free_stateid_res *res) 5967 struct nfs41_free_stateid_res *res)
5968{ 5968{
5969 __be32 *p; 5969 res->status = decode_op_hdr(xdr, OP_FREE_STATEID);
5970 int status;
5971
5972 status = decode_op_hdr(xdr, OP_FREE_STATEID);
5973 if (status)
5974 return status;
5975
5976 p = xdr_inline_decode(xdr, 4);
5977 if (unlikely(!p))
5978 goto out_overflow;
5979 res->status = be32_to_cpup(p++);
5980 return res->status; 5970 return res->status;
5981out_overflow:
5982 print_overflow_msg(__func__, xdr);
5983 return -EIO;
5984} 5971}
5985#endif /* CONFIG_NFS_V4_1 */ 5972#endif /* CONFIG_NFS_V4_1 */
5986 5973