From: NeilBrown Date: Wed, 16 Jul 2025 00:44:27 +0000 (+1000) Subject: ovl: narrow locking on ovl_remove_and_whiteout() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c69566b1d11d781d6b586113126ce1a803bbf8fc;p=thirdparty%2Flinux.git 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 Link: https://lore.kernel.org/20250716004725.1206467-17-neil@brown.name Reviewed-by: Amir Goldstein Signed-off-by: Christian Brauner --- diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index e81be60f11255..340f8679b6e7f 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -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: