On Fri, 11 Jul 2025, Amir Goldstein wrote: > 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: Agreed. > > > 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. Done. I got rid of the out: label completely. NeilBrown > > Thanks, > Amir. >