Re: [PATCH v1 02/12] Add and use d_for_each_positive_child family of iterators

NeilBrown <[email protected]>
Newsgroups org.kernel.vger.autofs,org.kernel.vger.ceph-devel,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-nfs
Message-ID <[email protected]>
On Tue, 11 Aug 2026, Miklos Szeredi wrote:
> On Mon, 3 Aug 2026 at 03:38, NeilBrown <[email protected]> wrote:
> 
> > coda_flag_children() doesn't need rcu_read_lock() as holding any
> > spinlock prevents an RCU critical section from finishing.
> 
> I think prep changes should go in separate patches.
> 
> The conversion should be an equivalent transformation.

Ok, that's reasonable.

> 
> > nfs_clear_verifier_directory() is changed slightly so the parent lock is
> > dropped and retaken between clearing the verifier on the parent and on
> > all the children.  I think this is safe.
> 
> This can also be a prep patch.
> 
> > get_next_postive_dentry() in autofs now holds the parent lock a bit
> > less.  The only non-trivial code that is no locked any more is
> >    parent = p->d_parent
> > This cannot need the lock as autofs doesn't support rename and
> > a ref is held on a descendent of parent, so ->d_parent cannot
> > change.  And if it could, the lock wouldn't help.
> 
> And this too.
> 
> > diff --git a/fs/autofs/expire.c b/fs/autofs/expire.c
> > index 5c2d459e1e48..7b0a22629415 100644
> > --- a/fs/autofs/expire.c
> > +++ b/fs/autofs/expire.c
> > @@ -70,12 +70,9 @@ static int autofs_mount_busy(struct vfsmount *mnt,
> >         return status;
> >  }
> >
> > -/* p->d_lock held */
> >  static struct dentry *positive_after(struct dentry *p, struct dentry *child)
> 
> Move this primitive to libfs.c?

By the end of the series it is nearly identical to scan_positives().
So maybe I could add a patch which exports that and uses it instead
of positive_after().

> 
> > --- a/fs/ceph/mds_client.c
> > +++ b/fs/ceph/mds_client.c
> > @@ -2182,14 +2182,10 @@ static bool drop_negative_children(struct dentry *dentry)
> >         if (!d_is_dir(dentry))
> >                 goto out;
> >
> > -       spin_lock(&dentry->d_lock);
> > -       hlist_for_each_entry(child, &dentry->d_children, d_sib) {
> > -               if (d_really_is_positive(child)) {
> > -                       all_negative = false;
> > -                       break;
> > -               }
> > +       d_for_each_positive_child(child, dentry) {
> > +               all_negative = false;
> > +               break;
> >         }
> > -       spin_unlock(&dentry->d_lock);
> 
> simple_empty()?

Maybe...
They aren't quite the same in that simple_empty() locks the found
positive dentry and checks again.  drop_negative_children() doesn't pay
the cost of that spin lock.
Does that matter?  Is the spinlock needed?  Should I remove it from
simple_empty()?

Also they are called in different circumstances.

simple_empty() is used for an in-dcache filesystem.  It is called with
the directory locked (i_rwsem) so nothing can be added/removed and it
gives an answer about the directory (and so shouldn't need the spinlock
as it has the i_rwsem).

drop_negative_children() is called on a caching filesystem so it is
reporting on the cache, not on the directory.  Also i_rwsem isn't held
(so maybe it does need the spinlock???)

I wonder if ceph really wants a version of shrink_dcache_parent() which
only drops negative children.....  looking at the history is probably
doesn't and probably isn't bothered by TOCTOU races between checking for
positives, and calling shrink_dcache_parent().

I think I would rather keep the to separate.

Thanks again,
NeilBrown


> 
> Thanks,
> Miklos
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.