diff mbox series

[2/2] btrfs: reduce the width of device counters

Message ID 1cf7d5f66d1fb9caabc8ccadb4a4c3be02df0c8b.1695089790.git.wqu@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: reduce the width of devices counter | expand

Commit Message

Qu Wenruo Sept. 19, 2023, 2:21 a.m. UTC
Since we will reject the super block if its num_devices is beyond
U16_MAX, there is no need to go u64 to count the devices.

We can shrink the width of the following members:

- num_devices
- open_devices
- rw_devices
- missing_devices
- total_devices

And for the ioctls which will add a new device, always make sure the
existing num_devices (the real total number of devices, including
missing and replace-source) would never go beyond U16_MAX.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/dev-replace.c |  9 +++++++++
 fs/btrfs/volumes.c     | 11 ++++++++++-
 fs/btrfs/volumes.h     | 12 ++++++------
 3 files changed, 25 insertions(+), 7 deletions(-)
diff mbox series

Patch

diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index d3998cad62c2..1a7a8caf1e51 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -250,6 +250,15 @@  static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
 	u64 devid = BTRFS_DEV_REPLACE_DEVID;
 	int ret = 0;
 
+	mutex_lock(&fs_devices->device_list_mutex);
+	if (unlikely(fs_devices->num_devices >= U16_MAX)) {
+		mutex_unlock(&fs_devices->device_list_mutex);
+		btrfs_err(fs_info,
+			  "too many devices, has %u devices, up limit is %u",
+			  fs_devices->num_devices, U16_MAX);
+		return -EINVAL;
+	}
+	mutex_unlock(&fs_devices->device_list_mutex);
 	*device_out = NULL;
 	if (srcdev->fs_devices->seeding) {
 		btrfs_err(fs_info, "the filesystem is a seed filesystem!");
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 2f05d38980ce..96bfa86d7371 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2652,6 +2652,15 @@  int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
 	if (sb_rdonly(sb) && !fs_devices->seeding)
 		return -EROFS;
 
+	mutex_lock(&fs_info->chunk_mutex);
+	if (unlikely(fs_devices->num_devices >= U16_MAX)) {
+		btrfs_err(fs_info, "too many devices, has %u devices, up limit is %u",
+			  fs_devices->num_devices, U16_MAX);
+		mutex_unlock(&fs_info->chunk_mutex);
+		return -EINVAL;
+	}
+	mutex_unlock(&fs_info->chunk_mutex);
+
 	bdev = blkdev_get_by_path(device_path, BLK_OPEN_WRITE,
 				  fs_info->bdev_holder, NULL);
 	if (IS_ERR(bdev))
@@ -5263,7 +5272,7 @@  static int gather_device_info(struct btrfs_fs_devices *fs_devices,
 		}
 
 		if (ndevs == fs_devices->rw_devices) {
-			WARN(1, "%s: found more than %llu devices\n",
+			WARN(1, "%s: found more than %u devices\n",
 			     __func__, fs_devices->rw_devices);
 			break;
 		}
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index b513b2846793..045e9eadd025 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -308,28 +308,28 @@  struct btrfs_fs_devices {
 	 * Number of devices under this fsid including missing and
 	 * replace-target device and excludes seed devices.
 	 */
-	u64 num_devices;
+	u16 num_devices;
 
 	/*
 	 * The number of devices that successfully opened, including
 	 * replace-target, excludes seed devices.
 	 */
-	u64 open_devices;
+	u16 open_devices;
 
 	/* The number of devices that are under the chunk allocation list. */
-	u64 rw_devices;
+	u16 rw_devices;
 
 	/* Count of missing devices under this fsid excluding seed device. */
-	u64 missing_devices;
-	u64 total_rw_bytes;
+	u16 missing_devices;
 
 	/*
 	 * Count of devices from btrfs_super_block::num_devices for this fsid,
 	 * which includes the seed device, excludes the transient replace-target
 	 * device.
 	 */
-	u64 total_devices;
+	u16 total_devices;
 
+	u64 total_rw_bytes;
 	/* Highest generation number of seen devices */
 	u64 latest_generation;