From 40ce21951aab62b8cdd6d2b852154d6fe9f11163 Mon Sep 17 00:00:00 2001 From: Anand Jain Date: Tue, 29 May 2018 17:23:20 +0800 Subject: [PATCH] btrfs: use device_list_mutex when removing stale devices [ Upstream commit 7bcb8164ad9435068d9bc3b83b8a002c64d63ff6 ] 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 Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- 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 34ac2c7c8b97..6e6b4f2c85ad 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -640,8 +640,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) { @@ -661,16 +664,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); } } }