Introduction
Subsystems (2)
PATCH 1/1 Introduction
16 patches for knfsd.
The first three are bug fixes that would be good to get into 2.6.12 The rest are continuing work on tidying and extending the V4 server.
Thanks,
NeilBrown
[PATCH kNFSd 001 of 16] nfsd: clear signals before exiting the nfsd() thread [PATCH kNFSd 002 of 16] nfsd4: callback create rpc client returns [PATCH kNFSd 003 of 16] nfsd4: fix struct file leak
[PATCH kNFSd 004 of 16] nfsd4: find_delegation_file()
[PATCH kNFSd 005 of 16] nfsd4: nfs4_check_delegmode
[PATCH kNFSd 006 of 16] nfsd4: don't reopen for delegated client [PATCH kNFSd 007 of 16] nfsd4: add open state code for CLAIM_DELEGATE_CUR [PATCH kNFSd 008 of 16] nfsd4: support CLAIM_DELEGATE_CUR [PATCH kNFSd 009 of 16] nfsd4: fix fh_expire_type
[PATCH kNFSd 010 of 16] nfsd4: block metadata ops during grace period [PATCH kNFSd 011 of 16] nfsd4: slabify nfs4_files
[PATCH kNFSd 012 of 16] nfsd4: slabify stateids
[PATCH kNFSd 013 of 16] nfsd4: slabify delegations
[PATCH kNFSd 014 of 16] nfsd4: remove debugging counters [PATCH kNFSd 015 of 16] nfsd4: rename nfs4_file fields
[PATCH kNFSd 016 of 16] nfsd4: reference count struct nfs4_file
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd: clear signals before exiting the nfsd() thread
Fixes the error "RPC: failed to contact portmap (errno -512)." when the server later tries to unregister from the portmapper.
### Diffstat output
./fs/nfsd/nfssvc.c | 2 ++ 1 files changed, 2 insertions(+)
fs/nfsd/nfssvc.c renamed from fs/nfsd/nfssvc.c~current~ +2 -0
@@ -259,6 +259,8 @@ nfsd(struct svc_rqst *rqstp)break ; err = signo; } +/* Clear signals before calling lockd_down() and svc_exit_thread() */ +flush_signals (current);lock_kernel ();
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: callback create rpc client returns
In reply to NeilBrownrpc_create_clnt and friends return errors, not NULL, on failure.
### Diffstat output
./fs/nfsd/nfs4callback.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-)
fs/nfsd/nfs4callback.c renamed from fs/nfsd/nfs4callback.c~current~ +4 -2
@@ -405,7 +405,8 @@ nfsd4_probe_callback(struct nfs4_client timeparms.to_exponential =1 ;/* Create RPC transport */ -if (!(xprt =xprt_create_proto (IPPROTO_TCP , &addr, &timeparms))) { + xprt =xprt_create_proto (IPPROTO_TCP , &addr, &timeparms); +if (IS_ERR (xprt)) {dprintk ("NFSD: couldn't create callback transport!\n" ); goto out_err; }
@@ -426,7 +427,8 @@ nfsd4_probe_callback(struct nfs4_client* XXX AUTH_UNIX only - need AUTH_GSS.... */ sprintf (hostname,"%u.%u.%u.%u" ,NIPQUAD (addr.sin_addr.s_addr)); -if (!(clnt =rpc_create_client (xprt, hostname, program,1 ,RPC_AUTH_UNIX ))) { + clnt =rpc_create_client (xprt, hostname, program,1 ,RPC_AUTH_UNIX ); +if (IS_ERR (clnt)) {dprintk ("NFSD: couldn't create callback client\n" ); goto out_err; }
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: find_delegation_file()
In reply to NeilBrownFactor out a bit of common code that will be useful elsewhere.
### Diffstat output
./fs/nfsd/nfs4state.c | 25 ++++++++++++++----------- 1 files changed, 14 insertions(+), 11 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +14 -11
@@ -1526,6 +1526,18 @@ out:return status; } +static struct nfs4_delegation * +find_delegation_file (struct nfs4_file *fp,stateid_t *stid) +{ +struct nfs4_delegation *dp; + +list_for_each_entry (dp, &fp->fi_del_perfile, dl_del_perfile) { +if (dp->dl_stateid.si_stateownerid == stid->si_stateownerid) +return dp; + } +return NULL ; +} +static int nfs4_check_open (struct nfs4_file *fp,struct nfsd4_open *open,struct nfs4_stateid **stpp) {
@@ -2419,24 +2431,15 @@ find_stateid(stateid_t *stid, int flags)static struct nfs4_delegation *find_delegation_stateid (struct inode *ino,stateid_t *stid) { -struct nfs4_delegation *dp =NULL ;struct nfs4_file *fp =NULL ; -u32 st_id;dprintk ("NFSD:find_delegation_stateid stateid=(%08x/%08x/%08x/%08x)\n" , stid->si_boot, stid->si_stateownerid, stid->si_fileid, stid->si_generation); - st_id = stid->si_stateownerid; fp =find_file (ino); -if (fp) { -list_for_each_entry (dp, &fp->fi_del_perfile, dl_del_perfile) { -if (dp->dl_stateid.si_stateownerid == st_id) { -dprintk ("NFSD: find_delegation dp %p\n" ,dp); -return dp; - } - } - } +if (fp) +return find_delegation_file (fp, stid);return NULL ; }
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: nfs4_check_delegmode
In reply to NeilBrownAdditional minor code reshuffling to prepare for claim_deleg_cur support.
### Diffstat output
./fs/nfsd/nfs4state.c | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +9 -9
@@ -1526,6 +1526,15 @@ out:return status; } +static inline int +nfs4_check_delegmode (struct nfs4_delegation *dp,int flags) +{ +if ((flags &WR_STATE ) && (dp->dl_type ==NFS4_OPEN_DELEGATE_READ )) +return nfserr_openmode; +else +return nfs_ok; +} +static struct nfs4_delegation *find_delegation_file (struct nfs4_file *fp,stateid_t *stid) {
@@ -1961,15 +1970,6 @@ out: }static inline int -nfs4_check_delegmode (struct nfs4_delegation *dp,int flags) -{ -if ((flags &WR_STATE ) && (dp->dl_type ==NFS4_OPEN_DELEGATE_READ )) -return nfserr_openmode; -else -return nfs_ok; -} - -static inline int check_special_stateids (svc_fh *current_fh,stateid_t *stateid,int flags) {/* Trying to call delegreturn with a special stateid? Yuch: */
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: don't reopen for delegated client
In reply to NeilBrownWe don't really need to be doing a separate open for every stateid. And in the case of an open from a client that already has a delegation on a file, it unnecessarily results in a delegation recall.
### Diffstat output
./fs/nfsd/nfs4state.c | 44 ++++++++++++++++++++++++++++++++++++-------- 1 files changed, 36 insertions(+), 8 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +36 -8
@@ -1547,6 +1547,24 @@ find_delegation_file(struct nfs4_file *freturn NULL ; } +static void +nfs4_check_deleg (struct nfs4_file *fp,struct nfsd4_open *open, +struct nfs4_delegation **dp) +{ +int flags; +int status; + + *dp =find_delegation_file (fp, &open->op_delegate_stateid); +if (*dp ==NULL ) +return ; + flags = open->op_share_access ==NFS4_SHARE_ACCESS_READ ? +RD_STATE :WR_STATE ; + status =nfs4_check_delegmode (*dp, flags); +if (status) + *dp =NULL ; +return ; +} +static int nfs4_check_open (struct nfs4_file *fp,struct nfsd4_open *open,struct nfs4_stateid **stpp) {
@@ -1572,21 +1590,28 @@ out:static int nfs4_new_open (struct svc_rqst *rqstp,struct nfs4_stateid **stpp, +struct nfs4_delegation *dp,struct svc_fh *cur_fh,int flags) {struct nfs4_stateid *stp; -int status; stp =kmalloc (sizeof (struct nfs4_stateid ),GFP_KERNEL );if (stp ==NULL )return nfserr_resource; - status =nfsd_open (rqstp, cur_fh,S_IFREG , flags, &stp->st_vfs_file); -if (status) { -if (status == nfserr_dropit) - status = nfserr_jukebox; -kfree (stp); -return status; +if (dp) { +get_file (dp->dl_vfs_file); + stp->st_vfs_file = dp->dl_vfs_file; + }else { +int status; + status =nfsd_open (rqstp, cur_fh,S_IFREG , flags, + &stp->st_vfs_file); +if (status) { +if (status == nfserr_dropit) + status = nfserr_jukebox; +kfree (stp); +return status; + } } vfsopen++; *stpp = stp;
@@ -1720,6 +1745,7 @@ nfsd4_process_open2(struct svc_rqst *rqsstruct nfs4_file *fp =NULL ;struct inode *ino = current_fh->fh_dentry->d_inode;struct nfs4_stateid *stp =NULL ; +struct nfs4_delegation *dp =NULL ;int status; status = nfserr_inval;
@@ -1734,6 +1760,7 @@ nfsd4_process_open2(struct svc_rqst *rqsif (fp) {if ((status =nfs4_check_open (fp, open, &stp))) goto out; +nfs4_check_deleg (fp, open, &dp); }else { status = nfserr_resource; fp =alloc_init_file (ino);
@@ -1757,7 +1784,8 @@ nfsd4_process_open2(struct svc_rqst *rqs flags =MAY_WRITE ; else flags =MAY_READ ; -if ((status =nfs4_new_open (rqstp, &stp, current_fh, flags))) + status =nfs4_new_open (rqstp, &stp, dp, current_fh, flags); +if (status) goto out;init_stateid (stp, fp, open); status =nfsd4_truncate (rqstp, current_fh, open);
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: add open state code for CLAIM_DELEGATE_CUR
In reply to NeilBrownState logic for OPEN with claim type CLAIM_DELEGATE_CUR, which the NFSv4 client uses to report local OPENs on a delegated file back to the NFSv4 server.
nfs4_check_deleg() performs input delegation stateid lookup and sanity check.
### Diffstat output
./fs/nfsd/nfs4state.c | 21 ++++++++++++++++----- 1 files changed, 16 insertions(+), 5 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +16 -5
@@ -1547,22 +1547,28 @@ find_delegation_file(struct nfs4_file *freturn NULL ; } -static void +static int nfs4_check_deleg (struct nfs4_file *fp,struct nfsd4_open *open,struct nfs4_delegation **dp) {int flags; -int status; +int status = nfserr_bad_stateid; *dp =find_delegation_file (fp, &open->op_delegate_stateid);if (*dp ==NULL ) -return ; + goto out; flags = open->op_share_access ==NFS4_SHARE_ACCESS_READ ?RD_STATE :WR_STATE ; status =nfs4_check_delegmode (*dp, flags);if (status) *dp =NULL ; -return ; +out: +if (open->op_claim_type !=NFS4_OPEN_CLAIM_DELEGATE_CUR ) +return nfs_ok; +if (status) +return status; + open->op_stateowner->so_confirmed =1 ; +return nfs_ok; } static int
@@ -1760,8 +1766,13 @@ nfsd4_process_open2(struct svc_rqst *rqsif (fp) {if ((status =nfs4_check_open (fp, open, &stp))) goto out; -nfs4_check_deleg (fp, open, &dp); + status =nfs4_check_deleg (fp, open, &dp); +if (status) + goto out; }else { + status = nfserr_bad_stateid; +if (open->op_claim_type ==NFS4_OPEN_CLAIM_DELEGATE_CUR ) + goto out; status = nfserr_resource; fp =alloc_init_file (ino);if (fp ==NULL )
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: support CLAIM_DELEGATE_CUR
In reply to NeilBrownAdd OPEN claim type NFS4_OPEN_CLAIM_DELEGATE_CUR to nfsd4_open().
A delegation stateid and a name are provided. OPEN with O_CREAT is not legal with this claim type; otherwise, use the NFS4_OPEN_CLAIM_NULL code path to lookup the filename to be opened.
### Diffstat output
./fs/nfsd/nfs4proc.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletion(-)
fs/nfsd/nfs4proc.c renamed from fs/nfsd/nfs4proc.c~current~ +5 -1
@@ -198,6 +198,11 @@ nfsd4_open(struct svc_rqst *rqstp, strucif (status) goto out;switch (open->op_claim_type) { +case NFS4_OPEN_CLAIM_DELEGATE_CUR : + status = nfserr_inval; +if (open->op_create) + goto out; +/* fall through */ case NFS4_OPEN_CLAIM_NULL :/* * (1) set CURRENT_FH to the file being opened,
@@ -220,7 +225,6 @@ nfsd4_open(struct svc_rqst *rqstp, strucif (status) goto out;break ; -case NFS4_OPEN_CLAIM_DELEGATE_CUR :case NFS4_OPEN_CLAIM_DELEGATE_PREV :printk ("NFSD: unsupported OPEN claim type %d\n" , open->op_claim_type);
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: fix fh_expire_type
In reply to NeilBrownWe're returning NFS4_FH_NOEXPIRE_WITH_OPEN | NFS4_FH_VOL_RENAME for the fh_expire_type attribute. This is incorrect:
1. The spec actually only allows NOEXPIRE_WITH_OPEN when VOLATILE_ANY is also set.
2. Filehandles for open files can expire, if the file is removed and there is a reboot.
3. Filehandles are only volatile on rename in the nosubtree check case.
Unfortunately, there's no way to indicate that we only expire on remove. So our only choice is FH4_VOLATILE_ANY. Although it's redundant, we also set FH4_VOL_RENAME in the subtree check case, since subtreecheck does actually cause problems in practice and it seems possibly useful to give clients some way to distinguish that case.
Fix a mispelled #define while we're at it.
### Diffstat output
./fs/nfsd/nfs4xdr.c | 5 ++++- ./include/linux/nfs4.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-)
fs/nfsd/nfs4xdr.c renamed from fs/nfsd/nfs4xdr.c~current~ +4 -1
@@ -1366,7 +1366,10 @@ nfsd4_encode_fattr(struct svc_fh *fhp, sif (bmval0 &FATTR4_WORD0_FH_EXPIRE_TYPE ) {if ((buflen -=4 ) <0 ) goto out_resource; -WRITE32 (NFS4_FH_NOEXPIRE_WITH_OPEN |NFS4_FH_VOL_RENAME ); +if (exp->ex_flags &NFSEXP_NOSUBTREECHECK ) +WRITE32 (NFS4_FH_VOLATILE_ANY ); +else +WRITE32 (NFS4_FH_VOLATILE_ANY |NFS4_FH_VOL_RENAME ); }if (bmval0 &FATTR4_WORD0_CHANGE ) {/*
include/linux/nfs4.h renamed from include/linux/nfs4.h~current~ +1 -1
@@ -28,7 +28,7 @@#define NFS4_ACCESS_DELETE 0x0010#define NFS4_ACCESS_EXECUTE 0x0020 -#define NFS4_FH_PERISTENT 0x0000 +#define NFS4_FH_PERSISTENT 0x0000#define NFS4_FH_NOEXPIRE_WITH_OPEN 0x0001#define NFS4_FH_VOLATILE_ANY 0x0002#define NFS4_FH_VOL_MIGRATION 0x0004
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: block metadata ops during grace period
In reply to NeilBrownWe currently return err_grace if a user attempts a non-reclaim open during the grace period. But we also need to prevent renames and removes, at least, to ensure clients have the chance to recover state on files before they are moved or deleted.
Of course, local users could also do renames and removes during the lease period, and there's not much we can do about that. This at least will help with remote users.
### Diffstat output
./fs/nfsd/nfs4proc.c | 5 +++++ 1 files changed, 5 insertions(+)
fs/nfsd/nfs4proc.c renamed from fs/nfsd/nfs4proc.c~current~ +5 -0
@@ -536,6 +536,8 @@ nfsd4_remove(struct svc_rqst *rqstp, str {int status; +if (nfs4_in_grace ()) +return nfserr_grace; status =nfsd_unlink (rqstp, current_fh,0 , remove->rm_name, remove->rm_namelen);if (status == nfserr_symlink)return nfserr_notdir;
@@ -554,6 +556,9 @@ nfsd4_rename(struct svc_rqst *rqstp, strif (!save_fh->fh_dentry)return status; +if (nfs4_in_grace () && !(save_fh->fh_export->ex_flags + &NFSEXP_NOSUBTREECHECK )) +return nfserr_grace; status =nfsd_rename (rqstp, save_fh, rename->rn_sname, rename->rn_snamelen, current_fh, rename->rn_tname, rename->rn_tnamelen);
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: slabify nfs4_files
In reply to NeilBrownThe structures the server uses to keep track of various pieces of nfsv4 state (open files, outstanding delegations, etc.) are likely to be allocated and deallocated frequently and seem reasonable candidates for slab caches.
While we're at it, the slab code keeps statistics that help catch leaks and such, so we may as well take this chance to eliminate some debugging counters that we've been keeping ourselves.
Start with the struct nfs4_file.
### Diffstat output
./fs/nfsd/nfs4state.c | 58 +++++++++++++++++++++++++++++--------------------- 1 files changed, 34 insertions(+), 24 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +34 -24
@@ -70,8 +70,6 @@ u32 list_add_perfile = 0;u32 list_del_perfile =0 ;u32 add_perclient =0 ;u32 del_perclient =0 ; -u32 alloc_file =0 ; -u32 free_file =0 ;u32 vfsopen =0 ;u32 vfsclose =0 ;u32 alloc_delegation=0 ;
@@ -90,6 +88,9 @@ static void release_stateid_lockowners(s*/ static DECLARE_MUTEX (client_sema); +kmem_cache_t *stateowner_slab =NULL ; +kmem_cache_t *file_slab =NULL ; +void nfs4_lock_state (void ) {
@@ -961,14 +962,14 @@ alloc_init_file(struct inode *ino)struct nfs4_file *fp;unsigned int hashval =file_hashval (ino); -if ((fp =kmalloc (sizeof (struct nfs4_file ),GFP_KERNEL ))) { + fp =kmem_cache_alloc (file_slab,GFP_KERNEL ); +if (fp) {INIT_LIST_HEAD (&fp->fi_hash);INIT_LIST_HEAD (&fp->fi_perfile);INIT_LIST_HEAD (&fp->fi_del_perfile);list_add (&fp->fi_hash, &file_hashtbl[hashval]); fp->fi_inode =igrab (ino); fp->fi_id = current_fileid++; - alloc_file++;return fp; }return NULL ;
@@ -992,29 +993,41 @@ release_all_files(void) } } -kmem_cache_t *stateowner_slab =NULL ; - -static int -nfsd4_init_slabs (void ) +static void +nfsd4_free_slab (kmem_cache_t **slab) { - 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 ; +int status; + +if (*slab ==NULL ) +return ; + status =kmem_cache_destroy (*slab); + *slab =NULL ; +WARN_ON (status); }static void nfsd4_free_slabs (void ) { -int status =0 ; +nfsd4_free_slab (&stateowner_slab); +nfsd4_free_slab (&file_slab); +} -if (stateowner_slab) - status =kmem_cache_destroy (stateowner_slab); - stateowner_slab =NULL ; -BUG_ON (status); +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 ) + goto out_nomem; + file_slab =kmem_cache_create ("nfsd4_files" , +sizeof (struct nfs4_file ),0 ,0 ,NULL ,NULL ); +if (file_slab ==NULL ) + goto out_nomem; +return 0 ; +out_nomem: +nfsd4_free_slabs (); +dprintk ("nfsd4: out of memory while initializing nfsv4\n" ); +return -ENOMEM ; }void
@@ -1167,10 +1180,9 @@ release_stateid(struct nfs4_stateid *stpstatic void release_file (struct nfs4_file *fp) { - free_file++;list_del (&fp->fi_hash);iput (fp->fi_inode); -kfree (fp); +kmem_cache_free (file_slab, fp); }void
@@ -3286,8 +3298,6 @@ __nfs4_state_shutdown(void) list_add_perfile, list_del_perfile);dprintk ("NFSD: add_perclient %d del_perclient %d\n" , add_perclient, del_perclient); -dprintk ("NFSD: alloc_file %d free_file %d\n" , - alloc_file, free_file);dprintk ("NFSD: vfsopen %d vfsclose %d\n" , vfsopen, vfsclose); dprintk("NFSD: alloc_delegation %d free_delegation %d\n",
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: slabify stateids
In reply to NeilBrownAllocate stateid's from a slab cache.
### Diffstat output
./fs/nfsd/nfs4state.c | 22 +++++++++++++++++----- 1 files changed, 17 insertions(+), 5 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +17 -5
@@ -90,6 +90,7 @@ static DECLARE_MUTEX(client_sema);kmem_cache_t *stateowner_slab =NULL ;kmem_cache_t *file_slab =NULL ; +kmem_cache_t *stateid_slab =NULL ;void nfs4_lock_state (void )
@@ -1010,6 +1011,7 @@ nfsd4_free_slabs(void) {nfsd4_free_slab (&stateowner_slab);nfsd4_free_slab (&file_slab); +nfsd4_free_slab (&stateid_slab); } static int
@@ -1023,6 +1025,10 @@ nfsd4_init_slabs(void) sizeof(struct nfs4_file), 0, 0, NULL, NULL);if (file_slab ==NULL ) goto out_nomem; + stateid_slab =kmem_cache_create ("nfsd4_stateids" , +sizeof (struct nfs4_stateid ),0 ,0 ,NULL ,NULL ); +if (stateid_slab ==NULL ) + goto out_nomem;return 0 ; out_nomem:nfsd4_free_slabs ();
@@ -1173,7 +1179,7 @@ release_stateid(struct nfs4_stateid *stp vfsclose++; }else if (flags &LOCK_STATE )locks_remove_posix (filp, (fl_owner_t ) stp->st_stateowner); -kfree (stp); +kmem_cache_free (stateid_slab, stp); stp =NULL ; }
@@ -1606,6 +1612,12 @@ out:return status; } +static inline struct nfs4_stateid * +nfs4_alloc_stateid (void ) +{ +return kmem_cache_alloc (stateid_slab,GFP_KERNEL ); +} + static int nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp, struct nfs4_delegation *dp,
@@ -1613,7 +1625,7 @@ nfs4_new_open(struct svc_rqst *rqstp, st {struct nfs4_stateid *stp; - stp =kmalloc (sizeof (struct nfs4_stateid ),GFP_KERNEL ); + stp =nfs4_alloc_stateid ();if (stp ==NULL )return nfserr_resource;
@@ -1627,7 +1639,7 @@ nfs4_new_open(struct svc_rqst *rqstp, stif (status) {if (status == nfserr_dropit) status = nfserr_jukebox; -kfree (stp); +kmem_cache_free (stateid_slab, stp);return status; } }
@@ -2627,8 +2639,8 @@ alloc_init_lock_stateid(struct nfs4_statstruct nfs4_stateid *stp;unsigned int hashval =stateid_hashval (sop->so_id, fp->fi_id); -if ((stp =kmalloc (sizeof (struct nfs4_stateid ), -GFP_KERNEL )) ==NULL ) + stp =nfs4_alloc_stateid (); +if (stp ==NULL ) goto out;INIT_LIST_HEAD (&stp->st_hash);INIT_LIST_HEAD (&stp->st_perfile);
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: slabify delegations
In reply to NeilBrownAllocate delegations from a slab cache.
### Diffstat output
./fs/nfsd/nfs4state.c | 19 +++++++++---------- 1 files changed, 9 insertions(+), 10 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +9 -10
@@ -72,8 +72,6 @@ u32 add_perclient = 0;u32 del_perclient =0 ;u32 vfsopen =0 ;u32 vfsclose =0 ; -u32 alloc_delegation=0 ; -u32 free_delegation=0 ;/* forward declarations */ struct nfs4_stateid *find_stateid (stateid_t *stid,int flags);
@@ -91,6 +89,7 @@ static DECLARE_MUTEX(client_sema);kmem_cache_t *stateowner_slab =NULL ;kmem_cache_t *file_slab =NULL ;kmem_cache_t *stateid_slab =NULL ; +kmem_cache_t *deleg_slab =NULL ;void nfs4_lock_state (void )
@@ -138,8 +137,8 @@ alloc_init_deleg(struct nfs4_client *clpstruct nfs4_callback *cb = &stp->st_stateowner->so_client->cl_callback;dprintk ("NFSD alloc_init_deleg\n" ); -if ((dp =kmalloc (sizeof (struct nfs4_delegation ), -GFP_KERNEL )) ==NULL ) + dp =kmem_cache_alloc (deleg_slab,GFP_KERNEL ); +if (dp ==NULL )return dp;INIT_LIST_HEAD (&dp->dl_del_perfile);INIT_LIST_HEAD (&dp->dl_del_perclnt);
@@ -164,7 +163,6 @@ alloc_init_deleg(struct nfs4_client *clpatomic_set (&dp->dl_count,1 );list_add (&dp->dl_del_perfile, &fp->fi_del_perfile);list_add (&dp->dl_del_perclnt, &clp->cl_del_perclnt); - alloc_delegation++;return dp; }
@@ -173,8 +171,7 @@ nfs4_put_delegation(struct nfs4_delegati {if (atomic_dec_and_test (&dp->dl_count)) {dprintk ("NFSD: freeing dp %p\n" ,dp); -kfree (dp); - free_delegation++; +kmem_cache_free (deleg_slab, dp); } }
@@ -1012,6 +1009,7 @@ nfsd4_free_slabs(void)nfsd4_free_slab (&stateowner_slab);nfsd4_free_slab (&file_slab);nfsd4_free_slab (&stateid_slab); +nfsd4_free_slab (&deleg_slab); } static int
@@ -1029,6 +1027,10 @@ nfsd4_init_slabs(void) sizeof(struct nfs4_stateid), 0, 0, NULL, NULL);if (stateid_slab ==NULL ) goto out_nomem; + deleg_slab =kmem_cache_create ("nfsd4_delegations" , +sizeof (struct nfs4_delegation ),0 ,0 ,NULL ,NULL ); +if (deleg_slab ==NULL ) + goto out_nomem;return 0 ; out_nomem:nfsd4_free_slabs ();
@@ -3312,9 +3314,6 @@ __nfs4_state_shutdown(void) add_perclient, del_perclient);dprintk ("NFSD: vfsopen %d vfsclose %d\n" , vfsopen, vfsclose); -dprintk ("NFSD: alloc_delegation %d free_delegation %d\n" , - alloc_delegation, free_delegation); - }void
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: fix struct file leak
In reply to NeilBrownWe were failing to close on an error path, resulting in a leak of struct files which could take a v4 server down fairly quickly....
So call nfs4_close_delegation instead of just open-coding parts of it.
Simplify the cleanup on delegation failure while we're at it.
### Diffstat output
./fs/nfsd/nfs4state.c | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +3 -5
@@ -190,7 +190,8 @@ nfs4_close_delegation(struct nfs4_delega dp->dl_vfs_file =NULL ;/* The following nfsd_close may not actually close the file, * but we want to remove the lease in any case. */ -setlease (filp,F_UNLCK , &dp->dl_flock); +if (dp->dl_flock) +setlease (filp,F_UNLCK , &dp->dl_flock);nfsd_close (filp); vfsclose++; }
@@ -1673,10 +1674,7 @@ nfs4_open_delegation(struct svc_fh *fh,if ((status =setlease (stp->st_vfs_file, flag ==NFS4_OPEN_DELEGATE_READ ?F_RDLCK :F_WRLCK , &flp))) {dprintk ("NFSD: setlease failed [%d], no delegation\n" , status); -list_del (&dp->dl_del_perfile); -list_del (&dp->dl_del_perclnt); -nfs4_put_delegation (dp); - free_delegation++; +unhash_delegation (dp); flag =NFS4_OPEN_DELEGATE_NONE ; goto out; }
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: remove debugging counters
In reply to NeilBrownThese remaining debugging counters haven't proved that useful.
### Diffstat output
./fs/nfsd/nfs4state.c | 25 +------------------------ 1 files changed, 1 insertion(+), 24 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +1 -24
@@ -65,14 +65,6 @@ static u32 nfs4_init;stateid_t zerostateid;/* bits all 0 */ stateid_t onestateid;/* bits all 1 */ -/* debug counters */ -u32 list_add_perfile =0 ; -u32 list_del_perfile =0 ; -u32 add_perclient =0 ; -u32 del_perclient =0 ; -u32 vfsopen =0 ; -u32 vfsclose =0 ; -/* forward declarations */ struct nfs4_stateid *find_stateid (stateid_t *stid,int flags);static struct nfs4_delegation *find_delegation_stateid (struct inode *ino,stateid_t *stid);
@@ -192,7 +184,6 @@ nfs4_close_delegation(struct nfs4_delegaif (dp->dl_flock)setlease (filp,F_UNLCK , &dp->dl_flock);nfsd_close (filp); - vfsclose++; }/* Called under the state lock. */
@@ -1083,7 +1074,6 @@ alloc_init_open_stateowner(unsigned intlist_add (&sop->so_idhash, &ownerid_hashtbl[idhashval]);list_add (&sop->so_strhash, &ownerstr_hashtbl[strhashval]);list_add (&sop->so_perclient, &clp->cl_perclient); - add_perclient++; sop->so_is_open_owner =1 ; sop->so_id = current_ownerid++; sop->so_client = clp;
@@ -1117,10 +1107,8 @@ unhash_stateowner(struct nfs4_stateownerlist_del (&sop->so_idhash);list_del (&sop->so_strhash); -if (sop->so_is_open_owner) { +if (sop->so_is_open_owner)list_del (&sop->so_perclient); - del_perclient++; - }list_del (&sop->so_perlockowner);while (!list_empty (&sop->so_perfilestate)) { stp = list_entry(sop->so_perfilestate.next,
@@ -1151,7 +1139,6 @@ init_stateid(struct nfs4_stateid *stp, sINIT_LIST_HEAD (&stp->st_perfile);list_add (&stp->st_hash, &stateid_hashtbl[hashval]);list_add (&stp->st_perfilestate, &sop->so_perfilestate); - list_add_perfile++;list_add (&stp->st_perfile, &fp->fi_perfile); stp->st_stateowner = sop; stp->st_file = fp;
@@ -1171,14 +1158,12 @@ release_stateid(struct nfs4_stateid *stpstruct file *filp = stp->st_vfs_file;list_del (&stp->st_hash); - list_del_perfile++;list_del (&stp->st_perfile);list_del (&stp->st_perfilestate);if (flags &OPEN_STATE ) {release_stateid_lockowners (stp); stp->st_vfs_file =NULL ;nfsd_close (filp); - vfsclose++; }else if (flags &LOCK_STATE )locks_remove_posix (filp, (fl_owner_t ) stp->st_stateowner);kmem_cache_free (stateid_slab, stp);
@@ -1645,7 +1630,6 @@ nfs4_new_open(struct svc_rqst *rqstp, streturn status; } } - vfsopen++; *stpp = stp;return 0 ; }
@@ -2650,7 +2634,6 @@ alloc_init_lock_stateid(struct nfs4_statINIT_LIST_HEAD (&stp->st_perlockowner);/* not used */ list_add (&stp->st_hash, &lockstateid_hashtbl[hashval]);list_add (&stp->st_perfile, &fp->fi_perfile); - list_add_perfile++;list_add (&stp->st_perfilestate, &sop->so_perfilestate); stp->st_stateowner = sop; stp->st_file = fp;
@@ -3308,12 +3291,6 @@ __nfs4_state_shutdown(void)cancel_delayed_work (&laundromat_work);flush_scheduled_work (); nfs4_init =0 ; -dprintk ("NFSD: list_add_perfile %d list_del_perfile %d\n" , - list_add_perfile, list_del_perfile); -dprintk ("NFSD: add_perclient %d del_perclient %d\n" , - add_perclient, del_perclient); -dprintk ("NFSD: vfsopen %d vfsclose %d\n" , - vfsopen, vfsclose); }void
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: rename nfs4_file fields
In reply to NeilBrownTrivial renaming patch:
I can never remember, while looking at various lists relating the nfsd4 state structures, which are the "heads" and which are items on other lists, or which structures are actually on the various lists. The following convention helps
me: given structures foo and bar, with foo containing the head of a list of bars, use "bars" for the name of the head of the list contained in the struct foo, and use "per_foo" for the entries in the struct bars.
Go ahead and do this for struct nfs4_file.
### Diffstat output
./fs/nfsd/nfs4state.c | 22 +++++++++++----------- ./include/linux/nfsd/state.h | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +11 -11
@@ -153,7 +153,7 @@ alloc_init_deleg(struct nfs4_client *clp current_fh->fh_handle.fh_size); dp->dl_time =0 ;atomic_set (&dp->dl_count,1 ); -list_add (&dp->dl_del_perfile, &fp->fi_del_perfile); +list_add (&dp->dl_del_perfile, &fp->fi_delegations);list_add (&dp->dl_del_perclnt, &clp->cl_del_perclnt);return dp; }
@@ -954,8 +954,8 @@ alloc_init_file(struct inode *ino) fp =kmem_cache_alloc (file_slab,GFP_KERNEL );if (fp) {INIT_LIST_HEAD (&fp->fi_hash); -INIT_LIST_HEAD (&fp->fi_perfile); -INIT_LIST_HEAD (&fp->fi_del_perfile); +INIT_LIST_HEAD (&fp->fi_stateids); +INIT_LIST_HEAD (&fp->fi_delegations);list_add (&fp->fi_hash, &file_hashtbl[hashval]); fp->fi_inode =igrab (ino); fp->fi_id = current_fileid++;
@@ -974,7 +974,7 @@ release_all_files(void)while (!list_empty (&file_hashtbl[i])) { fp = list_entry(file_hashtbl[i].next, struct nfs4_file, fi_hash);/* this should never be more than once... */ -if (!list_empty (&fp->fi_perfile) || !list_empty (&fp->fi_del_perfile)) { +if (!list_empty (&fp->fi_stateids) || !list_empty (&fp->fi_delegations)) {printk ("ERROR: release_all_files: file %p is open, creating dangling state !!!\n" ,fp); }release_file (fp);
@@ -1139,7 +1139,7 @@ init_stateid(struct nfs4_stateid *stp, sINIT_LIST_HEAD (&stp->st_perfile);list_add (&stp->st_hash, &stateid_hashtbl[hashval]);list_add (&stp->st_perfilestate, &sop->so_perfilestate); -list_add (&stp->st_perfile, &fp->fi_perfile); +list_add (&stp->st_perfile, &fp->fi_stateids); stp->st_stateowner = sop; stp->st_file = fp; stp->st_stateid.si_boot = boot_time;
@@ -1204,7 +1204,7 @@ release_state_owner(struct nfs4_stateidif (sop->so_confirmed &&list_empty (&sop->so_perfilestate))move_to_close_lru (sop);/* unused nfs4_file's are releseed. XXX slab cache? */ -if (list_empty (&fp->fi_perfile) &&list_empty (&fp->fi_del_perfile)) { +if (list_empty (&fp->fi_stateids) &&list_empty (&fp->fi_delegations)) {release_file (fp); } }
@@ -1294,7 +1294,7 @@ nfs4_share_conflict(struct svc_fh *curre fp =find_file (ino);if (fp) {/* Search for conflicting share reservations */ -list_for_each_entry (stp, &fp->fi_perfile, st_perfile) { +list_for_each_entry (stp, &fp->fi_stateids, st_perfile) {if (test_bit (deny_type, &stp->st_deny_bmap) ||test_bit (NFS4_SHARE_DENY_BOTH , &stp->st_deny_bmap))return nfserr_share_denied;
@@ -1545,7 +1545,7 @@ find_delegation_file(struct nfs4_file *f {struct nfs4_delegation *dp; -list_for_each_entry (dp, &fp->fi_del_perfile, dl_del_perfile) { +list_for_each_entry (dp, &fp->fi_delegations, dl_del_perfile) {if (dp->dl_stateid.si_stateownerid == stid->si_stateownerid)return dp; }
@@ -1583,7 +1583,7 @@ nfs4_check_open(struct nfs4_file *fp, stint status = nfserr_share_denied;struct nfs4_stateowner *sop = open->op_stateowner; -list_for_each_entry (local, &fp->fi_perfile, st_perfile) { +list_for_each_entry (local, &fp->fi_stateids, st_perfile) {/* ignore lock owners */ if (local->st_stateowner->so_is_open_owner ==0 )continue ;
@@ -1830,7 +1830,7 @@ nfsd4_process_open2(struct svc_rqst *rqs stp->st_stateid.si_fileid, stp->st_stateid.si_generation); out:/* take the opportunity to clean up unused state */ -if (fp &&list_empty (&fp->fi_perfile) &&list_empty (&fp->fi_del_perfile)) +if (fp &&list_empty (&fp->fi_stateids) &&list_empty (&fp->fi_delegations))release_file (fp);/* CLAIM_PREVIOUS has different error returns */
@@ -2633,7 +2633,7 @@ alloc_init_lock_stateid(struct nfs4_statINIT_LIST_HEAD (&stp->st_perfilestate);INIT_LIST_HEAD (&stp->st_perlockowner);/* not used */ list_add (&stp->st_hash, &lockstateid_hashtbl[hashval]); -list_add (&stp->st_perfile, &fp->fi_perfile); +list_add (&stp->st_perfile, &fp->fi_stateids);list_add (&stp->st_perfilestate, &sop->so_perfilestate); stp->st_stateowner = sop; stp->st_file = fp;
include/linux/nfsd/state.h renamed from include/linux/nfsd/state.h~current~ +2 -2
@@ -218,8 +218,8 @@ struct nfs4_stateowner {*/ struct nfs4_file {struct list_head fi_hash;/* hash by "struct inode *" */ -struct list_head fi_perfile;/* list: nfs4_stateid */ -struct list_head fi_del_perfile;/* list: nfs4_delegation */ +struct list_head fi_stateids; +struct list_head fi_delegations;struct inode *fi_inode;u32 fi_id;/* used with stateowner->so_id * for stateid_hashtbl hash */
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs
PATCH 1/1 nfsd4: reference count struct nfs4_file
In reply to NeilBrownAdd a struct kref to each nfs4_file and take a reference to it from each stateid and delegation that refers to it. The atomicity guarantees are overkill given that all this stuff is done under the single nfsd4 state lock, but a) we'd like finer-grained locking some day, and b) this simplifies the cleanup of the structures a bit, something that has previously been a bit complicated and bug-prone.
### Diffstat output
./fs/nfsd/nfs4state.c | 100 +++++++++++++++++++++---------------------- ./include/linux/nfsd/state.h | 1 2 files changed, 52 insertions(+), 49 deletions(-)
fs/nfsd/nfs4state.c renamed from fs/nfsd/nfs4state.c~current~ +51 -49
@@ -111,7 +111,6 @@ opaque_hashval(const void *ptr, int nbyt/* forward declarations */ static void release_stateowner (struct nfs4_stateowner *sop);static void release_stateid (struct nfs4_stateid *stp,int flags); -static void release_file (struct nfs4_file *fp);/* * Delegation state
@@ -121,6 +120,27 @@ static void release_file(struct nfs4_filspinlock_t recall_lock;static struct list_head del_recall_lru; +static void +free_nfs4_file (struct kref *kref) +{ + struct nfs4_file *fp = container_of(kref, struct nfs4_file, fi_ref); +list_del (&fp->fi_hash); +iput (fp->fi_inode); +kmem_cache_free (file_slab, fp); +} + +static inline void +put_nfs4_file (struct nfs4_file *fi) +{ +kref_put (&fi->fi_ref, free_nfs4_file); +} + +static inline void +get_nfs4_file (struct nfs4_file *fi) +{ +kref_get (&fi->fi_ref); +} +static struct nfs4_delegation *alloc_init_deleg (struct nfs4_client *clp,struct nfs4_stateid *stp,struct svc_fh *current_fh,u32 type) {
@@ -136,6 +156,7 @@ alloc_init_deleg(struct nfs4_client *clpINIT_LIST_HEAD (&dp->dl_del_perclnt);INIT_LIST_HEAD (&dp->dl_recall_lru); dp->dl_client = clp; +get_nfs4_file (fp); dp->dl_file = fp; dp->dl_flock =NULL ;get_file (stp->st_vfs_file);
@@ -163,6 +184,7 @@ nfs4_put_delegation(struct nfs4_delegati {if (atomic_dec_and_test (&dp->dl_count)) {dprintk ("NFSD: freeing dp %p\n" ,dp); +put_nfs4_file (dp->dl_file);kmem_cache_free (deleg_slab, dp); } }
@@ -953,6 +975,7 @@ alloc_init_file(struct inode *ino) fp =kmem_cache_alloc (file_slab,GFP_KERNEL );if (fp) { +kref_init (&fp->fi_ref);INIT_LIST_HEAD (&fp->fi_hash);INIT_LIST_HEAD (&fp->fi_stateids);INIT_LIST_HEAD (&fp->fi_delegations);
@@ -965,24 +988,6 @@ alloc_init_file(struct inode *ino) }static void -release_all_files (void ) -{ -int i; -struct nfs4_file *fp; - -for (i=0 ;i<FILE_HASH_SIZE ;i++) { -while (!list_empty (&file_hashtbl[i])) { - fp = list_entry(file_hashtbl[i].next, struct nfs4_file, fi_hash); -/* this should never be more than once... */ -if (!list_empty (&fp->fi_stateids) || !list_empty (&fp->fi_delegations)) { -printk ("ERROR: release_all_files: file %p is open, creating dangling state !!!\n" ,fp); - } -release_file (fp); - } - } -} - -static void nfsd4_free_slab (kmem_cache_t **slab) {int status;
@@ -1141,6 +1146,7 @@ init_stateid(struct nfs4_stateid *stp, slist_add (&stp->st_perfilestate, &sop->so_perfilestate);list_add (&stp->st_perfile, &fp->fi_stateids); stp->st_stateowner = sop; +get_nfs4_file (fp); stp->st_file = fp; stp->st_stateid.si_boot = boot_time; stp->st_stateid.si_stateownerid = sop->so_id;
@@ -1166,18 +1172,11 @@ release_stateid(struct nfs4_stateid *stpnfsd_close (filp); }else if (flags &LOCK_STATE )locks_remove_posix (filp, (fl_owner_t ) stp->st_stateowner); +put_nfs4_file (stp->st_file);kmem_cache_free (stateid_slab, stp); stp =NULL ; } -static void -release_file (struct nfs4_file *fp) -{ -list_del (&fp->fi_hash); -iput (fp->fi_inode); -kmem_cache_free (file_slab, fp); -} -void move_to_close_lru (struct nfs4_stateowner *sop) {
@@ -1192,7 +1191,6 @@ void release_state_owner(struct nfs4_stateid *stp, int flag) {struct nfs4_stateowner *sop = stp->st_stateowner; -struct nfs4_file *fp = stp->st_file;dprintk ("NFSD: release_state_owner\n" );release_stateid (stp, flag);
@@ -1203,10 +1201,6 @@ release_state_owner(struct nfs4_stateid*/ if (sop->so_confirmed &&list_empty (&sop->so_perfilestate))move_to_close_lru (sop); -/* unused nfs4_file's are releseed. XXX slab cache? */ -if (list_empty (&fp->fi_stateids) &&list_empty (&fp->fi_delegations)) { -release_file (fp); - } } static int
@@ -1236,8 +1230,10 @@ find_file(struct inode *ino)struct nfs4_file *fp;list_for_each_entry (fp, &file_hashtbl[hashval], fi_hash) { -if (fp->fi_inode == ino) +if (fp->fi_inode == ino) { +get_nfs4_file (fp);return fp; + } }return NULL ; }
@@ -1288,19 +1284,24 @@ nfs4_share_conflict(struct svc_fh *currestruct inode *ino = current_fh->fh_dentry->d_inode;struct nfs4_file *fp;struct nfs4_stateid *stp; +int ret;dprintk ("NFSD: nfs4_share_conflict\n" ); fp =find_file (ino); -if (fp) { +if (!fp) +return nfs_ok; + ret = nfserr_share_denied;/* Search for conflicting share reservations */ -list_for_each_entry (stp, &fp->fi_stateids, st_perfile) { -if (test_bit (deny_type, &stp->st_deny_bmap) || -test_bit (NFS4_SHARE_DENY_BOTH , &stp->st_deny_bmap)) -return nfserr_share_denied; - } +list_for_each_entry (stp, &fp->fi_stateids, st_perfile) { +if (test_bit (deny_type, &stp->st_deny_bmap) || +test_bit (NFS4_SHARE_DENY_BOTH , &stp->st_deny_bmap)) + goto out; } -return nfs_ok; + ret = nfs_ok; +out: +put_nfs4_file (fp); +return ret; } static inline void
@@ -1829,10 +1830,8 @@ nfsd4_process_open2(struct svc_rqst *rqs stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid, stp->st_stateid.si_fileid, stp->st_stateid.si_generation); out: -/* take the opportunity to clean up unused state */ -if (fp &&list_empty (&fp->fi_stateids) &&list_empty (&fp->fi_delegations)) -release_file (fp); - +if (fp) +put_nfs4_file (fp);/* CLAIM_PREVIOUS has different error returns */ nfs4_set_claim_prev (open, &status);/*
@@ -2480,16 +2479,19 @@ find_stateid(stateid_t *stid, int flags)static struct nfs4_delegation *find_delegation_stateid (struct inode *ino,stateid_t *stid) { -struct nfs4_file *fp =NULL ; +struct nfs4_file *fp; +struct nfs4_delegation *dl;dprintk ("NFSD:find_delegation_stateid stateid=(%08x/%08x/%08x/%08x)\n" , stid->si_boot, stid->si_stateownerid, stid->si_fileid, stid->si_generation); fp =find_file (ino); -if (fp) -return find_delegation_file (fp, stid); -return NULL ; +if (!fp) +return NULL ; + dl =find_delegation_file (fp, stid); +put_nfs4_file (fp); +return dl; }/*
@@ -2636,6 +2638,7 @@ alloc_init_lock_stateid(struct nfs4_statlist_add (&stp->st_perfile, &fp->fi_stateids);list_add (&stp->st_perfilestate, &sop->so_perfilestate); stp->st_stateowner = sop; +get_nfs4_file (fp); stp->st_file = fp; stp->st_stateid.si_boot = boot_time; stp->st_stateid.si_stateownerid = sop->so_id;
@@ -3287,7 +3290,6 @@ __nfs4_state_shutdown(void)unhash_delegation (dp); } -release_all_files ();cancel_delayed_work (&laundromat_work);flush_scheduled_work (); nfs4_init =0 ;
include/linux/nfsd/state.h renamed from include/linux/nfsd/state.h~current~ +1 -0
@@ -217,6 +217,7 @@ struct nfs4_stateowner {* share_acces, share_deny on the file. */ struct nfs4_file { +struct kref fi_ref;struct list_head fi_hash;/* hash by "struct inode *" */ struct list_head fi_stateids;struct list_head fi_delegations;
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
NFS maillist - [email protected]
https://lists.sourceforge.net/lists/listinfo/nfs