diff options
| author | NeilBrown <neil@brown.name> | 2025-07-16 10:44:16 +1000 |
|---|---|---|
| committer | Christian Brauner <brauner@kernel.org> | 2025-07-18 11:10:41 +0200 |
| commit | a07052e07b67add56328b547ce4459878618334d (patch) | |
| tree | 7f14f7ce21d3b797df2ae319f9de25e00c48a0c9 /fs | |
| parent | a735bdf0b78528970f169870ced234dd3a33ea7b (diff) | |
ovl: narrow locking in ovl_create_upper()
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>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/overlayfs/dir.c | 12 |
1 files changed, 5 insertions, 7 deletions
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 373335e420fd..1a146a71993a 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -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, |
