Skip to content

Commit e735e86

Browse files
committed
btrfs: fix btrfs_free_stale_devices() with needed locks
btrfs_free_stale_devices() finds the stale (not opened) matching device path in the fs_uuid list. We are already under uuid_mutex so when we check for each fs_devices, hold the respective device_list_mutex. Signed-off-by: Anand Jain <anand.jain@oracle.com>
1 parent bdc6cc8 commit e735e86

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed

fs/btrfs/volumes.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -639,8 +639,11 @@ static void btrfs_free_stale_devices(const char *path,
639639
list_for_each_entry_safe(fs_devices, tmp_fs_devices, &fs_uuids,
640640
fs_list) {
641641

642-
if (fs_devices->opened)
642+
mutex_lock(&fs_devices->device_list_mutex);
643+
if (fs_devices->opened) {
644+
mutex_unlock(&fs_devices->device_list_mutex);
643645
continue;
646+
}
644647

645648
list_for_each_entry_safe(device, tmp_device,
646649
&fs_devices->devices, dev_list) {
@@ -660,16 +663,18 @@ static void btrfs_free_stale_devices(const char *path,
660663
continue;
661664

662665
/* delete the stale device */
663-
if (fs_devices->num_devices == 1) {
664-
btrfs_sysfs_remove_fsid(fs_devices);
665-
list_del(&fs_devices->fs_list);
666-
free_fs_devices(fs_devices);
666+
fs_devices->num_devices--;
667+
list_del(&device->dev_list);
668+
btrfs_free_device(device);
669+
670+
if (fs_devices->num_devices == 0)
667671
break;
668-
} else {
669-
fs_devices->num_devices--;
670-
list_del(&device->dev_list);
671-
btrfs_free_device(device);
672-
}
672+
}
673+
mutex_unlock(&fs_devices->device_list_mutex);
674+
if (fs_devices->num_devices == 0) {
675+
btrfs_sysfs_remove_fsid(fs_devices);
676+
list_del(&fs_devices->fs_list);
677+
free_fs_devices(fs_devices);
673678
}
674679
}
675680
}

0 commit comments

Comments
 (0)