From 7bcb8164ad9435068d9bc3b83b8a002c64d63ff6 Mon Sep 17 00:00:00 2001 From: Anand Jain Date: Tue, 29 May 2018 17:23:20 +0800 Subject: btrfs: use device_list_mutex when removing stale devices btrfs_free_stale_devices() finds a stale (not opened) device matching path in the fs_uuid list. We are already under uuid_mutex so when we check for each fs_devices, hold the device_list_mutex too. Signed-off-by: Anand Jain Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/volumes.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index f4ce081bbe46..6a8f1e2c116f 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -637,8 +637,11 @@ static void btrfs_free_stale_devices(const char *path, struct btrfs_device *device, *tmp_device; list_for_each_entry_safe(fs_devices, tmp_fs_devices, &fs_uuids, fs_list) { - if (fs_devices->opened) + mutex_lock(&fs_devices->device_list_mutex); + if (fs_devices->opened) { + mutex_unlock(&fs_devices->device_list_mutex); continue; + } list_for_each_entry_safe(device, tmp_device, &fs_devices->devices, dev_list) { @@ -658,16 +661,18 @@ static void btrfs_free_stale_devices(const char *path, continue; /* delete the stale device */ - if (fs_devices->num_devices == 1) { - btrfs_sysfs_remove_fsid(fs_devices); - list_del(&fs_devices->fs_list); - free_fs_devices(fs_devices); + fs_devices->num_devices--; + list_del(&device->dev_list); + btrfs_free_device(device); + + if (fs_devices->num_devices == 0) break; - } else { - fs_devices->num_devices--; - list_del(&device->dev_list); - btrfs_free_device(device); - } + } + mutex_unlock(&fs_devices->device_list_mutex); + if (fs_devices->num_devices == 0) { + btrfs_sysfs_remove_fsid(fs_devices); + list_del(&fs_devices->fs_list); + free_fs_devices(fs_devices); } } } -- cgit v1.2.3