Re: [PATCH 15/20] ovl: narrow locking on ovl_remove_and_whiteout()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 11 Jul 2025, Amir Goldstein wrote:
> On Fri, Jul 11, 2025 at 1:21 AM NeilBrown <neil@xxxxxxxxxx> wrote:
> >
> > Normally it is ok to include a lookup with the subsequent operation on
> > the result.  However in this case ovl_cleanup_and_whiteout() already
> > (potentially) creates a whiteout inode so we need separate locking.
> 
> The change itself looks fine and simple, but I didn't understand the text above.
> 
> Can you please explain?

Maybe that was really a note to myself - at first glance the change
looked a little misguided.

While it is possible to perform the lookups outside the directory lock,
the take the lock, check the parents, perform the operation, it is
generally better to combine the lookup with the lock (hence my proposed
lookup_and_lock operations).

In the current locking scheme, performing the lookup and the operation
under the one lock avoids some races.
In my new code we don't avoid the race but the lookup-and-lock can
detect the race and repeat the lookup.

So in generally we can avoid returning the -EINVAL if the parent check
fails.

So changing code that did a lookup and rename in the same lock to code
which takes the lock twice seems wrong.  I wanted to justify it, and the
justification is the need to create the whiteout between the lookup and
the rename.

A different way to do this might be the create the whiteout before doing
the lookup_upper.  That would require a larger refactoring that probably
isn't justified.

I've changed it to:

===========
This code:
  performs a lookup_upper
  created a whiteout object
  renames the whiteout over the result of the lookup

The create and the rename must be locked separated for proposed
directory locking changes.  This patch takes a first step of moving the
lookup out of the locked region.
===========

Thanks,
NeilBrown


> 
> Thanks,
> Amir.
> 
> >
> > Signed-off-by: NeilBrown <neil@xxxxxxxxxx>
> > ---
> >  fs/overlayfs/dir.c | 17 ++++++++---------
> >  1 file changed, 8 insertions(+), 9 deletions(-)
> >
> > diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
> > index d01e83f9d800..8580cd5c61e4 100644
> > --- a/fs/overlayfs/dir.c
> > +++ b/fs/overlayfs/dir.c
> > @@ -769,15 +769,11 @@ static int ovl_remove_and_whiteout(struct dentry *dentry,
> >                         goto out;
> >         }
> >
> > -       err = ovl_lock_rename_workdir(workdir, NULL, upperdir, NULL);
> > -       if (err)
> > -               goto out_dput;
> > -
> > -       upper = ovl_lookup_upper(ofs, dentry->d_name.name, upperdir,
> > -                                dentry->d_name.len);
> > +       upper = ovl_lookup_upper_unlocked(ofs, dentry->d_name.name, upperdir,
> > +                                         dentry->d_name.len);
> >         err = PTR_ERR(upper);
> >         if (IS_ERR(upper))
> > -               goto out_unlock;
> > +               goto out_dput;
> >
> >         err = -ESTALE;
> >         if ((opaquedir && upper != opaquedir) ||
> > @@ -786,6 +782,10 @@ static int ovl_remove_and_whiteout(struct dentry *dentry,
> >                 goto out_dput_upper;
> >         }
> >
> > +       err = ovl_lock_rename_workdir(workdir, NULL, upperdir, upper);
> > +       if (err)
> > +               goto out_dput_upper;
> > +
> >         err = ovl_cleanup_and_whiteout(ofs, upperdir, upper);
> >         if (err)
> >                 goto out_d_drop;
> > @@ -793,10 +793,9 @@ static int ovl_remove_and_whiteout(struct dentry *dentry,
> >         ovl_dir_modified(dentry->d_parent, true);
> >  out_d_drop:
> >         d_drop(dentry);
> > +       unlock_rename(workdir, upperdir);
> >  out_dput_upper:
> >         dput(upper);
> > -out_unlock:
> > -       unlock_rename(workdir, upperdir);
> >  out_dput:
> >         dput(opaquedir);
> >  out:
> > --
> > 2.49.0
> >
> 






[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux