[PATCH 17/23] NFS: change access cache to use 'struct cred'.

2018-12-02 Thread NeilBrown
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 
---
 fs/nfs/dir.c   |   44 +++-
 fs/nfs/nfs3proc.c  |9 -
 fs/nfs/nfs4proc.c  |   16 
 include/linux/nfs_fs.h |4 ++--
 4 files changed, 41 insertions(+), 32 deletions(-)

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 71b2e390becf..4dc61b6f74e8 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2139,7 +2139,7 @@ MODULE_PARM_DESC(nfs_access_max_cachesize, "NFS access 
maximum total cache lengt
 
 static void nfs_access_free_entry(struct nfs_access_entry *entry)
 {
-   put_rpccred(entry->cred);
+   put_cred(entry->cred);
kfree_rcu(entry, rcu_head);
smp_mb__before_atomic();
atomic_long_dec(&nfs_access_nr_entries);
@@ -2265,17 +2265,18 @@ void nfs_access_zap_cache(struct inode *inode)
 }
 EXPORT_SYMBOL_GPL(nfs_access_zap_cache);
 
-static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, 
struct rpc_cred *cred)
+static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, 
const struct cred *cred)
 {
struct rb_node *n = NFS_I(inode)->access_cache.rb_node;
-   struct nfs_access_entry *entry;
 
while (n != NULL) {
-   entry = rb_entry(n, struct nfs_access_entry, rb_node);
+   struct nfs_access_entry *entry =
+   rb_entry(n, struct nfs_access_entry, rb_node);
+   int cmp = cred_fscmp(cred, entry->cred);
 
-   if (cred < entry->cred)
+   if (cmp < 0)
n = n->rb_left;
-   else if (cred > entry->cred)
+   else if (cmp > 0)
n = n->rb_right;
else
return entry;
@@ -2283,7 +2284,7 @@ static struct nfs_access_entry 
*nfs_access_search_rbtree(struct inode *inode, st
return NULL;
 }
 
-static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, 
struct nfs_access_entry *res, bool may_block)
+static int nfs_access_get_cached(struct inode *inode, const struct cred *cred, 
struct nfs_access_entry *res, bool may_block)
 {
struct nfs_inode *nfsi = NFS_I(inode);
struct nfs_access_entry *cache;
@@ -2326,7 +2327,7 @@ static int nfs_access_get_cached(struct inode *inode, 
struct rpc_cred *cred, str
return -ENOENT;
 }
 
-static int nfs_access_get_cached_rcu(struct inode *inode, struct rpc_cred 
*cred, struct nfs_access_entry *res)
+static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred 
*cred, struct nfs_access_entry *res)
 {
/* Only check the most recently returned cache entry,
 * but do it without locking.
@@ -2363,15 +2364,17 @@ static void nfs_access_add_rbtree(struct inode *inode, 
struct nfs_access_entry *
struct rb_node **p = &root_node->rb_node;
struct rb_node *parent = NULL;
struct nfs_access_entry *entry;
+   int cmp;
 
spin_lock(&inode->i_lock);
while (*p != NULL) {
parent = *p;
entry = rb_entry(parent, struct nfs_access_entry, rb_node);
+   cmp = cred_fscmp(set->cred, entry->cred);
 
-   if (set->cred < entry->cred)
+   if (cmp < 0)
p = &parent->rb_left;
-   else if (set->cred > entry->cred)
+   else if (cmp > 0)
p = &parent->rb_right;
else
goto found;
@@ -2395,7 +2398,7 @@ void nfs_access_add_cache(struct inode *inode, struct 
nfs_access_entry *set)
if (cache == NULL)
return;
RB_CLEAR_NODE(&cache->rb_node);
-   cache->cred = get_rpccred(set->cred);
+   cache->cred = get_cred(set->cred);
cache->mask = set->mask;
 
/* The above field assignments must be visible
@@ -2459,7 +2462,7 @@ void nfs_access_set_mask(struct nfs_access_entry *entry, 
u32 access_result)
 }
 EXPORT_SYMBOL_GPL(nfs_access_set_mask);
 
-static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
+static int nfs_do_access(struct inode *inode, const struct cred *cred, int 
mask)
 {
struct nfs_access_entry cache;
bool may_block = (mask & MAY_NOT_BLOCK) == 0;
@@ -2523,7 +2526,7 @@ static int nfs_open_permission_mask(int openflags)
return mask;
 }
 
-int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
+int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags)
 {
return nfs_do_access(inode, cred, nfs_open_per

[PATCH 17/23] NFS: change access cache to use 'struct cred'.

2018-11-06 Thread NeilBrown
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 
---
 fs/nfs/dir.c   |   44 +++-
 fs/nfs/nfs3proc.c  |9 -
 fs/nfs/nfs4proc.c  |   16 
 include/linux/nfs_fs.h |4 ++--
 4 files changed, 41 insertions(+), 32 deletions(-)

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 71b2e390becf..4dc61b6f74e8 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2139,7 +2139,7 @@ MODULE_PARM_DESC(nfs_access_max_cachesize, "NFS access 
maximum total cache lengt
 
 static void nfs_access_free_entry(struct nfs_access_entry *entry)
 {
-   put_rpccred(entry->cred);
+   put_cred(entry->cred);
kfree_rcu(entry, rcu_head);
smp_mb__before_atomic();
atomic_long_dec(&nfs_access_nr_entries);
@@ -2265,17 +2265,18 @@ void nfs_access_zap_cache(struct inode *inode)
 }
 EXPORT_SYMBOL_GPL(nfs_access_zap_cache);
 
-static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, 
struct rpc_cred *cred)
+static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, 
const struct cred *cred)
 {
struct rb_node *n = NFS_I(inode)->access_cache.rb_node;
-   struct nfs_access_entry *entry;
 
while (n != NULL) {
-   entry = rb_entry(n, struct nfs_access_entry, rb_node);
+   struct nfs_access_entry *entry =
+   rb_entry(n, struct nfs_access_entry, rb_node);
+   int cmp = cred_fscmp(cred, entry->cred);
 
-   if (cred < entry->cred)
+   if (cmp < 0)
n = n->rb_left;
-   else if (cred > entry->cred)
+   else if (cmp > 0)
n = n->rb_right;
else
return entry;
@@ -2283,7 +2284,7 @@ static struct nfs_access_entry 
*nfs_access_search_rbtree(struct inode *inode, st
return NULL;
 }
 
-static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, 
struct nfs_access_entry *res, bool may_block)
+static int nfs_access_get_cached(struct inode *inode, const struct cred *cred, 
struct nfs_access_entry *res, bool may_block)
 {
struct nfs_inode *nfsi = NFS_I(inode);
struct nfs_access_entry *cache;
@@ -2326,7 +2327,7 @@ static int nfs_access_get_cached(struct inode *inode, 
struct rpc_cred *cred, str
return -ENOENT;
 }
 
-static int nfs_access_get_cached_rcu(struct inode *inode, struct rpc_cred 
*cred, struct nfs_access_entry *res)
+static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred 
*cred, struct nfs_access_entry *res)
 {
/* Only check the most recently returned cache entry,
 * but do it without locking.
@@ -2363,15 +2364,17 @@ static void nfs_access_add_rbtree(struct inode *inode, 
struct nfs_access_entry *
struct rb_node **p = &root_node->rb_node;
struct rb_node *parent = NULL;
struct nfs_access_entry *entry;
+   int cmp;
 
spin_lock(&inode->i_lock);
while (*p != NULL) {
parent = *p;
entry = rb_entry(parent, struct nfs_access_entry, rb_node);
+   cmp = cred_fscmp(set->cred, entry->cred);
 
-   if (set->cred < entry->cred)
+   if (cmp < 0)
p = &parent->rb_left;
-   else if (set->cred > entry->cred)
+   else if (cmp > 0)
p = &parent->rb_right;
else
goto found;
@@ -2395,7 +2398,7 @@ void nfs_access_add_cache(struct inode *inode, struct 
nfs_access_entry *set)
if (cache == NULL)
return;
RB_CLEAR_NODE(&cache->rb_node);
-   cache->cred = get_rpccred(set->cred);
+   cache->cred = get_cred(set->cred);
cache->mask = set->mask;
 
/* The above field assignments must be visible
@@ -2459,7 +2462,7 @@ void nfs_access_set_mask(struct nfs_access_entry *entry, 
u32 access_result)
 }
 EXPORT_SYMBOL_GPL(nfs_access_set_mask);
 
-static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
+static int nfs_do_access(struct inode *inode, const struct cred *cred, int 
mask)
 {
struct nfs_access_entry cache;
bool may_block = (mask & MAY_NOT_BLOCK) == 0;
@@ -2523,7 +2526,7 @@ static int nfs_open_permission_mask(int openflags)
return mask;
 }
 
-int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
+int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags)
 {
return nfs_do_access(inode, cred, nfs_open_per