summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neil@brown.name>2025-07-16 10:44:17 +1000
committerChristian Brauner <brauner@kernel.org>2025-07-18 11:10:41 +0200
commit4f622bd9f3e5dd1e882ee8f4194ea1d95dcf752f (patch)
tree6a242d86efae931773ff95c5a00bee5a74a93391
parenta07052e07b67add56328b547ce4459878618334d (diff)
downloadlinux-4f622bd9f3e5dd1e882ee8f4194ea1d95dcf752f.tar.gz
linux-4f622bd9f3e5dd1e882ee8f4194ea1d95dcf752f.zip
ovl: narrow locking in ovl_clear_empty()
Drop the locks immediately after rename, and use a separate lock for cleanup. This makes way for future changes where locks are taken on individual dentries rather than the whole directory. Note that ovl_cleanup_whiteouts() operates on "upper", a child of "upperdir" and does not require upperdir or workdir to be locked. Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: NeilBrown <neil@brown.name> Link: https://lore.kernel.org/20250716004725.1206467-7-neil@brown.name Signed-off-by: Christian Brauner <brauner@kernel.org>
-rw-r--r--fs/overlayfs/dir.c7
1 files changed, 3 insertions, 4 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index 1a146a71993a..540b67f5cdf5 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -353,7 +353,6 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry,
{
struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
struct dentry *workdir = ovl_workdir(dentry);
- struct inode *wdir = workdir->d_inode;
struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent);
struct path upperpath;
struct dentry *upper;
@@ -399,12 +398,12 @@ static struct dentry *ovl_clear_empty(struct dentry *dentry,
goto out_cleanup;
err = ovl_do_rename(ofs, workdir, opaquedir, upperdir, upper, RENAME_EXCHANGE);
+ unlock_rename(workdir, upperdir);
if (err)
- goto out_cleanup;
+ goto out_cleanup_unlocked;
ovl_cleanup_whiteouts(ofs, upper, list);
- ovl_cleanup(ofs, wdir, upper);
- unlock_rename(workdir, upperdir);
+ ovl_cleanup_unlocked(ofs, workdir, upper);
/* dentry's upper doesn't match now, get rid of it */
d_drop(dentry);