Skip to content

Commit 241062a

Browse files
neilbrownbrauner
authored andcommitted
ovl: change ovl_workdir_cleanup() to take dir lock as needed.
Rather than calling ovl_workdir_cleanup() with the dir already locked, change it to take the dir lock only when needed. Also change ovl_workdir_cleanup() to take a dentry for the parent rather than an inode. Signed-off-by: NeilBrown <neil@brown.name> Link: https://lore.kernel.org/20250716004725.1206467-16-neil@brown.name Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent a45ee87 commit 241062a

3 files changed

Lines changed: 15 additions & 29 deletions

File tree

fs/overlayfs/overlayfs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ void ovl_cleanup_whiteouts(struct ovl_fs *ofs, struct dentry *upper,
742742
void ovl_cache_free(struct list_head *list);
743743
void ovl_dir_cache_free(struct inode *inode);
744744
int ovl_check_d_type_supported(const struct path *realpath);
745-
int ovl_workdir_cleanup(struct ovl_fs *ofs, struct inode *dir,
745+
int ovl_workdir_cleanup(struct ovl_fs *ofs, struct dentry *parent,
746746
struct vfsmount *mnt, struct dentry *dentry, int level);
747747
int ovl_indexdir_cleanup(struct ovl_fs *ofs);
748748

fs/overlayfs/readdir.c

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,7 +1096,6 @@ static int ovl_workdir_cleanup_recurse(struct ovl_fs *ofs, const struct path *pa
10961096
int level)
10971097
{
10981098
int err;
1099-
struct inode *dir = path->dentry->d_inode;
11001099
LIST_HEAD(list);
11011100
struct ovl_cache_entry *p;
11021101
struct ovl_readdir_data rdd = {
@@ -1139,14 +1138,9 @@ static int ovl_workdir_cleanup_recurse(struct ovl_fs *ofs, const struct path *pa
11391138
dentry = ovl_lookup_upper_unlocked(ofs, p->name, path->dentry, p->len);
11401139
if (IS_ERR(dentry))
11411140
continue;
1142-
if (dentry->d_inode) {
1143-
err = ovl_parent_lock(path->dentry, dentry);
1144-
if (!err) {
1145-
err = ovl_workdir_cleanup(ofs, dir, path->mnt,
1146-
dentry, level);
1147-
ovl_parent_unlock(path->dentry);
1148-
}
1149-
}
1141+
if (dentry->d_inode)
1142+
err = ovl_workdir_cleanup(ofs, path->dentry, path->mnt,
1143+
dentry, level);
11501144
dput(dentry);
11511145
if (err)
11521146
break;
@@ -1156,24 +1150,25 @@ static int ovl_workdir_cleanup_recurse(struct ovl_fs *ofs, const struct path *pa
11561150
return err;
11571151
}
11581152

1159-
int ovl_workdir_cleanup(struct ovl_fs *ofs, struct inode *dir,
1153+
int ovl_workdir_cleanup(struct ovl_fs *ofs, struct dentry *parent,
11601154
struct vfsmount *mnt, struct dentry *dentry, int level)
11611155
{
11621156
int err;
11631157

1164-
if (!d_is_dir(dentry) || level > 1) {
1165-
return ovl_cleanup(ofs, dir, dentry);
1166-
}
1158+
if (!d_is_dir(dentry) || level > 1)
1159+
return ovl_cleanup_unlocked(ofs, parent, dentry);
11671160

1168-
err = ovl_do_rmdir(ofs, dir, dentry);
1161+
err = ovl_parent_lock(parent, dentry);
1162+
if (err)
1163+
return err;
1164+
err = ovl_do_rmdir(ofs, parent->d_inode, dentry);
1165+
ovl_parent_unlock(parent);
11691166
if (err) {
11701167
struct path path = { .mnt = mnt, .dentry = dentry };
11711168

1172-
inode_unlock(dir);
11731169
err = ovl_workdir_cleanup_recurse(ofs, &path, level + 1);
1174-
inode_lock_nested(dir, I_MUTEX_PARENT);
11751170
if (!err)
1176-
err = ovl_cleanup(ofs, dir, dentry);
1171+
err = ovl_cleanup_unlocked(ofs, parent, dentry);
11771172
}
11781173

11791174
return err;
@@ -1184,7 +1179,6 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs)
11841179
int err;
11851180
struct dentry *indexdir = ofs->workdir;
11861181
struct dentry *index = NULL;
1187-
struct inode *dir = indexdir->d_inode;
11881182
struct path path = { .mnt = ovl_upper_mnt(ofs), .dentry = indexdir };
11891183
LIST_HEAD(list);
11901184
struct ovl_cache_entry *p;
@@ -1213,11 +1207,7 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs)
12131207
}
12141208
/* Cleanup leftover from index create/cleanup attempt */
12151209
if (index->d_name.name[0] == '#') {
1216-
err = ovl_parent_lock(indexdir, index);
1217-
if (!err) {
1218-
err = ovl_workdir_cleanup(ofs, dir, path.mnt, index, 1);
1219-
ovl_parent_unlock(indexdir);
1220-
}
1210+
err = ovl_workdir_cleanup(ofs, indexdir, path.mnt, index, 1);
12211211
if (err)
12221212
break;
12231213
goto next;

fs/overlayfs/super.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,11 +319,7 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs,
319319
return work;
320320

321321
retried = true;
322-
err = ovl_parent_lock(ofs->workbasedir, work);
323-
if (!err) {
324-
err = ovl_workdir_cleanup(ofs, dir, mnt, work, 0);
325-
ovl_parent_unlock(ofs->workbasedir);
326-
}
322+
err = ovl_workdir_cleanup(ofs, ofs->workbasedir, mnt, work, 0);
327323
dput(work);
328324
if (err == -EINVAL)
329325
return ERR_PTR(err);

0 commit comments

Comments
 (0)