* [PATCH 2/2] btrfs: reduce the width of device counters
2023-09-19 2:21 [PATCH 0/2] btrfs: reduce the width of devices counter Qu Wenruo
2023-09-19 2:21 ` [PATCH 1/2] btrfs: reject a superblock with over 65536 devices Qu Wenruo
@ 2023-09-19 2:21 ` Qu Wenruo
1 sibling, 0 replies; 3+ messages in thread
From: Qu Wenruo @ 2023-09-19 2:21 UTC (permalink / raw)
To: linux-btrfs
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 --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;
--
2.42.0
^ permalink raw reply related [flat|nested] 3+ messages in thread