Skip to content

Commit b68572e

Browse files
NeilBrownamschuma-ntap
authored andcommitted
NFS: change access cache to use 'struct cred'.
Rather than keying the access cache with 'struct rpc_cred', use 'struct cred'. Then use cred_fscmp() to compare credentials rather than comparing the raw pointer. A benefit of this approach is that in the common case we avoid the rpc_lookup_cred_nonblock() call which can be slow when the cred cache is large. This also keeps many fewer items pinned in the rpc cred cache, so the cred cache is less likely to get large. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent 354698b commit b68572e

File tree

4 files changed

+41
-32
lines changed

4 files changed

+41
-32
lines changed

fs/nfs/dir.c

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2139,7 +2139,7 @@ MODULE_PARM_DESC(nfs_access_max_cachesize, "NFS access maximum total cache lengt
21392139

21402140
static void nfs_access_free_entry(struct nfs_access_entry *entry)
21412141
{
2142-
put_rpccred(entry->cred);
2142+
put_cred(entry->cred);
21432143
kfree_rcu(entry, rcu_head);
21442144
smp_mb__before_atomic();
21452145
atomic_long_dec(&nfs_access_nr_entries);
@@ -2265,25 +2265,26 @@ void nfs_access_zap_cache(struct inode *inode)
22652265
}
22662266
EXPORT_SYMBOL_GPL(nfs_access_zap_cache);
22672267

2268-
static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred)
2268+
static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, const struct cred *cred)
22692269
{
22702270
struct rb_node *n = NFS_I(inode)->access_cache.rb_node;
2271-
struct nfs_access_entry *entry;
22722271

22732272
while (n != NULL) {
2274-
entry = rb_entry(n, struct nfs_access_entry, rb_node);
2273+
struct nfs_access_entry *entry =
2274+
rb_entry(n, struct nfs_access_entry, rb_node);
2275+
int cmp = cred_fscmp(cred, entry->cred);
22752276

2276-
if (cred < entry->cred)
2277+
if (cmp < 0)
22772278
n = n->rb_left;
2278-
else if (cred > entry->cred)
2279+
else if (cmp > 0)
22792280
n = n->rb_right;
22802281
else
22812282
return entry;
22822283
}
22832284
return NULL;
22842285
}
22852286

2286-
static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res, bool may_block)
2287+
static int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res, bool may_block)
22872288
{
22882289
struct nfs_inode *nfsi = NFS_I(inode);
22892290
struct nfs_access_entry *cache;
@@ -2326,7 +2327,7 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str
23262327
return -ENOENT;
23272328
}
23282329

2329-
static int nfs_access_get_cached_rcu(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res)
2330+
static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res)
23302331
{
23312332
/* Only check the most recently returned cache entry,
23322333
* but do it without locking.
@@ -2363,15 +2364,17 @@ static void nfs_access_add_rbtree(struct inode *inode, struct nfs_access_entry *
23632364
struct rb_node **p = &root_node->rb_node;
23642365
struct rb_node *parent = NULL;
23652366
struct nfs_access_entry *entry;
2367+
int cmp;
23662368

23672369
spin_lock(&inode->i_lock);
23682370
while (*p != NULL) {
23692371
parent = *p;
23702372
entry = rb_entry(parent, struct nfs_access_entry, rb_node);
2373+
cmp = cred_fscmp(set->cred, entry->cred);
23712374

2372-
if (set->cred < entry->cred)
2375+
if (cmp < 0)
23732376
p = &parent->rb_left;
2374-
else if (set->cred > entry->cred)
2377+
else if (cmp > 0)
23752378
p = &parent->rb_right;
23762379
else
23772380
goto found;
@@ -2395,7 +2398,7 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
23952398
if (cache == NULL)
23962399
return;
23972400
RB_CLEAR_NODE(&cache->rb_node);
2398-
cache->cred = get_rpccred(set->cred);
2401+
cache->cred = get_cred(set->cred);
23992402
cache->mask = set->mask;
24002403

24012404
/* The above field assignments must be visible
@@ -2459,7 +2462,7 @@ void nfs_access_set_mask(struct nfs_access_entry *entry, u32 access_result)
24592462
}
24602463
EXPORT_SYMBOL_GPL(nfs_access_set_mask);
24612464

2462-
static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
2465+
static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask)
24632466
{
24642467
struct nfs_access_entry cache;
24652468
bool may_block = (mask & MAY_NOT_BLOCK) == 0;
@@ -2523,7 +2526,7 @@ static int nfs_open_permission_mask(int openflags)
25232526
return mask;
25242527
}
25252528

2526-
int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
2529+
int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags)
25272530
{
25282531
return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags));
25292532
}
@@ -2548,7 +2551,7 @@ static int nfs_execute_ok(struct inode *inode, int mask)
25482551

25492552
int nfs_permission(struct inode *inode, int mask)
25502553
{
2551-
struct rpc_cred *cred;
2554+
const struct cred *cred = current_cred();
25522555
int res = 0;
25532556

25542557
nfs_inc_stats(inode, NFSIOS_VFSACCESS);
@@ -2582,20 +2585,11 @@ int nfs_permission(struct inode *inode, int mask)
25822585

25832586
/* Always try fast lookups first */
25842587
rcu_read_lock();
2585-
cred = rpc_lookup_cred_nonblock();
2586-
if (!IS_ERR(cred))
2587-
res = nfs_do_access(inode, cred, mask|MAY_NOT_BLOCK);
2588-
else
2589-
res = PTR_ERR(cred);
2588+
res = nfs_do_access(inode, cred, mask|MAY_NOT_BLOCK);
25902589
rcu_read_unlock();
25912590
if (res == -ECHILD && !(mask & MAY_NOT_BLOCK)) {
25922591
/* Fast lookup failed, try the slow way */
2593-
cred = rpc_lookup_cred();
2594-
if (!IS_ERR(cred)) {
2595-
res = nfs_do_access(inode, cred, mask);
2596-
put_rpccred(cred);
2597-
} else
2598-
res = PTR_ERR(cred);
2592+
res = nfs_do_access(inode, cred, mask);
25992593
}
26002594
out:
26012595
if (!res && (mask & MAY_EXEC))

fs/nfs/nfs3proc.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,20 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
195195
.access = entry->mask,
196196
};
197197
struct nfs3_accessres res;
198+
struct auth_cred acred = {
199+
.cred = entry->cred,
200+
};
198201
struct rpc_message msg = {
199202
.rpc_proc = &nfs3_procedures[NFS3PROC_ACCESS],
200203
.rpc_argp = &arg,
201204
.rpc_resp = &res,
202-
.rpc_cred = entry->cred,
205+
.rpc_cred = rpc_lookup_generic_cred(&acred, 0, GFP_NOFS),
203206
};
204207
int status = -ENOMEM;
205208

