]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
cred: add get_cred_rcu()
authorNeilBrown <neilb@suse.com>
Mon, 3 Dec 2018 00:30:30 +0000 (11:30 +1100)
committerAnna Schumaker <Anna.Schumaker@Netapp.com>
Wed, 19 Dec 2018 18:52:44 +0000 (13:52 -0500)
Sometimes we want to opportunistically get a
ref to a cred in an rcu_read_lock protected section.
get_task_cred() does this, and NFS does as similar thing
with its own credential structures.
To prepare for NFS converting to use 'struct cred' more
uniformly, define get_cred_rcu(), and use it in
get_task_cred().

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
include/linux/cred.h
kernel/cred.c

index f1085767e1b3c1da858b196041ebd8af1a068142..48979fcb95cf959b031bef05d987263e20a65d17 100644 (file)
@@ -252,6 +252,17 @@ static inline const struct cred *get_cred(const struct cred *cred)
        return get_new_cred(nonconst_cred);
 }
 
+static inline const struct cred *get_cred_rcu(const struct cred *cred)
+{
+       struct cred *nonconst_cred = (struct cred *) cred;
+       if (!cred)
+               return NULL;
+       if (!atomic_inc_not_zero(&nonconst_cred->usage))
+               return NULL;
+       validate_creds(cred);
+       return cred;
+}
+
 /**
  * put_cred - Release a reference to a set of credentials
  * @cred: The credentials to release
index 0b3ac72bd71749494621a6a2cae55933ffbe671c..ba60162249e86dc1553b31c67e2f1e14a1fcdcf1 100644 (file)
@@ -195,7 +195,7 @@ const struct cred *get_task_cred(struct task_struct *task)
        do {
                cred = __task_cred((task));
                BUG_ON(!cred);
-       } while (!atomic_inc_not_zero(&((struct cred *)cred)->usage));
+       } while (!get_cred_rcu(cred));
 
        rcu_read_unlock();
        return cred;