All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] btrfs: fix rw device counting in __btrfs_free_extra_devids
@ 2021-07-27  7:13 ` Desmond Cheong Zhi Xi
  0 siblings, 0 replies; 28+ messages in thread
From: Desmond Cheong Zhi Xi @ 2021-07-27  7:13 UTC (permalink / raw)
  To: clm, josef, dsterba
  Cc: Desmond Cheong Zhi Xi, anand.jain, linux-btrfs, linux-kernel,
	skhan, gregkh, linux-kernel-mentees, syzbot+a70e2ad0879f160b9217

When removing a writeable device in __btrfs_free_extra_devids, the rw
device count should be decremented.

This error was caught by Syzbot which reported a warning in
close_fs_devices because fs_devices->rw_devices was not 0 after
closing all devices. Here is the call trace that was observed:

  btrfs_mount_root():
    btrfs_scan_one_device():
      device_list_add();   <---------------- device added
    btrfs_open_devices():
      open_fs_devices():
        btrfs_open_one_device();   <-------- writable device opened,
	                                     rw device count ++
    btrfs_fill_super():
      open_ctree():
        btrfs_free_extra_devids():
	  __btrfs_free_extra_devids();  <--- writable device removed,
	                              rw device count not decremented
	  fail_tree_roots:
	    btrfs_close_devices():
	      close_fs_devices();   <------- rw device count off by 1

As a note, prior to commit cf89af146b7e ("btrfs: dev-replace: fail
mount if we don't have replace item with target device"), rw_devices
was decremented on removing a writable device in
__btrfs_free_extra_devids only if the BTRFS_DEV_STATE_REPLACE_TGT bit
was not set for the device. However, this check does not need to be
reinstated as it is now redundant and incorrect.

In __btrfs_free_extra_devids, we skip removing the device if it is the
target for replacement. This is done by checking whether device->devid
== BTRFS_DEV_REPLACE_DEVID. Since BTRFS_DEV_STATE_REPLACE_TGT is set
only on the device with devid BTRFS_DEV_REPLACE_DEVID, no devices
should have the BTRFS_DEV_STATE_REPLACE_TGT bit set after the check,
and so it's redundant to test for that bit.

Additionally, following commit 82372bc816d7 ("Btrfs: make
the logic of source device removing more clear"), rw_devices is
incremented whenever a writeable device is added to the alloc
list (including the target device in btrfs_dev_replace_finishing), so
all removals of writable devices from the alloc list should also be
accompanied by a decrement to rw_devices.

Fixes: cf89af146b7e ("btrfs: dev-replace: fail mount if we don't have replace item with target device")
Reported-by: syzbot+a70e2ad0879f160b9217@syzkaller.appspotmail.com
Tested-by: syzbot+a70e2ad0879f160b9217@syzkaller.appspotmail.com
Signed-off-by: Desmond Cheong Zhi Xi <desmondcheongzx@gmail.com>
Reviewed-by: Anand Jain <anand.jain@oracle.com>
---
 fs/btrfs/volumes.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 807502cd6510..916c25371658 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -1078,6 +1078,7 @@ static void __btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices,
 		if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) {
 			list_del_init(&device->dev_alloc_list);
 			clear_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state);
+			fs_devices->rw_devices--;
 		}
 		list_del_init(&device->dev_list);
 		fs_devices->num_devices--;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2021-08-20 17:54 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-27  7:13 [PATCH v2] btrfs: fix rw device counting in __btrfs_free_extra_devids Desmond Cheong Zhi Xi
2021-07-27  7:13 ` Desmond Cheong Zhi Xi
2021-07-28 12:58 ` David Sterba
2021-07-28 12:58   ` David Sterba
2021-08-12 10:38 ` David Sterba
2021-08-12 10:38   ` David Sterba
2021-08-12 15:43   ` Desmond Cheong Zhi Xi
2021-08-12 15:43     ` Desmond Cheong Zhi Xi
2021-08-12 15:50     ` David Sterba
2021-08-12 15:50       ` David Sterba
2021-08-12 17:31       ` Desmond Cheong Zhi Xi
2021-08-12 17:31         ` Desmond Cheong Zhi Xi
2021-08-13  8:51         ` David Sterba
2021-08-13  8:51           ` David Sterba
2021-08-13  9:57           ` Desmond Cheong Zhi Xi
2021-08-13  9:57             ` Desmond Cheong Zhi Xi
2021-08-13 10:30             ` David Sterba
2021-08-13 10:30               ` David Sterba
2021-08-19 17:11               ` Desmond Cheong Zhi Xi
2021-08-19 17:11                 ` Desmond Cheong Zhi Xi
2021-08-19 17:34                 ` David Sterba
2021-08-19 17:34                   ` David Sterba
2021-08-20  3:09                   ` Desmond Cheong Zhi Xi
2021-08-20  3:09                     ` Desmond Cheong Zhi Xi
2021-08-20 10:58                     ` David Sterba
2021-08-20 10:58                       ` David Sterba
2021-08-20 17:53                       ` Desmond Cheong Zhi Xi
2021-08-20 17:53                         ` Desmond Cheong Zhi Xi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.