diff options
| author | Neil Brown <neilb@cse.unsw.edu.au> | 2005-03-09 16:44:42 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-03-09 16:44:42 -0800 |
| commit | 2cc9438be4ccfa96348bdbd3b6fb419b5387e659 (patch) | |
| tree | 99b47d9c38a8948c23bfc0bc3e62131c89fdb535 | |
| parent | 8b0f11fa5d3e5c4114e25ea9b33cb413ed1e0823 (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.c | 55 | ||||
| -rw-r--r-- | fs/nfsd/nfssvc.c | 4 | ||||
| -rw-r--r-- | include/linux/nfsd/nfsd.h | 4 |
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){} |
