Message ID | 166665108230.50761.12047289373435044414.stgit@klimt.1015granger.net (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | A course change, for sure | expand |
On Tue, 25 Oct 2022, Chuck Lever wrote: > find_file() is now the only caller of find_file_locked(), so just > fold these two together. > > Name nfs4_file-related helpers consistently. There are already > nfs4_file_yada functions, so let's go with the same convention used > by put_nfs4_file(): find_nfs4_file(). > > Signed-off-by: Chuck Lever <chuck.lever@oracle.com> > --- > fs/nfsd/nfs4state.c | 35 ++++++++++++++--------------------- > 1 file changed, 14 insertions(+), 21 deletions(-) > > diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c > index 529995a9e916..abed795bb4ec 100644 > --- a/fs/nfsd/nfs4state.c > +++ b/fs/nfsd/nfs4state.c > @@ -4666,31 +4666,23 @@ move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net) > nfs4_put_stid(&last->st_stid); > } > > -/* search file_hashtbl[] for file */ > -static struct nfs4_file * > -find_file_locked(const struct svc_fh *fh, unsigned int hashval) > +static noinline_for_stack struct nfs4_file * > +find_nfs4_file(const struct svc_fh *fhp) > { > - struct nfs4_file *fp; > + unsigned int hashval = file_hashval(fhp); > + struct nfs4_file *fi = NULL; > > - hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash, > - lockdep_is_held(&state_lock)) { > - if (fh_match(&fp->fi_fhandle, &fh->fh_handle)) { > - if (refcount_inc_not_zero(&fp->fi_ref)) > - return fp; > + rcu_read_lock(); > + hlist_for_each_entry_rcu(fi, &file_hashtbl[hashval], fi_hash, > + lockdep_is_held(&state_lock)) { > + if (fh_match(&fi->fi_fhandle, &fhp->fh_handle)) { > + if (!refcount_inc_not_zero(&fi->fi_ref)) > + fi = NULL; This looks .... imperfect to me. If the refcount_inc_not_zero fails, it means we haven't found what we are looking for, so why break out of the loop? I guess we can *know* that if some other thread has deleted the entry and some third thread has added a new entry then the new entry will be early in the list so it doesn't hurt to stop now. But it seems unnecessary. I would write this. if (fh_match(&fi->fi_fhandle, &fhp->fh_handle) && refcount_inc_not_zero(&fi->fi_ref)) break; > + break; > } > } .. > rcu_read_unlock(); .. > + return fi; This assumes that when the loop completes normally, the loop variable is NULL. That is the case for this particular for_each loop, but isn't for some others. There was a recent spate of patches for for_each loops that made the wrong assumption so I feel a bit wary. At most I might suggest a comment ... but that probably wouldn't help at all.. So it is probably fine as it is. So I'd like to see the loop simplified to remove the assignment (fi = NULL), but either way Reviewed-by: NeilBrown <neilb@suse.de> Thanks, NeilBrown
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 529995a9e916..abed795bb4ec 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4666,31 +4666,23 @@ move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net) nfs4_put_stid(&last->st_stid); } -/* search file_hashtbl[] for file */ -static struct nfs4_file * -find_file_locked(const struct svc_fh *fh, unsigned int hashval) +static noinline_for_stack struct nfs4_file * +find_nfs4_file(const struct svc_fh *fhp) { - struct nfs4_file *fp; + unsigned int hashval = file_hashval(fhp); + struct nfs4_file *fi = NULL; - hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash, - lockdep_is_held(&state_lock)) { - if (fh_match(&fp->fi_fhandle, &fh->fh_handle)) { - if (refcount_inc_not_zero(&fp->fi_ref)) - return fp; + rcu_read_lock(); + hlist_for_each_entry_rcu(fi, &file_hashtbl[hashval], fi_hash, + lockdep_is_held(&state_lock)) { + if (fh_match(&fi->fi_fhandle, &fhp->fh_handle)) { + if (!refcount_inc_not_zero(&fi->fi_ref)) + fi = NULL; + break; } } - return NULL; -} - -static struct nfs4_file * find_file(struct svc_fh *fh) -{ - struct nfs4_file *fp; - unsigned int hashval = file_hashval(fh); - - rcu_read_lock(); - fp = find_file_locked(fh, hashval); rcu_read_unlock(); - return fp; + return fi; } /* @@ -4741,9 +4733,10 @@ nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type) struct nfs4_file *fp; __be32 ret = nfs_ok; - fp = find_file(current_fh); + fp = find_nfs4_file(current_fh); if (!fp) return ret; + /* Check for conflicting share reservations */ spin_lock(&fp->fi_lock); if (fp->fi_share_deny & deny_type)
find_file() is now the only caller of find_file_locked(), so just fold these two together. Name nfs4_file-related helpers consistently. There are already nfs4_file_yada functions, so let's go with the same convention used by put_nfs4_file(): find_nfs4_file(). Signed-off-by: Chuck Lever <chuck.lever@oracle.com> --- fs/nfsd/nfs4state.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-)