diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-12 16:39:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-12 16:39:34 -0400 |
commit | 1d7b24ff335489dd7e864b71ba5b35eaa25b625a (patch) | |
tree | f27815967e44510a833cf0e017c2ecc004c14e8d /fs/nfs | |
parent | 68f0d9d92e5430e250f2bd2a1e7a350e880d776a (diff) | |
parent | 23c323af0375a7f63732bed0386aba5935b8de69 (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.h | 10 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 22 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 17 |
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: | |||
5966 | static int decode_free_stateid(struct xdr_stream *xdr, | 5966 | static 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; |
5981 | out_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 | ||