Skip to content

Commit 2ae4db5

Browse files
committed
fs: don't misleadingly warn during thaw operations
The block device may have been frozen before it was claimed by a filesystem. Concurrently another process might try to mount that frozen block device and has temporarily claimed the block device for that purpose causing a concurrent fs_bdev_thaw() to end up here. The mounter is already about to abort mounting because they still saw an elevanted bdev->bd_fsfreeze_count so get_bdev_super() will return NULL in that case. For example, P1 calls dm_suspend() which calls into bdev_freeze() before the block device has been claimed by the filesystem. This brings bdev->bd_fsfreeze_count to 1 and no call into fs_bdev_freeze() is required. Now P2 tries to mount that frozen block device. It claims it and checks bdev->bd_fsfreeze_count. As it's elevated it aborts mounting. In the meantime P3 called dm_resume(). P3 sees that the block device is already claimed by a filesystem and calls into fs_bdev_thaw(). P3 takes a passive reference and realizes that the filesystem isn't ready yet. P3 puts itself to sleep to wait for the filesystem to become ready. P2 now puts the last active reference to the filesystem and marks it as dying. P3 gets woken, sees that the filesystem is dying and get_bdev_super() fails. Fixes: 49ef883 ("bdev: implement freeze and thaw holder operations") Cc: <stable@vger.kernel.org> Reported-by: Theodore Ts'o <tytso@mit.edu> Link: https://lore.kernel.org/r/20240611085210.GA1838544@mit.edu Link: https://lore.kernel.org/r/20240613-lackmantel-einsehen-90f0d727358d@brauner Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 83a7eef commit 2ae4db5

1 file changed

Lines changed: 10 additions & 1 deletion

File tree

fs/super.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1502,8 +1502,17 @@ static int fs_bdev_thaw(struct block_device *bdev)
15021502

15031503
lockdep_assert_held(&bdev->bd_fsfreeze_mutex);
15041504

1505+
/*
1506+
* The block device may have been frozen before it was claimed by a
1507+
* filesystem. Concurrently another process might try to mount that
1508+
* frozen block device and has temporarily claimed the block device for
1509+
* that purpose causing a concurrent fs_bdev_thaw() to end up here. The
1510+
* mounter is already about to abort mounting because they still saw an
1511+
* elevanted bdev->bd_fsfreeze_count so get_bdev_super() will return
1512+
* NULL in that case.
1513+
*/
15051514
sb = get_bdev_super(bdev);
1506-
if (WARN_ON_ONCE(!sb))
1515+
if (!sb)
15071516
return -EINVAL;
15081517

15091518
if (sb->s_op->thaw_super)

0 commit comments

Comments
 (0)