ovl: narrow locking on ovl_remove_and_whiteout()

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

The create and the rename must be locked separately for proposed
directory locking changes.  This patch takes a first step of moving the
lookup out of the locked region.  A subsequent patch will separate the
create from the rename.

Signed-off-by: NeilBrown <neil@brown.name>
Link: https://lore.kernel.org/20250716004725.1206467-17-neil@brown.name
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
NeilBrown 2025-07-16 10:44:27 +10:00 committed by Christian Brauner
parent 241062ae5d
commit c69566b1d1
No known key found for this signature in database
GPG Key ID: 91C61BC06578DCA2

View File

@ -770,15 +770,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) ||
@ -787,17 +783,18 @@ static int ovl_remove_and_whiteout(struct dentry *dentry,
goto out_dput_upper;
}
err = ovl_cleanup_and_whiteout(ofs, upperdir, upper);
err = ovl_lock_rename_workdir(workdir, NULL, upperdir, upper);
if (err)
goto out_d_drop;
goto out_dput_upper;
err = ovl_cleanup_and_whiteout(ofs, upperdir, upper);
if (!err)
ovl_dir_modified(dentry->d_parent, true);
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: