From: NeilBrown Create a slab cache for nfsv4 stateowners. Signed-off-by: J. Bruce Fields Signed-off-by: Neil Brown Signed-off-by: Andrew Morton --- 25-akpm/fs/nfsd/nfs4state.c | 55 +++++++++++++++++++++++++++++++------- 25-akpm/fs/nfsd/nfssvc.c | 4 ++ 25-akpm/include/linux/nfsd/nfsd.h | 4 +- 3 files changed, 51 insertions(+), 12 deletions(-) diff -puN fs/nfsd/nfs4state.c~nfsd4-create-a-slab-cache-for-stateowners fs/nfsd/nfs4state.c --- 25/fs/nfsd/nfs4state.c~nfsd4-create-a-slab-cache-for-stateowners 2005-03-07 23:55:13.000000000 -0800 +++ 25-akpm/fs/nfsd/nfs4state.c 2005-03-08 00:02:30.000000000 -0800 @@ -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 *owne { 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 -puN fs/nfsd/nfssvc.c~nfsd4-create-a-slab-cache-for-stateowners fs/nfsd/nfssvc.c --- 25/fs/nfsd/nfssvc.c~nfsd4-create-a-slab-cache-for-stateowners 2005-03-07 23:55:13.000000000 -0800 +++ 25-akpm/fs/nfsd/nfssvc.c 2005-03-08 00:02:26.000000000 -0800 @@ -92,7 +92,9 @@ nfsd_svc(unsigned short port, int nrserv /* 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 -puN include/linux/nfsd/nfsd.h~nfsd4-create-a-slab-cache-for-stateowners include/linux/nfsd/nfsd.h --- 25/include/linux/nfsd/nfsd.h~nfsd4-create-a-slab-cache-for-stateowners 2005-03-07 23:55:13.000000000 -0800 +++ 25-akpm/include/linux/nfsd/nfsd.h 2005-03-08 00:02:42.000000000 -0800 @@ -129,12 +129,12 @@ int nfsd_permission(struct svc_export * * 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){} _