summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Brown <neilb@cse.unsw.edu.au>2005-03-09 16:44:42 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-03-09 16:44:42 -0800
commit2cc9438be4ccfa96348bdbd3b6fb419b5387e659 (patch)
tree99b47d9c38a8948c23bfc0bc3e62131c89fdb535
parent8b0f11fa5d3e5c4114e25ea9b33cb413ed1e0823 (diff)
[PATCH] nfsd4: create a slab cache for stateowners
Create a slab cache for nfsv4 stateowners. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu> Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/nfsd/nfs4state.c55
-rw-r--r--fs/nfsd/nfssvc.c4
-rw-r--r--include/linux/nfsd/nfsd.h4
3 files changed, 51 insertions, 12 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 498f30290fa9..7a021c13f48a 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -985,14 +985,38 @@ release_all_files(void)
}
}
-/* should use a slab cache */
+kmem_cache_t *stateowner_slab = NULL;
+
+static int
+nfsd4_init_slabs(void)
+{
+ stateowner_slab = kmem_cache_create("nfsd4_stateowners",
+ sizeof(struct nfs4_stateowner), 0, 0, NULL, NULL);
+ if (stateowner_slab == NULL) {
+ dprintk("nfsd4: out of memory while initializing nfsv4\n");
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static void
+nfsd4_free_slabs(void)
+{
+ int status = 0;
+
+ if (stateowner_slab)
+ status = kmem_cache_destroy(stateowner_slab);
+ stateowner_slab = NULL;
+ BUG_ON(status);
+}
+
void
nfs4_free_stateowner(struct kref *kref)
{
struct nfs4_stateowner *sop =
container_of(kref, struct nfs4_stateowner, so_ref);
kfree(sop->so_owner.data);
- kfree(sop);
+ kmem_cache_free(stateowner_slab, sop);
free_sowner++;
}
@@ -1001,14 +1025,14 @@ alloc_stateowner(struct xdr_netobj *owner)
{
struct nfs4_stateowner *sop;
- if ((sop = kmalloc(sizeof(struct nfs4_stateowner),GFP_KERNEL))) {
+ if ((sop = kmem_cache_alloc(stateowner_slab, GFP_KERNEL))) {
if ((sop->so_owner.data = kmalloc(owner->len, GFP_KERNEL))) {
memcpy(sop->so_owner.data, owner->data, owner->len);
sop->so_owner.len = owner->len;
kref_init(&sop->so_ref);
return sop;
}
- kfree(sop);
+ kmem_cache_free(stateowner_slab, sop);
}
return NULL;
}
@@ -3129,14 +3153,12 @@ nfs4_check_open_reclaim(clientid_t *clid)
* Start and stop routines
*/
-void
-nfs4_state_init(void)
+static void
+__nfs4_state_init(void)
{
int i;
time_t grace_time;
- if (nfs4_init)
- return;
if (!nfs4_reclaim_init) {
for (i = 0; i < CLIENT_HASH_SIZE; i++)
INIT_LIST_HEAD(&reclaim_str_hashtbl[i]);
@@ -3180,7 +3202,21 @@ nfs4_state_init(void)
grace_end = boot_time + grace_time;
INIT_WORK(&laundromat_work,laundromat_main, NULL);
schedule_delayed_work(&laundromat_work, NFSD_LEASE_TIME*HZ);
+}
+
+int
+nfs4_state_init(void)
+{
+ int status;
+
+ if (nfs4_init)
+ return 0;
+ status = nfsd4_init_slabs();
+ if (status)
+ return status;
+ __nfs4_state_init();
nfs4_init = 1;
+ return 0;
}
int
@@ -3253,6 +3289,7 @@ nfs4_state_shutdown(void)
nfs4_lock_state();
nfs4_release_reclaim();
__nfs4_state_shutdown();
+ nfsd4_free_slabs();
nfs4_unlock_state();
}
@@ -3305,7 +3342,7 @@ nfs4_reset_lease(time_t leasetime)
}
init_state:
__nfs4_state_shutdown();
- nfs4_state_init();
+ __nfs4_state_init();
nfs4_unlock_state();
}
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index f7e41965b043..39551657e656 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -92,7 +92,9 @@ nfsd_svc(unsigned short port, int nrservs)
/* Readahead param cache - will no-op if it already exists */
error = nfsd_racache_init(2*nrservs);
- nfs4_state_init();
+ if (error<0)
+ goto out;
+ error = nfs4_state_init();
if (error<0)
goto out;
if (!nfsd_serv) {
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index bf8143c8c133..8e189dbba426 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -129,12 +129,12 @@ int nfsd_permission(struct svc_export *, struct dentry *, int);
* NFSv4 State
*/
#ifdef CONFIG_NFSD_V4
-void nfs4_state_init(void);
+int nfs4_state_init(void);
void nfs4_state_shutdown(void);
time_t nfs4_lease_time(void);
void nfs4_reset_lease(time_t leasetime);
#else
-void static inline nfs4_state_init(void){}
+int static inline nfs4_state_init(void){return 0;}
void static inline nfs4_state_shutdown(void){}
time_t static inline nfs4_lease_time(void){return 0;}
void static inline nfs4_reset_lease(time_t leasetime){}