]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ovl: narrow locking in ovl_clear_empty()
authorNeilBrown <neil@brown.name>
Wed, 16 Jul 2025 00:44:17 +0000 (10:44 +1000)
committerChristian Brauner <brauner@kernel.org>
Fri, 18 Jul 2025 09:10:41 +0000 (11:10 +0200)
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>
fs/overlayfs/dir.c

index 1a146a71993a645bd29090c531c3d4c463bfb6bd..540b67f5cdf5dd65a1c02fd75a1c5a3da4814b66 100644 (file)
@@ -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);