Merge branch 'for-1209' of git://gitorious.org/smack-next/kernel into next
[deliverable/linux.git] / fs / nfs / idmap.c
index 864c51e4b400e5c7248bdd93eaed19772c0f23f2..b701358c39c351d0613d1db29ebcf382ca8cb0a6 100644 (file)
@@ -52,8 +52,6 @@
 
 #define NFS_UINT_MAXLEN 11
 
-/* Default cache timeout is 10 minutes */
-unsigned int nfs_idmap_cache_timeout = 600;
 static const struct cred *id_resolver_cache;
 static struct key_type key_type_id_resolver_legacy;
 
@@ -205,12 +203,18 @@ static int nfs_idmap_init_keyring(void)
        if (ret < 0)
                goto failed_put_key;
 
+       ret = register_key_type(&key_type_id_resolver_legacy);
+       if (ret < 0)
+               goto failed_reg_legacy;
+
        set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
        cred->thread_keyring = keyring;
        cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
        id_resolver_cache = cred;
        return 0;
 
+failed_reg_legacy:
+       unregister_key_type(&key_type_id_resolver);
 failed_put_key:
        key_put(keyring);
 failed_put_cred:
@@ -222,6 +226,7 @@ static void nfs_idmap_quit_keyring(void)
 {
        key_revoke(id_resolver_cache->thread_keyring);
        unregister_key_type(&key_type_id_resolver);
+       unregister_key_type(&key_type_id_resolver_legacy);
        put_cred(id_resolver_cache);
 }
 
@@ -359,7 +364,6 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *typ
 }
 
 /* idmap classic begins here */
-module_param(nfs_idmap_cache_timeout, int, 0644);
 
 enum {
        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 = {
 };
 
 static struct key_type key_type_id_resolver_legacy = {
-       .name           = "id_resolver",
+       .name           = "id_legacy",
        .instantiate    = user_instantiate,
        .match          = user_match,
        .revoke         = user_revoke,
@@ -674,6 +678,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
        if (ret < 0)
                goto out2;
 
+       BUG_ON(idmap->idmap_key_cons != NULL);
        idmap->idmap_key_cons = cons;
 
        ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
@@ -687,8 +692,7 @@ out2:
 out1:
        kfree(msg);
 out0:
-       key_revoke(cons->key);
-       key_revoke(cons->authkey);
+       complete_request_key(cons, ret);
        return ret;
 }
 
@@ -722,11 +726,18 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
 {
        struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
        struct idmap *idmap = (struct idmap *)rpci->private;
-       struct key_construction *cons = idmap->idmap_key_cons;
+       struct key_construction *cons;
        struct idmap_msg im;
        size_t namelen_in;
        int ret;
 
+       /* If instantiation is successful, anyone waiting for key construction
+        * will have been woken up and someone else may now have used
+        * idmap_key_cons - so after this point we may no longer touch it.
+        */
+       cons = ACCESS_ONCE(idmap->idmap_key_cons);
+       idmap->idmap_key_cons = NULL;
+
        if (mlen != sizeof(im)) {
                ret = -ENOSPC;
                goto out;
@@ -739,7 +750,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
 
        if (!(im.im_status & IDMAP_STATUS_SUCCESS)) {
                ret = mlen;
-               complete_request_key(idmap->idmap_key_cons, -ENOKEY);
+               complete_request_key(cons, -ENOKEY);
                goto out_incomplete;
        }
 
@@ -756,7 +767,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
        }
 
 out:
-       complete_request_key(idmap->idmap_key_cons, ret);
+       complete_request_key(cons, ret);
 out_incomplete:
        return ret;
 }
This page took 0.03244 seconds and 5 git commands to generate.