diff mbox series

[3/4] btrfs: refactor btrfs_free_stale_devices to free single stray device

Message ID a3b28db087e92ef21bf9303efb2e2209a18018f9.1709991203.git.anand.jain@oracle.com (mailing list archive)
State New, archived
Headers show
Series btrfs: enhanced logic for stray single device | expand

Commit Message

Anand Jain March 9, 2024, 1:44 p.m. UTC
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(-)
diff mbox series

Patch

diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 4b73c3a2d7ab..d381abb275d1 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -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)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 7821c152d956..60d848392cd0 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -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);
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 44942b7b36b8..0ac25ccde96e 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -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);