]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ovl: narrow locking in ovl_create_upper()
authorNeilBrown <neil@brown.name>
Wed, 16 Jul 2025 00:44:16 +0000 (10:44 +1000)
committerChristian Brauner <brauner@kernel.org>
Fri, 18 Jul 2025 09:10:41 +0000 (11:10 +0200)
Drop the directory lock immediately after the ovl_create_real() call and
take a separate lock later for cleanup in ovl_cleanup_unlocked() - if
needed.

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-6-neil@brown.name
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/overlayfs/dir.c

index 373335e420fd6770e90513929e361cdf7f656652..1a146a71993a645bd29090c531c3d4c463bfb6bd 100644 (file)
@@ -326,9 +326,9 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
                                    ovl_lookup_upper(ofs, dentry->d_name.name,
                                                     upperdir, dentry->d_name.len),
                                    attr);
-       err = PTR_ERR(newdentry);
+       inode_unlock(udir);
        if (IS_ERR(newdentry))
-               goto out_unlock;
+               return PTR_ERR(newdentry);
 
        if (ovl_type_merge(dentry->d_parent) && d_is_dir(newdentry) &&
            !ovl_allow_offline_changes(ofs)) {
@@ -340,14 +340,12 @@ static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
        err = ovl_instantiate(dentry, inode, newdentry, !!attr->hardlink, NULL);
        if (err)
                goto out_cleanup;
-out_unlock:
-       inode_unlock(udir);
-       return err;
+       return 0;
 
 out_cleanup:
-       ovl_cleanup(ofs, udir, newdentry);
+       ovl_cleanup_unlocked(ofs, upperdir, newdentry);
        dput(newdentry);
-       goto out_unlock;
+       return err;
 }
 
 static struct dentry *ovl_clear_empty(struct dentry *dentry,