lkml.org 
[lkml]   [2021]   [Jul]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    SubjectRe: [PATCH] btrfs: fix rw device counting in __btrfs_free_extra_devids
    From
    Date


    On 15/07/2021 18:34, Desmond Cheong Zhi Xi wrote:
    > Syzbot reports a warning in close_fs_devices that happens because
    > fs_devices->rw_devices is not 0 after calling btrfs_close_one_device
    > on each device.
    >
    > This happens when a writeable device is removed in
    > __btrfs_free_extra_devids, but the rw device count is not decremented
    > accordingly. So when close_fs_devices is called, the removed device is
    > still counted and we get an off by 1 error.
    >
    > Here is one 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(); <-------- rw device count ++
    > btrfs_fill_super():
    > open_ctree():
    > btrfs_free_extra_devids():
    > __btrfs_free_extra_devids(); <--- device removed
    > fail_tree_roots:
    > btrfs_close_devices():
    > close_fs_devices(); <------- rw device count off by 1
    >
    > 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>
    > ---
    > 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--;
    >

    Thanks for the fix.

    Looks good.

    Reviewed-by: Anand Jain <anand.jain@oracle.com>

    \
     
     \ /
      Last update: 2021-07-15 13:25    [W:2.477 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site