206209
dprintk("NFS call access\n");
210+
if (!msg.rpc_cred)
211+
goto out;
207212
res.fattr = nfs_alloc_fattr();
208213
if (res.fattr == NULL)
209214
goto out;
@@ -214,6 +219,8 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
214219
nfs_access_set_mask(entry, res.access);
215220
nfs_free_fattr(res.fattr);
216221
out:
222+
if (msg.rpc_cred)
223+
put_rpccred(msg.rpc_cred);
217224
dprintk("NFS reply access: %d\n", status);
218225
return status;
219226
}

fs/nfs/nfs4proc.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,7 +1772,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
17721772
rcu_read_unlock();
17731773
nfs_release_seqid(opendata->o_arg.seqid);
17741774
if (!opendata->is_recover) {
1775-
ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode);
1775+
ret = nfs_may_open(state->inode, state->owner->so_cred->cr_cred, open_mode);
17761776
if (ret != 0)
17771777
goto out;
17781778
}
@@ -2511,7 +2511,7 @@ static int nfs4_opendata_access(struct rpc_cred *cred,
25112511
} else if ((fmode & FMODE_READ) && !opendata->file_created)
25122512
mask = NFS4_ACCESS_READ;
25132513

2514-
cache.cred = cred;
2514+
cache.cred = cred->cr_cred;
25152515
nfs_access_set_mask(&cache, opendata->o_res.access_result);
25162516
nfs_access_add_cache(state->inode, &cache);
25172517

@@ -4188,18 +4188,25 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
41884188
struct nfs4_accessres res = {
41894189
.server = server,
41904190
};
4191+
struct auth_cred acred = {
4192+
.cred = entry->cred,
4193+
};
41914194
struct rpc_message msg = {
41924195
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS],
41934196
.rpc_argp = &args,
41944197
.rpc_resp = &res,
4195-
.rpc_cred = entry->cred,
4198+
.rpc_cred = rpc_lookup_generic_cred(&acred, 0, GFP_NOFS),
41964199
};
41974200
int status = 0;
41984201

4202+
if (!msg.rpc_cred)
4203+
return -ENOMEM;
41994204
if (!nfs4_have_delegation(inode, FMODE_READ)) {
42004205
res.fattr = nfs_alloc_fattr();
4201-
if (res.fattr == NULL)
4206+
if (res.fattr == NULL) {
4207+
put_rpccred(msg.rpc_cred);
42024208
return -ENOMEM;
4209+
}
42034210
args.bitmask = server->cache_consistency_bitmask;
42044211
}
42054212

@@ -4210,6 +4217,7 @@ static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
42104217
nfs_refresh_inode(inode, res.fattr);
42114218
}
42124219
nfs_free_fattr(res.fattr);
4220+
put_rpccred(msg.rpc_cred);
42134221
return status;
42144222
}
42154223

include/linux/nfs_fs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
struct nfs_access_entry {
5252
struct rb_node rb_node;
5353
struct list_head lru;
54-
struct rpc_cred * cred;
54+
const struct cred * cred;
5555
__u32 mask;
5656
struct rcu_head rcu_head;
5757
};
@@ -491,7 +491,7 @@ extern const struct dentry_operations nfs_dentry_operations;
491491
extern void nfs_force_lookup_revalidate(struct inode *dir);
492492
extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh,
493493
struct nfs_fattr *fattr, struct nfs4_label *label);
494-
extern int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags);
494+
extern int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags);
495495
extern void nfs_access_zap_cache(struct inode *inode);
496496

497497
/*

0 commit comments

Comments
 (0)