Commit 3ba75830 authored by J. Bruce Fields's avatar J. Bruce Fields

nfsd4: drc containerization

The nfsd duplicate reply cache should not be shared between network
namespaces.

The most straightforward way to fix this is just to move every global in
the code to per-net-namespace memory, so that's what we do.

Still todo: sort out which members of nfsd_stats should be global and
which per-net-namespace.
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent b401170f
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define NFSCACHE_H #define NFSCACHE_H
#include <linux/sunrpc/svc.h> #include <linux/sunrpc/svc.h>
#include "netns.h"
/* /*
* Representation of a reply cache entry. * Representation of a reply cache entry.
...@@ -77,8 +78,8 @@ enum { ...@@ -77,8 +78,8 @@ enum {
/* Checksum this amount of the request */ /* Checksum this amount of the request */
#define RC_CSUMLEN (256U) #define RC_CSUMLEN (256U)
int nfsd_reply_cache_init(void); int nfsd_reply_cache_init(struct nfsd_net *);
void nfsd_reply_cache_shutdown(void); void nfsd_reply_cache_shutdown(struct nfsd_net *);
int nfsd_cache_lookup(struct svc_rqst *); int nfsd_cache_lookup(struct svc_rqst *);
void nfsd_cache_update(struct svc_rqst *, int, __be32 *); void nfsd_cache_update(struct svc_rqst *, int, __be32 *);
int nfsd_reply_cache_stats_open(struct inode *, struct file *); int nfsd_reply_cache_stats_open(struct inode *, struct file *);
......
...@@ -127,6 +127,41 @@ struct nfsd_net { ...@@ -127,6 +127,41 @@ struct nfsd_net {
*/ */
bool *nfsd_versions; bool *nfsd_versions;
bool *nfsd4_minorversions; bool *nfsd4_minorversions;
/*
* Duplicate reply cache
*/
struct nfsd_drc_bucket *drc_hashtbl;
struct kmem_cache *drc_slab;
/* max number of entries allowed in the cache */
unsigned int max_drc_entries;
/* number of significant bits in the hash value */
unsigned int maskbits;
unsigned int drc_hashsize;
/*
* Stats and other tracking of on the duplicate reply cache. All of these and
* the "rc" fields in nfsdstats are protected by the cache_lock
*/
/* total number of entries */
atomic_t num_drc_entries;
/* cache misses due only to checksum comparison failures */
unsigned int payload_misses;
/* amount of memory (in bytes) currently consumed by the DRC */
unsigned int drc_mem_usage;
/* longest hash chain seen */
unsigned int longest_chain;
/* size of cache when we saw the longest hash chain */
unsigned int longest_chain_cachesize;
struct shrinker nfsd_reply_cache_shrinker;
}; };
/* Simple check to find out if a given net was properly initialized */ /* Simple check to find out if a given net was properly initialized */
......
This diff is collapsed.
...@@ -1242,6 +1242,9 @@ static __net_init int nfsd_init_net(struct net *net) ...@@ -1242,6 +1242,9 @@ static __net_init int nfsd_init_net(struct net *net)
goto out_idmap_error; goto out_idmap_error;
nn->nfsd_versions = NULL; nn->nfsd_versions = NULL;
nn->nfsd4_minorversions = NULL; nn->nfsd4_minorversions = NULL;
retval = nfsd_reply_cache_init(nn);
if (retval)
goto out_drc_error;
nn->nfsd4_lease = 90; /* default lease time */ nn->nfsd4_lease = 90; /* default lease time */
nn->nfsd4_grace = 90; nn->nfsd4_grace = 90;
nn->somebody_reclaimed = false; nn->somebody_reclaimed = false;
...@@ -1254,6 +1257,8 @@ static __net_init int nfsd_init_net(struct net *net) ...@@ -1254,6 +1257,8 @@ static __net_init int nfsd_init_net(struct net *net)
init_waitqueue_head(&nn->ntf_wq); init_waitqueue_head(&nn->ntf_wq);
return 0; return 0;
out_drc_error:
nfsd_idmap_shutdown(net);
out_idmap_error: out_idmap_error:
nfsd_export_shutdown(net); nfsd_export_shutdown(net);
out_export_error: out_export_error:
...@@ -1262,6 +1267,9 @@ static __net_init int nfsd_init_net(struct net *net) ...@@ -1262,6 +1267,9 @@ static __net_init int nfsd_init_net(struct net *net)
static __net_exit void nfsd_exit_net(struct net *net) static __net_exit void nfsd_exit_net(struct net *net)
{ {
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
nfsd_reply_cache_shutdown(nn);
nfsd_idmap_shutdown(net); nfsd_idmap_shutdown(net);
nfsd_export_shutdown(net); nfsd_export_shutdown(net);
nfsd_netns_free_versions(net_generic(net, nfsd_net_id)); nfsd_netns_free_versions(net_generic(net, nfsd_net_id));
...@@ -1295,9 +1303,6 @@ static int __init init_nfsd(void) ...@@ -1295,9 +1303,6 @@ static int __init init_nfsd(void)
if (retval) if (retval)
goto out_exit_pnfs; goto out_exit_pnfs;
nfsd_stat_init(); /* Statistics */ nfsd_stat_init(); /* Statistics */
retval = nfsd_reply_cache_init();
if (retval)
goto out_free_stat;
nfsd_lockd_init(); /* lockd->nfsd callbacks */ nfsd_lockd_init(); /* lockd->nfsd callbacks */
retval = create_proc_exports_entry(); retval = create_proc_exports_entry();
if (retval) if (retval)
...@@ -1311,8 +1316,6 @@ static int __init init_nfsd(void) ...@@ -1311,8 +1316,6 @@ static int __init init_nfsd(void)
remove_proc_entry("fs/nfs", NULL); remove_proc_entry("fs/nfs", NULL);
out_free_lockd: out_free_lockd:
nfsd_lockd_shutdown(); nfsd_lockd_shutdown();
nfsd_reply_cache_shutdown();
out_free_stat:
nfsd_stat_shutdown(); nfsd_stat_shutdown();
nfsd_fault_inject_cleanup(); nfsd_fault_inject_cleanup();
out_exit_pnfs: out_exit_pnfs:
...@@ -1328,7 +1331,6 @@ static int __init init_nfsd(void) ...@@ -1328,7 +1331,6 @@ static int __init init_nfsd(void)
static void __exit exit_nfsd(void) static void __exit exit_nfsd(void)
{ {
nfsd_reply_cache_shutdown();
remove_proc_entry("fs/nfs/exports", NULL); remove_proc_entry("fs/nfs/exports", NULL);
remove_proc_entry("fs/nfs", NULL); remove_proc_entry("fs/nfs", NULL);
nfsd_stat_shutdown(); nfsd_stat_shutdown();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment