Skip to content

Commit 2edd8d7

Browse files
NeilBrownamschuma-ntap
authored andcommitted
SUNRPC: simplify auth_unix.
1/ discard 'struct unx_cred'. We don't need any data that is not already in 'struct rpc_cred'. 2/ Don't keep these creds in a hash table. When a credential is needed, simply allocate it. When not needed, discard it. This can easily be faster than performing a lookup on a shared hash table. As the lookup can happen during write-out, use a mempool to ensure forward progress. This means that we cannot compare two credentials for equality by comparing the pointers, but we never do that anyway. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent d6efccd commit 2edd8d7

File tree

2 files changed

+32
-70
lines changed

2 files changed

+32
-70
lines changed

net/sunrpc/auth.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
651651
INIT_LIST_HEAD(&cred->cr_lru);
652652
refcount_set(&cred->cr_count, 1);
653653
cred->cr_auth = auth;
654+
cred->cr_flags = 0;
654655
cred->cr_ops = ops;
655656
cred->cr_expire = jiffies;
656657
cred->cr_cred = get_cred(acred->cred);

net/sunrpc/auth_unix.c

Lines changed: 31 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,19 @@
1111
#include <linux/types.h>
1212
#include <linux/sched.h>
1313
#include <linux/module.h>
14+
#include <linux/mempool.h>
1415
#include <linux/sunrpc/clnt.h>
1516
#include <linux/sunrpc/auth.h>
1617
#include <linux/user_namespace.h>
1718

18-
struct unx_cred {
19-
struct rpc_cred uc_base;
20-
kgid_t uc_gid;
21-
kgid_t uc_gids[UNX_NGROUPS];
22-
};
23-
#define uc_uid uc_base.cr_uid
2419

2520
#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
2621
# define RPCDBG_FACILITY RPCDBG_AUTH
2722
#endif
2823

2924
static struct rpc_auth unix_auth;
3025
static const struct rpc_credops unix_credops;
26+
static mempool_t *unix_pool;
3127

3228
static struct rpc_auth *
3329
unx_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
@@ -42,15 +38,6 @@ static void
4238
unx_destroy(struct rpc_auth *auth)
4339
{
4440
dprintk("RPC: destroying UNIX authenticator %p\n", auth);
45-
rpcauth_clear_credcache(auth->au_credcache);
46-
}
47-
48-
static int
49-
unx_hash_cred(struct auth_cred *acred, unsigned int hashbits)
50-
{
51-
return hash_64(from_kgid(&init_user_ns, acred->cred->fsgid) |
52-
((u64)from_kuid(&init_user_ns, acred->cred->fsuid) <<
53-
(sizeof(gid_t) * 8)), hashbits);
5441
}
5542

5643
/*
@@ -59,53 +46,24 @@ unx_hash_cred(struct auth_cred *acred, unsigned int hashbits)
5946
static struct rpc_cred *
6047
unx_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
6148
{
62-
return rpcauth_lookup_credcache(auth, acred, flags, GFP_NOFS);
63-
}
64-
65-
static struct rpc_cred *
66-
unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags, gfp_t gfp)
67-
{
68-
struct unx_cred *cred;
69-
unsigned int groups = 0;
70-
unsigned int i;
49+
struct rpc_cred *ret = mempool_alloc(unix_pool, GFP_NOFS);
7150

7251
dprintk("RPC: allocating UNIX cred for uid %d gid %d\n",
7352
from_kuid(&init_user_ns, acred->cred->fsuid),
7453
from_kgid(&init_user_ns, acred->cred->fsgid));
7554

76-
if (!(cred = kmalloc(sizeof(*cred), gfp)))
77-
return ERR_PTR(-ENOMEM);
78-
79-
rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops);
80-
cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
81-
82-
if (acred->cred && acred->cred->group_info != NULL)
83-
groups = acred->cred->group_info->ngroups;
84-
if (groups > UNX_NGROUPS)
85-
groups = UNX_NGROUPS;
86-
87-
cred->uc_gid = acred->cred->fsgid;
88-
for (i = 0; i < groups; i++)
89-
cred->uc_gids[i] = acred->cred->group_info->gid[i];
90-
if (i < UNX_NGROUPS)
91-
cred->uc_gids[i] = INVALID_GID;
92-
93-
return &cred->uc_base;
94-
}
95-
96-
static void
97-
unx_free_cred(struct unx_cred *unx_cred)
98-
{
99-
dprintk("RPC: unx_free_cred %p\n", unx_cred);
100-
put_cred(unx_cred->uc_base.cr_cred);
101-
kfree(unx_cred);
55+
rpcauth_init_cred(ret, acred, auth, &unix_credops);
56+
ret->cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
57+
return ret;
10258
}
10359

10460
static void
10561
unx_free_cred_callback(struct rcu_head *head)
10662
{
107-
struct unx_cred *unx_cred = container_of(head, struct unx_cred, uc_base.cr_rcu);
108-
unx_free_cred(unx_cred);
63+
struct rpc_cred *rpc_cred = container_of(head, struct rpc_cred, cr_rcu);
64+
dprintk("RPC: unx_free_cred %p\n", rpc_cred);
65+
put_cred(rpc_cred->cr_cred);
66+
mempool_free(rpc_cred, unix_pool);
10967
}
11068

11169
static void
@@ -115,30 +73,32 @@ unx_destroy_cred(struct rpc_cred *cred)
11573
}
11674

11775
/*
118-
* Match credentials against current process creds.
119-
* The root_override argument takes care of cases where the caller may
120-
* request root creds (e.g. for NFS swapping).
76+
* Match credentials against current the auth_cred.
12177
*/
12278
static int
123-
unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
79+
unx_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
12480
{
125-
struct unx_cred *cred = container_of(rcred, struct unx_cred, uc_base);
12681
unsigned int groups = 0;
12782
unsigned int i;
12883

84+
if (cred->cr_cred == acred->cred)
85+
return 1;
12986

130-
if (!uid_eq(cred->uc_uid, acred->cred->fsuid) || !gid_eq(cred->uc_gid, acred->cred->fsgid))
87+
if (!uid_eq(cred->cr_cred->fsuid, acred->cred->fsuid) || !gid_eq(cred->cr_cred->fsgid, acred->cred->fsgid))
13188
return 0;
13289

13390
if (acred->cred && acred->cred->group_info != NULL)
13491
groups = acred->cred->group_info->ngroups;
13592
if (groups > UNX_NGROUPS)
13693
groups = UNX_NGROUPS;
94+
if (cred->cr_cred->group_info == NULL)
95+
return groups == 0;
96+
if (groups != cred->cr_cred->group_info->ngroups)
97+
return 0;
98+
13799
for (i = 0; i < groups ; i++)
138-
if (!gid_eq(cred->uc_gids[i], acred->cred->group_info->gid[i]))
100+
if (!gid_eq(cred->cr_cred->group_info->gid[i], acred->cred->group_info->gid[i]))
139101
return 0;
140-
if (groups < UNX_NGROUPS && gid_valid(cred->uc_gids[groups]))
141-
return 0;
142102
return 1;
143103
}
144104

@@ -150,9 +110,10 @@ static __be32 *
150110
unx_marshal(struct rpc_task *task, __be32 *p)
151111
{
152112
struct rpc_clnt *clnt = task->tk_client;
153-
struct unx_cred *cred = container_of(task->tk_rqstp->rq_cred, struct unx_cred, uc_base);
113+
struct rpc_cred *cred = task->tk_rqstp->rq_cred;
154114
__be32 *base, *hold;
155115
int i;
116+
struct group_info *gi = cred->cr_cred->group_info;
156117

157118
*p++ = htonl(RPC_AUTH_UNIX);
158119
base = p++;
@@ -163,11 +124,12 @@ unx_marshal(struct rpc_task *task, __be32 *p)
163124
*/
164125
p = xdr_encode_array(p, clnt->cl_nodename, clnt->cl_nodelen);
165126

166-
*p++ = htonl((u32) from_kuid(&init_user_ns, cred->uc_uid));
167-
*p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gid));
127+
*p++ = htonl((u32) from_kuid(&init_user_ns, cred->cr_cred->fsuid));
128+
*p++ = htonl((u32) from_kgid(&init_user_ns, cred->cr_cred->fsgid));
168129
hold = p++;
169-
for (i = 0; i < UNX_NGROUPS && gid_valid(cred->uc_gids[i]); i++)
170-
*p++ = htonl((u32) from_kgid(&init_user_ns, cred->uc_gids[i]));
130+
if (gi)
131+
for (i = 0; i < UNX_NGROUPS && i < gi->ngroups; i++)
132+
*p++ = htonl((u32) from_kgid(&init_user_ns, gi->gid[i]));
171133
*hold = htonl(p - hold - 1); /* gid array length */
172134
*base = htonl((p - base - 1) << 2); /* cred length */
173135

@@ -214,12 +176,13 @@ unx_validate(struct rpc_task *task, __be32 *p)
214176

215177
int __init rpc_init_authunix(void)
216178
{
217-
return rpcauth_init_credcache(&unix_auth);
179+
unix_pool = mempool_create_kmalloc_pool(16, sizeof(struct rpc_cred));
180+
return unix_pool ? 0 : -ENOMEM;
218181
}
219182

220183
void rpc_destroy_authunix(void)
221184
{
222-
rpcauth_destroy_credcache(&unix_auth);
185+
mempool_destroy(unix_pool);
223186
}
224187

225188
const struct rpc_authops authunix_ops = {
@@ -228,9 +191,7 @@ const struct rpc_authops authunix_ops = {
228191
.au_name = "UNIX",
229192
.create = unx_create,
230193
.destroy = unx_destroy,
231-
.hash_cred = unx_hash_cred,
232194
.lookup_cred = unx_lookup_cred,
233-
.crcreate = unx_create_cred,
234195
};
235196

236197
static

0 commit comments

Comments
 (0)