Skip to content

Commit d56c6fe

Browse files
neilbrownbrauner
authored andcommitted
ovl: narrow locking in ovl_indexdir_cleanup()
Instead of taking the directory lock for the whole cleanup, only take it when needed. Signed-off-by: NeilBrown <neil@brown.name> Link: https://lore.kernel.org/20250716004725.1206467-14-neil@brown.name Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 61eb7fe commit d56c6fe

1 file changed

Lines changed: 13 additions & 7 deletions

File tree

fs/overlayfs/readdir.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,23 +1194,26 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs)
11941194
if (err)
11951195
goto out;
11961196

1197-
inode_lock_nested(dir, I_MUTEX_PARENT);
11981197
list_for_each_entry(p, &list, l_node) {
11991198
if (p->name[0] == '.') {
12001199
if (p->len == 1)
12011200
continue;
12021201
if (p->len == 2 && p->name[1] == '.')
12031202
continue;
12041203
}
1205-
index = ovl_lookup_upper(ofs, p->name, indexdir, p->len);
1204+
index = ovl_lookup_upper_unlocked(ofs, p->name, indexdir, p->len);
12061205
if (IS_ERR(index)) {
12071206
err = PTR_ERR(index);
12081207
index = NULL;
12091208
break;
12101209
}
12111210
/* Cleanup leftover from index create/cleanup attempt */
12121211
if (index->d_name.name[0] == '#') {
1213-
err = ovl_workdir_cleanup(ofs, dir, path.mnt, index, 1);
1212+
err = ovl_parent_lock(indexdir, index);
1213+
if (!err) {
1214+
err = ovl_workdir_cleanup(ofs, dir, path.mnt, index, 1);
1215+
ovl_parent_unlock(indexdir);
1216+
}
12141217
if (err)
12151218
break;
12161219
goto next;
@@ -1220,7 +1223,7 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs)
12201223
goto next;
12211224
} else if (err == -ESTALE) {
12221225
/* Cleanup stale index entries */
1223-
err = ovl_cleanup(ofs, dir, index);
1226+
err = ovl_cleanup_unlocked(ofs, indexdir, index);
12241227
} else if (err != -ENOENT) {
12251228
/*
12261229
* Abort mount to avoid corrupting the index if
@@ -1233,10 +1236,14 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs)
12331236
* Whiteout orphan index to block future open by
12341237
* handle after overlay nlink dropped to zero.
12351238
*/
1236-
err = ovl_cleanup_and_whiteout(ofs, indexdir, index);
1239+
err = ovl_parent_lock(indexdir, index);
1240+
if (!err) {
1241+
err = ovl_cleanup_and_whiteout(ofs, indexdir, index);
1242+
ovl_parent_unlock(indexdir);
1243+
}
12371244
} else {
12381245
/* Cleanup orphan index entries */
1239-
err = ovl_cleanup(ofs, dir, index);
1246+
err = ovl_cleanup_unlocked(ofs, indexdir, index);
12401247
}
12411248

12421249
if (err)
@@ -1247,7 +1254,6 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs)
12471254
index = NULL;
12481255
}
12491256
dput(index);
1250-
inode_unlock(dir);
12511257
out:
12521258
ovl_cache_free(&list);
12531259
if (err)

0 commit comments

Comments
 (0)