@@ -1821,7 +1821,7 @@ static int btrfs_get_tree_super(struct fs_context *fc)
ret = btrfs_open_devices(fs_devices, mode, &btrfs_fs_type);
if (ret && fs_devices->total_devices == 1)
- btrfs_free_stale_devices(device->devt, NULL);
+ btrfs_free_stale_devices(device->devt, NULL, false);
mutex_unlock(&uuid_mutex);
if (ret)
@@ -515,7 +515,8 @@ btrfs_get_bdev_and_sb(const char *device_path, blk_mode_t flags, void *holder,
* -EBUSY if @devt is a mounted device.
* -ENOENT if @devt does not match any device in the list.
*/
-int btrfs_free_stale_devices(dev_t devt, struct btrfs_device *skip_device)
+int btrfs_free_stale_devices(dev_t devt, struct btrfs_device *skip_device,
+ bool free_stray_single)
{
struct btrfs_fs_devices *fs_devices, *tmp_fs_devices;
struct btrfs_device *device, *tmp_device;
@@ -529,6 +530,12 @@ int btrfs_free_stale_devices(dev_t devt, struct btrfs_device *skip_device)
list_for_each_entry_safe(fs_devices, tmp_fs_devices, &fs_uuids, fs_list) {
mutex_lock(&fs_devices->device_list_mutex);
+
+ if (free_stray_single && fs_devices->total_devices != 1) {
+ mutex_unlock(&fs_devices->device_list_mutex);
+ continue;
+ }
+
list_for_each_entry_safe(device, tmp_device,
&fs_devices->devices, dev_list) {
if (skip_device && skip_device == device)
@@ -1307,7 +1314,7 @@ int btrfs_forget_devices(dev_t devt)
int ret;
mutex_lock(&uuid_mutex);
- ret = btrfs_free_stale_devices(devt, NULL);
+ ret = btrfs_free_stale_devices(devt, NULL, false);
mutex_unlock(&uuid_mutex);
return ret;
@@ -1416,7 +1423,8 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
path, MAJOR(bdev_handle->bdev->bd_dev),
MINOR(bdev_handle->bdev->bd_dev));
- btrfs_free_stale_devices(bdev_handle->bdev->bd_dev, NULL);
+ btrfs_free_stale_devices(bdev_handle->bdev->bd_dev, NULL,
+ false);
device = NULL;
goto free_disk_super;
@@ -1424,7 +1432,7 @@ struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
device = device_list_add(path, disk_super, &new_device_added);
if (!IS_ERR(device) && new_device_added)
- btrfs_free_stale_devices(device->devt, device);
+ btrfs_free_stale_devices(device->devt, device, false);
free_disk_super:
btrfs_release_disk_super(disk_super);
@@ -681,7 +681,8 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
blk_mode_t flags, void *holder);
struct btrfs_device *btrfs_scan_one_device(const char *path, blk_mode_t flags,
bool mount_arg_dev);
-int btrfs_free_stale_devices(dev_t devt, struct btrfs_device *skip_device);
+int btrfs_free_stale_devices(dev_t devt, struct btrfs_device *skip_device,
+ bool free_stray_single);
int btrfs_forget_devices(dev_t devt);
void btrfs_close_devices(struct btrfs_fs_devices *fs_devices);
void btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices);
Refactor the function btrfs_free_stale_devices() to search for devices with a single device and unmounted, freeing it. This a preparation harden the reliance of tempfsid on a stray-free single device, allowing temp fsid activation on a device. Signed-off-by: Anand Jain <anand.jain@oracle.com> --- fs/btrfs/super.c | 2 +- fs/btrfs/volumes.c | 16 ++++++++++++---- fs/btrfs/volumes.h | 3 ++- 3 files changed, 15 insertions(+), 6 deletions(-)