diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-31 21:45:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-31 21:45:44 -0400 |
commit | 6dbb35b0a74b44b2a48a5373d48074c5aa69fdf5 (patch) | |
tree | 4afb5eec521659e19c9d2343c2431054a082eb06 /fs/nfs/idmap.c | |
parent | fd37ce34bd512f2b1a503f82abf8768da556a955 (diff) | |
parent | ad0fcd4eb68059de02e1766948263c71b8a5b1dc (diff) |
Merge tag 'nfs-for-3.6-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull second wave of NFS client updates from Trond Myklebust:
- Patches from Bryan to allow splitting of the NFSv2/v3/v4 code into
separate modules.
- Fix Oopses in the NFSv4 idmapper
- Fix a deadlock whereby rpciod tries to allocate a new socket and ends
up recursing into the NFS code due to memory reclaim.
- Increase the number of permitted callback connections.
* tag 'nfs-for-3.6-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
nfs: explicitly reject LOCK_MAND flock() requests
nfs: increase number of permitted callback connections.
SUNRPC: return negative value in case rpcbind client creation error
NFS: Convert v4 into a module
NFS: Convert v3 into a module
NFS: Convert v2 into a module
NFS: Keep module parameters in the generic NFS client
NFS: Split out remaining NFS v4 inode functions
NFS: Pass super operations and xattr handlers in the nfs_subversion
NFS: Only initialize the ACL client in the v3 case
NFS: Create a try_mount rpc op
NFS: Remove the NFS v4 xdev mount function
NFS: Add version registering framework
NFS: Fix a number of bugs in the idmapper
nfs: skip commit in releasepage if we're freeing memory for fs-related reasons
sunrpc: clarify comments on rpc_make_runnable
pnfsblock: bail out partial page IO
Diffstat (limited to 'fs/nfs/idmap.c')
-rw-r--r-- | fs/nfs/idmap.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 864c51e4b400..b701358c39c3 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -52,8 +52,6 @@ | |||
52 | 52 | ||
53 | #define NFS_UINT_MAXLEN 11 | 53 | #define NFS_UINT_MAXLEN 11 |
54 | 54 | ||
55 | /* Default cache timeout is 10 minutes */ | ||
56 | unsigned int nfs_idmap_cache_timeout = 600; | ||
57 | static const struct cred *id_resolver_cache; | 55 | static const struct cred *id_resolver_cache; |
58 | static struct key_type key_type_id_resolver_legacy; | 56 | static struct key_type key_type_id_resolver_legacy; |
59 | 57 | ||
@@ -205,12 +203,18 @@ static int nfs_idmap_init_keyring(void) | |||
205 | if (ret < 0) | 203 | if (ret < 0) |
206 | goto failed_put_key; | 204 | goto failed_put_key; |
207 | 205 | ||
206 | ret = register_key_type(&key_type_id_resolver_legacy); | ||
207 | if (ret < 0) | ||
208 | goto failed_reg_legacy; | ||
209 | |||
208 | set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); | 210 | set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); |
209 | cred->thread_keyring = keyring; | 211 | cred->thread_keyring = keyring; |
210 | cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; | 212 | cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; |
211 | id_resolver_cache = cred; | 213 | id_resolver_cache = cred; |
212 | return 0; | 214 | return 0; |
213 | 215 | ||
216 | failed_reg_legacy: | ||
217 | unregister_key_type(&key_type_id_resolver); | ||
214 | failed_put_key: | 218 | failed_put_key: |
215 | key_put(keyring); | 219 | key_put(keyring); |
216 | failed_put_cred: | 220 | failed_put_cred: |
@@ -222,6 +226,7 @@ static void nfs_idmap_quit_keyring(void) | |||
222 | { | 226 | { |
223 | key_revoke(id_resolver_cache->thread_keyring); | 227 | key_revoke(id_resolver_cache->thread_keyring); |
224 | unregister_key_type(&key_type_id_resolver); | 228 | unregister_key_type(&key_type_id_resolver); |
229 | unregister_key_type(&key_type_id_resolver_legacy); | ||
225 | put_cred(id_resolver_cache); | 230 | put_cred(id_resolver_cache); |
226 | } | 231 | } |
227 | 232 | ||
@@ -359,7 +364,6 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *typ | |||
359 | } | 364 | } |
360 | 365 | ||
361 | /* idmap classic begins here */ | 366 | /* idmap classic begins here */ |
362 | module_param(nfs_idmap_cache_timeout, int, 0644); | ||
363 | 367 | ||
364 | enum { | 368 | enum { |
365 | Opt_find_uid, Opt_find_gid, Opt_find_user, Opt_find_group, Opt_find_err | 369 | Opt_find_uid, Opt_find_gid, Opt_find_user, Opt_find_group, Opt_find_err |
@@ -385,7 +389,7 @@ static const struct rpc_pipe_ops idmap_upcall_ops = { | |||
385 | }; | 389 | }; |
386 | 390 | ||
387 | static struct key_type key_type_id_resolver_legacy = { | 391 | static struct key_type key_type_id_resolver_legacy = { |
388 | .name = "id_resolver", | 392 | .name = "id_legacy", |
389 | .instantiate = user_instantiate, | 393 | .instantiate = user_instantiate, |
390 | .match = user_match, | 394 | .match = user_match, |
391 | .revoke = user_revoke, | 395 | .revoke = user_revoke, |
@@ -674,6 +678,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons, | |||
674 | if (ret < 0) | 678 | if (ret < 0) |
675 | goto out2; | 679 | goto out2; |
676 | 680 | ||
681 | BUG_ON(idmap->idmap_key_cons != NULL); | ||
677 | idmap->idmap_key_cons = cons; | 682 | idmap->idmap_key_cons = cons; |
678 | 683 | ||
679 | ret = rpc_queue_upcall(idmap->idmap_pipe, msg); | 684 | ret = rpc_queue_upcall(idmap->idmap_pipe, msg); |
@@ -687,8 +692,7 @@ out2: | |||
687 | out1: | 692 | out1: |
688 | kfree(msg); | 693 | kfree(msg); |
689 | out0: | 694 | out0: |
690 | key_revoke(cons->key); | 695 | complete_request_key(cons, ret); |
691 | key_revoke(cons->authkey); | ||
692 | return ret; | 696 | return ret; |
693 | } | 697 | } |
694 | 698 | ||
@@ -722,11 +726,18 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
722 | { | 726 | { |
723 | struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode); | 727 | struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode); |
724 | struct idmap *idmap = (struct idmap *)rpci->private; | 728 | struct idmap *idmap = (struct idmap *)rpci->private; |
725 | struct key_construction *cons = idmap->idmap_key_cons; | 729 | struct key_construction *cons; |
726 | struct idmap_msg im; | 730 | struct idmap_msg im; |
727 | size_t namelen_in; | 731 | size_t namelen_in; |
728 | int ret; | 732 | int ret; |
729 | 733 | ||
734 | /* If instantiation is successful, anyone waiting for key construction | ||
735 | * will have been woken up and someone else may now have used | ||
736 | * idmap_key_cons - so after this point we may no longer touch it. | ||
737 | */ | ||
738 | cons = ACCESS_ONCE(idmap->idmap_key_cons); | ||
739 | idmap->idmap_key_cons = NULL; | ||
740 | |||
730 | if (mlen != sizeof(im)) { | 741 | if (mlen != sizeof(im)) { |
731 | ret = -ENOSPC; | 742 | ret = -ENOSPC; |
732 | goto out; | 743 | goto out; |
@@ -739,7 +750,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
739 | 750 | ||
740 | if (!(im.im_status & IDMAP_STATUS_SUCCESS)) { | 751 | if (!(im.im_status & IDMAP_STATUS_SUCCESS)) { |
741 | ret = mlen; | 752 | ret = mlen; |
742 | complete_request_key(idmap->idmap_key_cons, -ENOKEY); | 753 | complete_request_key(cons, -ENOKEY); |
743 | goto out_incomplete; | 754 | goto out_incomplete; |
744 | } | 755 | } |
745 | 756 | ||
@@ -756,7 +767,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
756 | } | 767 | } |
757 | 768 | ||
758 | out: | 769 | out: |
759 | complete_request_key(idmap->idmap_key_cons, ret); | 770 | complete_request_key(cons, ret); |
760 | out_incomplete: | 771 | out_incomplete: |
761 | return ret; | 772 | return ret; |
762 | } | 773 | } |