Skip to content

Commit f1a9622

Browse files
oleg-nesterovAl Viro
authored andcommitted
fs/super.c: don't fool lockdep in freeze_super() and thaw_super() paths
sb_wait_write()->percpu_rwsem_release() fools lockdep to avoid the false-positives. Now that xfs was fixed by Dave's commit dbad7c9 ("xfs: stop holding ILOCK over filldir callbacks") we can remove it and change freeze_super() and thaw_super() to run with s_writers.rw_sem locks held; we add two trivial helpers for that, lockdep_sb_freeze_release() and lockdep_sb_freeze_acquire(). xfstests-dev/check `grep -il freeze tests/*/???` does not trigger any warning from lockdep. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 89f39af commit f1a9622

1 file changed

Lines changed: 25 additions & 12 deletions

File tree

fs/super.c

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,25 +1269,34 @@ EXPORT_SYMBOL(__sb_start_write);
12691269
static void sb_wait_write(struct super_block *sb, int level)
12701270
{
12711271
percpu_down_write(sb->s_writers.rw_sem + level-1);
1272-
/*
1273-
* We are going to return to userspace and forget about this lock, the
1274-
* ownership goes to the caller of thaw_super() which does unlock.
1275-
*
1276-
* FIXME: we should do this before return from freeze_super() after we
1277-
* called sync_filesystem(sb) and s_op->freeze_fs(sb), and thaw_super()
1278-
* should re-acquire these locks before s_op->unfreeze_fs(sb). However
1279-
* this leads to lockdep false-positives, so currently we do the early
1280-
* release right after acquire.
1281-
*/
1282-
percpu_rwsem_release(sb->s_writers.rw_sem + level-1, 0, _THIS_IP_);
12831272
}
12841273

1285-
static void sb_freeze_unlock(struct super_block *sb)
1274+
/*
1275+
* We are going to return to userspace and forget about these locks, the
1276+
* ownership goes to the caller of thaw_super() which does unlock().
1277+
*/
1278+
static void lockdep_sb_freeze_release(struct super_block *sb)
1279+
{
1280+
int level;
1281+
1282+
for (level = SB_FREEZE_LEVELS - 1; level >= 0; level--)
1283+
percpu_rwsem_release(sb->s_writers.rw_sem + level, 0, _THIS_IP_);
1284+
}
1285+
1286+
/*
1287+
* Tell lockdep we are holding these locks before we call ->unfreeze_fs(sb).
1288+
*/
1289+
static void lockdep_sb_freeze_acquire(struct super_block *sb)
12861290
{
12871291
int level;
12881292

12891293
for (level = 0; level < SB_FREEZE_LEVELS; ++level)
12901294
percpu_rwsem_acquire(sb->s_writers.rw_sem + level, 0, _THIS_IP_);
1295+
}
1296+
1297+
static void sb_freeze_unlock(struct super_block *sb)
1298+
{
1299+
int level;
12911300

12921301
for (level = SB_FREEZE_LEVELS - 1; level >= 0; level--)
12931302
percpu_up_write(sb->s_writers.rw_sem + level);
@@ -1383,6 +1392,7 @@ int freeze_super(struct super_block *sb)
13831392
* when frozen is set to SB_FREEZE_COMPLETE, and for thaw_super().
13841393
*/
13851394
sb->s_writers.frozen = SB_FREEZE_COMPLETE;
1395+
lockdep_sb_freeze_release(sb);
13861396
up_write(&sb->s_umount);
13871397
return 0;
13881398
}
@@ -1409,11 +1419,14 @@ int thaw_super(struct super_block *sb)
14091419
goto out;
14101420
}
14111421

1422+
lockdep_sb_freeze_acquire(sb);
1423+
14121424
if (sb->s_op->unfreeze_fs) {
14131425
error = sb->s_op->unfreeze_fs(sb);
14141426
if (error) {
14151427
printk(KERN_ERR
14161428
"VFS:Filesystem thaw failed\n");
1429+
lockdep_sb_freeze_release(sb);
14171430
up_write(&sb->s_umount);
14181431
return error;
14191432
}

0 commit comments

Comments
 (0)