|
@@ -557,6 +557,12 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
|
|
|
hlist_for_each_entry_rcu(entry, &cache->hashtable[nr], cr_hash) {
|
|
|
if (!entry->cr_ops->crmatch(acred, entry, flags))
|
|
|
continue;
|
|
|
+ if (flags & RPCAUTH_LOOKUP_RCU) {
|
|
|
+ if (test_bit(RPCAUTH_CRED_HASHED, &entry->cr_flags) &&
|
|
|
+ !test_bit(RPCAUTH_CRED_NEW, &entry->cr_flags))
|
|
|
+ cred = entry;
|
|
|
+ break;
|
|
|
+ }
|
|
|
spin_lock(&cache->lock);
|
|
|
if (test_bit(RPCAUTH_CRED_HASHED, &entry->cr_flags) == 0) {
|
|
|
spin_unlock(&cache->lock);
|
|
@@ -571,6 +577,9 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
|
|
|
if (cred != NULL)
|
|
|
goto found;
|
|
|
|
|
|
+ if (flags & RPCAUTH_LOOKUP_RCU)
|
|
|
+ return ERR_PTR(-ECHILD);
|
|
|
+
|
|
|
new = auth->au_ops->crcreate(auth, acred, flags);
|
|
|
if (IS_ERR(new)) {
|
|
|
cred = new;
|
|
@@ -621,10 +630,14 @@ rpcauth_lookupcred(struct rpc_auth *auth, int flags)
|
|
|
memset(&acred, 0, sizeof(acred));
|
|
|
acred.uid = cred->fsuid;
|
|
|
acred.gid = cred->fsgid;
|
|
|
- acred.group_info = get_group_info(((struct cred *)cred)->group_info);
|
|
|
+ if (flags & RPCAUTH_LOOKUP_RCU)
|
|
|
+ acred.group_info = rcu_dereference(cred->group_info);
|
|
|
+ else
|
|
|
+ acred.group_info = get_group_info(((struct cred *)cred)->group_info);
|
|
|
|
|
|
ret = auth->au_ops->lookup_cred(auth, &acred, flags);
|
|
|
- put_group_info(acred.group_info);
|
|
|
+ if (!(flags & RPCAUTH_LOOKUP_RCU))
|
|
|
+ put_group_info(acred.group_info);
|
|
|
return ret;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(rpcauth_lookupcred);
|