On Fri, Jul 11, 2025 at 1:21 AM NeilBrown <neil@xxxxxxxxxx> wrote: > > In ovl_workdir_create() don't hold the dir lock for the whole time, but > only take it when needed. > > It now gets taken separately for ovl_workdir_cleanup(). A subsequent > patch will move the locking into that function. > > Signed-off-by: NeilBrown <neil@xxxxxxxxxx> > --- > fs/overlayfs/super.c | 16 ++++++++++------ > 1 file changed, 10 insertions(+), 6 deletions(-) > > diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c > index 9cce3251dd83..239ae1946edf 100644 > --- a/fs/overlayfs/super.c > +++ b/fs/overlayfs/super.c > @@ -299,8 +299,8 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs, > int err; > bool retried = false; > > - inode_lock_nested(dir, I_MUTEX_PARENT); > retry: > + inode_lock_nested(dir, I_MUTEX_PARENT); > work = ovl_lookup_upper(ofs, name, ofs->workbasedir, strlen(name)); > > if (!IS_ERR(work)) { > @@ -311,23 +311,27 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs, > > if (work->d_inode) { > err = -EEXIST; > + inode_unlock(dir); > if (retried) > goto out_dput; > > if (persist) > - goto out_unlock; > + goto out; > > retried = true; > + inode_lock_nested(dir, I_MUTEX_PARENT); Feels like this should be parent_lock(ofs->workbasedir, work) and parent_lock(ofs->workbasedir, NULL) in retry: > err = ovl_workdir_cleanup(ofs, dir, mnt, work, 0); > + inode_unlock(dir); > dput(work); > if (err == -EINVAL) { > work = ERR_PTR(err); > - goto out_unlock; > + goto out; > } > goto retry; > } > > work = ovl_do_mkdir(ofs, dir, work, attr.ia_mode); > + inode_unlock(dir); > err = PTR_ERR(work); > if (IS_ERR(work)) > goto out_err; > @@ -365,11 +369,11 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs, > if (err) > goto out_dput; > } else { > + inode_unlock(dir); > err = PTR_ERR(work); > goto out_err; > } > -out_unlock: > - inode_unlock(dir); > +out: > return work; > > out_dput: > @@ -378,7 +382,7 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs, > pr_warn("failed to create directory %s/%s (errno: %i); mounting read-only\n", > ofs->config.workdir, name, -err); > work = NULL; > - goto out_unlock; > + goto out; might as well be return NULL now. Thanks, Amir.