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@xxxxxxxxxx> > --- > 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@xxxxxxx> Thanks, NeilBrown