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. Signed-off-by: NeilBrown <neil@xxxxxxxxxx> --- fs/overlayfs/dir.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index a51a3dc02bf5..2d67704d641e 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -326,9 +326,10 @@ 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); + inode_unlock(udir); err = PTR_ERR(newdentry); if (IS_ERR(newdentry)) - goto out_unlock; + goto out; if (ovl_type_merge(dentry->d_parent) && d_is_dir(newdentry) && !ovl_allow_offline_changes(ofs)) { @@ -340,14 +341,13 @@ 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); +out: return err; out_cleanup: - ovl_cleanup(ofs, udir, newdentry); + ovl_cleanup_unlocked(ofs, upperdir, newdentry); dput(newdentry); - goto out_unlock; + goto out; } static struct dentry *ovl_clear_empty(struct dentry *dentry, -- 2.49.0