]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ovl: narrow locking in ovl_create_over_whiteout()
authorNeilBrown <neil@brown.name>
Wed, 16 Jul 2025 00:44:18 +0000 (10:44 +1000)
committerChristian Brauner <brauner@kernel.org>
Fri, 18 Jul 2025 09:10:41 +0000 (11:10 +0200)
Unlock the parents immediately after the rename, and use
ovl_cleanup_unlocked() for cleanup, which takes a separate lock.

This makes way for future changes where locks are taken on individual
dentries rather than the whole directory.

Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: NeilBrown <neil@brown.name>
Link: https://lore.kernel.org/20250716004725.1206467-8-neil@brown.name
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/overlayfs/dir.c

index 540b67f5cdf5dd65a1c02fd75a1c5a3da4814b66..7c92ffb6e3124d10f44daa7c8c22f88e7d17bc9e 100644 (file)
@@ -433,9 +433,7 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
 {
        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 inode *udir = upperdir->d_inode;
        struct dentry *upper;
        struct dentry *newdentry;
        int err;
@@ -506,22 +504,23 @@ static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
 
                err = ovl_do_rename(ofs, workdir, newdentry, upperdir, upper,
                                    RENAME_EXCHANGE);
+               unlock_rename(workdir, upperdir);
                if (err)
-                       goto out_cleanup;
+                       goto out_cleanup_unlocked;
 
-               ovl_cleanup(ofs, wdir, upper);
+               ovl_cleanup_unlocked(ofs, workdir, upper);
        } else {
                err = ovl_do_rename(ofs, workdir, newdentry, upperdir, upper, 0);
+               unlock_rename(workdir, upperdir);
                if (err)
-                       goto out_cleanup;
+                       goto out_cleanup_unlocked;
        }
        ovl_dir_modified(dentry->d_parent, false);
        err = ovl_instantiate(dentry, inode, newdentry, hardlink, NULL);
        if (err) {
-               ovl_cleanup(ofs, udir, newdentry);
+               ovl_cleanup_unlocked(ofs, upperdir, newdentry);
                dput(newdentry);
        }
-       unlock_rename(workdir, upperdir);
 out_dput:
        dput(upper);
 out: