Anand Jain
aa1af89a66
btrfs: fix lockdep warning while mounting sprout fs
[ Upstream commit c124706900c20dee70f921bb3a90492431561a0a ]
Following test case reproduces lockdep warning.
Test case:
$ mkfs.btrfs -f <dev1>
$ btrfstune -S 1 <dev1>
$ mount <dev1> <mnt>
$ btrfs device add <dev2> <mnt> -f
$ umount <mnt>
$ mount <dev2> <mnt>
$ umount <mnt>
The warning claims a possible ABBA deadlock between the threads
initiated by [#1] btrfs device add and [#0] the mount.
[ 540.743122] WARNING: possible circular locking dependency detected
[ 540.743129] 5.11.0-rc7+ #5 Not tainted
[ 540.743135] ------------------------------------------------------
[ 540.743142] mount/2515 is trying to acquire lock:
[ 540.743149] ffffa0c5544c2ce0 (&fs_devs->device_list_mutex){+.+.}-{4:4}, at: clone_fs_devices+0x6d/0x210 [btrfs]
[ 540.743458] but task is already holding lock:
[ 540.743461] ffffa0c54a7932b8 (btrfs-chunk-00){++++}-{4:4}, at: __btrfs_tree_read_lock+0x32/0x200 [btrfs]
[ 540.743541] which lock already depends on the new lock.
[ 540.743543] the existing dependency chain (in reverse order) is:
[ 540.743546] -> #1 (btrfs-chunk-00){++++}-{4:4}:
[ 540.743566] down_read_nested+0x48/0x2b0
[ 540.743585] __btrfs_tree_read_lock+0x32/0x200 [btrfs]
[ 540.743650] btrfs_read_lock_root_node+0x70/0x200 [btrfs]
[ 540.743733] btrfs_search_slot+0x6c6/0xe00 [btrfs]
[ 540.743785] btrfs_update_device+0x83/0x260 [btrfs]
[ 540.743849] btrfs_finish_chunk_alloc+0x13f/0x660 [btrfs] <--- device_list_mutex
[ 540.743911] btrfs_create_pending_block_groups+0x18d/0x3f0 [btrfs]
[ 540.743982] btrfs_commit_transaction+0x86/0x1260 [btrfs]
[ 540.744037] btrfs_init_new_device+0x1600/0x1dd0 [btrfs]
[ 540.744101] btrfs_ioctl+0x1c77/0x24c0 [btrfs]
[ 540.744166] __x64_sys_ioctl+0xe4/0x140
[ 540.744170] do_syscall_64+0x4b/0x80
[ 540.744174] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 540.744180] -> #0 (&fs_devs->device_list_mutex){+.+.}-{4:4}:
[ 540.744184] __lock_acquire+0x155f/0x2360
[ 540.744188] lock_acquire+0x10b/0x5c0
[ 540.744190] __mutex_lock+0xb1/0xf80
[ 540.744193] mutex_lock_nested+0x27/0x30
[ 540.744196] clone_fs_devices+0x6d/0x210 [btrfs]
[ 540.744270] btrfs_read_chunk_tree+0x3c7/0xbb0 [btrfs]
[ 540.744336] open_ctree+0xf6e/0x2074 [btrfs]
[ 540.744406] btrfs_mount_root.cold.72+0x16/0x127 [btrfs]
[ 540.744472] legacy_get_tree+0x38/0x90
[ 540.744475] vfs_get_tree+0x30/0x140
[ 540.744478] fc_mount+0x16/0x60
[ 540.744482] vfs_kern_mount+0x91/0x100
[ 540.744484] btrfs_mount+0x1e6/0x670 [btrfs]
[ 540.744536] legacy_get_tree+0x38/0x90
[ 540.744537] vfs_get_tree+0x30/0x140
[ 540.744539] path_mount+0x8d8/0x1070
[ 540.744541] do_mount+0x8d/0xc0
[ 540.744543] __x64_sys_mount+0x125/0x160
[ 540.744545] do_syscall_64+0x4b/0x80
[ 540.744547] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 540.744551] other info that might help us debug this:
[ 540.744552] Possible unsafe locking scenario:
[ 540.744553] CPU0 CPU1
[ 540.744554] ---- ----
[ 540.744555] lock(btrfs-chunk-00);
[ 540.744557] lock(&fs_devs->device_list_mutex);
[ 540.744560] lock(btrfs-chunk-00);
[ 540.744562] lock(&fs_devs->device_list_mutex);
[ 540.744564]
*** DEADLOCK ***
[ 540.744565] 3 locks held by mount/2515:
[ 540.744567] #0: ffffa0c56bf7a0e0 (&type->s_umount_key#42/1){+.+.}-{4:4}, at: alloc_super.isra.16+0xdf/0x450
[ 540.744574] #1: ffffffffc05a9628 (uuid_mutex){+.+.}-{4:4}, at: btrfs_read_chunk_tree+0x63/0xbb0 [btrfs]
[ 540.744640] #2: ffffa0c54a7932b8 (btrfs-chunk-00){++++}-{4:4}, at: __btrfs_tree_read_lock+0x32/0x200 [btrfs]
[ 540.744708]
stack backtrace:
[ 540.744712] CPU: 2 PID: 2515 Comm: mount Not tainted 5.11.0-rc7+ #5
But the device_list_mutex in clone_fs_devices() is redundant, as
explained below. Two threads [1] and [2] (below) could lead to
clone_fs_device().
[1]
open_ctree <== mount sprout fs
btrfs_read_chunk_tree()
mutex_lock(&uuid_mutex) <== global lock
read_one_dev()
open_seed_devices()
clone_fs_devices() <== seed fs_devices
mutex_lock(&orig->device_list_mutex) <== seed fs_devices
[2]
btrfs_init_new_device() <== sprouting
mutex_lock(&uuid_mutex); <== global lock
btrfs_prepare_sprout()
lockdep_assert_held(&uuid_mutex)
clone_fs_devices(seed_fs_device) <== seed fs_devices
Both of these threads hold uuid_mutex which is sufficient to protect
getting the seed device(s) freed while we are trying to clone it for
sprouting [2] or mounting a sprout [1] (as above). A mounted seed device
can not free/write/replace because it is read-only. An unmounted seed
device can be freed by btrfs_free_stale_devices(), but it needs
uuid_mutex. So this patch removes the unnecessary device_list_mutex in
clone_fs_devices(). And adds a lockdep_assert_held(&uuid_mutex) in
clone_fs_devices().
Reported-by: Su Yue <l@damenly.su>
Tested-by: Su Yue <l@damenly.su>
Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2021-09-26 14:09:00 +02:00
..
2021-09-08 08:49:01 +02:00
2020-10-24 12:26:05 -07:00
2021-03-04 11:38:37 +01:00
2021-07-28 14:35:41 +02:00
2020-10-16 11:11:22 -07:00
2020-09-18 16:45:50 -04:00
2021-01-06 14:56:52 +01:00
2021-09-26 14:09:00 +02:00
2021-03-30 14:32:07 +02:00
2021-09-26 14:09:00 +02:00
2021-09-18 13:40:32 +02:00
2021-07-14 16:56:48 +02:00
2020-09-18 16:45:50 -04:00
2021-09-08 08:48:59 +02:00
2021-09-15 09:50:37 +02:00
2021-07-14 16:55:59 +02:00
2021-05-26 12:06:55 +02:00
2020-11-25 16:55:02 +01:00
2020-09-18 16:45:50 -04:00
2021-07-14 16:56:53 +02:00
2021-07-14 16:56:52 +02:00
2020-10-24 12:26:05 -07:00
2021-09-08 08:48:59 +02:00
2021-09-18 13:40:16 +02:00
2020-09-18 16:45:50 -04:00
2021-09-18 13:40:15 +02:00
2021-09-22 12:28:00 +02:00
2021-09-18 13:40:30 +02:00
2021-07-31 08:16:12 +02:00
2021-05-19 10:13:10 +02:00
2021-04-14 08:42:06 +02:00
2020-09-18 16:45:50 -04:00
2021-07-28 14:35:46 +02:00
2021-09-18 13:40:29 +02:00
2021-09-15 09:50:25 +02:00
2021-05-19 10:13:19 +02:00
2021-05-11 14:47:36 +02:00
2021-07-20 16:05:40 +02:00
2021-01-27 11:55:29 +01:00
2021-09-18 13:40:30 +02:00
2020-09-18 16:45:50 -04:00
2021-09-18 13:40:13 +02:00
2020-12-30 11:53:45 +01:00
2021-09-18 13:40:33 +02:00
2021-09-26 14:08:57 +02:00
2021-09-18 13:40:38 +02:00
2021-07-14 16:55:38 +02:00
2021-08-04 12:46:40 +02:00
2020-09-22 23:39:45 -04:00
2021-07-20 16:05:48 +02:00
2021-09-18 13:40:35 +02:00
2021-07-28 14:35:42 +02:00
2021-07-14 16:56:12 +02:00
2020-09-18 16:45:50 -04:00
2020-09-18 16:45:50 -04:00
2021-03-04 11:37:53 +01:00
2020-10-16 11:11:22 -07:00
2021-08-12 13:22:19 +02:00
2020-10-24 12:26:05 -07:00
2021-05-19 10:13:10 +02:00
2020-10-02 12:02:30 +02:00
2020-09-18 16:45:50 -04:00
2021-09-08 08:48:59 +02:00
2021-09-15 09:50:27 +02:00
2020-10-24 12:26:05 -07:00
2020-09-10 14:03:31 -07:00
2021-08-18 08:59:18 +02:00
2020-07-21 16:02:41 -07:00
2021-05-14 09:50:34 +02:00
2021-03-25 09:04:05 +01:00
2020-11-10 16:53:07 -08:00
2020-10-16 11:11:21 -07:00
2020-10-29 17:22:59 -05:00
2020-08-24 08:49:13 +10:00
2021-03-17 17:06:35 +01:00
2021-06-03 09:00:45 +02:00
2020-10-18 09:27:09 -07:00
2021-09-26 14:08:56 +02:00
2020-10-14 14:54:45 -07:00
2021-07-14 16:56:13 +02:00
2020-07-29 16:14:27 +02:00
2021-04-14 08:41:58 +02:00
2021-05-11 14:47:12 +02:00
2021-09-08 08:49:00 +02:00
2021-09-15 09:50:27 +02:00
2020-10-17 15:05:30 -06:00
2021-01-30 13:55:18 +01:00
2020-08-23 17:36:59 -05:00
2020-10-13 18:38:27 -07:00
2020-07-29 16:14:27 +02:00
2021-07-14 16:56:31 +02:00
2020-08-23 17:36:59 -05:00
2020-08-04 21:02:38 -04:00
2020-12-30 11:53:49 +01:00
2021-07-31 08:16:11 +02:00
2021-09-22 12:27:54 +02:00
2021-09-18 13:40:06 +02:00
2021-02-13 13:54:56 +01:00
2020-07-31 08:16:01 +02:00
2021-02-17 11:02:21 +01:00
2020-10-05 13:37:04 +02:00
2020-11-22 10:48:22 -08:00
2021-03-20 10:43:44 +01:00
2020-10-23 11:33:41 -07:00
2021-04-14 08:41:58 +02:00
2021-08-26 08:35:57 -04:00
2021-07-14 16:55:59 +02:00
2021-09-03 10:09:28 +02:00
2021-03-17 17:06:13 +01:00
2020-12-30 11:54:02 +01:00
2020-10-23 11:33:41 -07:00
2021-04-21 13:00:54 +02:00
2020-10-15 09:48:49 -07:00
2021-03-25 09:04:16 +01:00
2021-07-20 16:05:59 +02:00
2020-08-23 17:36:59 -05:00
2020-10-24 12:40:18 -07:00
2021-05-11 14:47:33 +02:00
2020-08-27 16:06:47 -04:00
2020-11-10 16:53:11 -08:00
2021-09-18 13:40:17 +02:00
2020-07-31 08:16:01 +02:00
2020-10-13 18:38:27 -07:00