diff options
author | NeilBrown <neil@brown.name> | 2025-07-16 10:44:18 +1000 |
---|---|---|
committer | Christian Brauner <brauner@kernel.org> | 2025-07-18 11:10:41 +0200 |
commit | e460bc4d012ce144376264609309b14b84b693ff (patch) | |
tree | 883308a60c16def2838e682657dffcb3e551c03a | |
parent | 4f622bd9f3e5dd1e882ee8f4194ea1d95dcf752f (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.c | 13 |
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: |