summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neil@brown.name>2025-07-16 10:44:18 +1000
committerChristian Brauner <brauner@kernel.org>2025-07-18 11:10:41 +0200
commite460bc4d012ce144376264609309b14b84b693ff (patch)
tree883308a60c16def2838e682657dffcb3e551c03a
parent4f622bd9f3e5dd1e882ee8f4194ea1d95dcf752f (diff)
ovl: narrow locking in ovl_create_over_whiteout()
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>
-rw-r--r--fs/overlayfs/dir.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index 540b67f5cdf5..7c92ffb6e312 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -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: