mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 15:41:52 +02:00
ovl: narrow locking in ovl_workdir_create()
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@brown.name> Link: https://lore.kernel.org/20250716004725.1206467-13-neil@brown.name Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
8290fb412d
commit
61eb7fec9e
|
|
@ -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,28 @@ 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;
|
||||
return work;
|
||||
|
||||
retried = true;
|
||||
err = ovl_workdir_cleanup(ofs, dir, mnt, work, 0);
|
||||
dput(work);
|
||||
if (err == -EINVAL) {
|
||||
work = ERR_PTR(err);
|
||||
goto out_unlock;
|
||||
err = ovl_parent_lock(ofs->workbasedir, work);
|
||||
if (!err) {
|
||||
err = ovl_workdir_cleanup(ofs, dir, mnt, work, 0);
|
||||
ovl_parent_unlock(ofs->workbasedir);
|
||||
}
|
||||
dput(work);
|
||||
if (err == -EINVAL)
|
||||
return ERR_PTR(err);
|
||||
|
||||
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 +370,10 @@ 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);
|
||||
return work;
|
||||
|
||||
out_dput:
|
||||
|
|
@ -377,8 +381,7 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs,
|
|||
out_err:
|
||||
pr_warn("failed to create directory %s/%s (errno: %i); mounting read-only\n",
|
||||
ofs->config.workdir, name, -err);
|
||||
work = NULL;
|
||||
goto out_unlock;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ovl_check_namelen(const struct path *path, struct ovl_fs *ofs,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user