btrfs: shrink the size of btrfs_device

There are two main causes of holes inside btrfs_device:

- The single bytes member of last_flush_error
  Not only it's a single byte member, but we never really care about the
  exact error number.

- The @devt member
  Which is placed between two u64 members.

Shrink the size of btrfs_device by:

- Use a single bit flag for flush error
  Use BTRFS_DEV_STATE_FLUSH_FAILED so that we no longer need that
  dedicated member.

- Move @devt to the hole after dev_stat_values[]

This reduces the size of btrfs_device from 528 to exact 512 bytes for
x86_64.

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Qu Wenruo 2026-01-10 10:08:28 +10:30 committed by David Sterba
parent 8ecf596ed8
commit 4681dbcfdc
3 changed files with 12 additions and 11 deletions

View File

@ -3834,7 +3834,7 @@ static void write_dev_flush(struct btrfs_device *device)
{
struct bio *bio = &device->flush_bio;
device->last_flush_error = BLK_STS_OK;
clear_bit(BTRFS_DEV_STATE_FLUSH_FAILED, &device->dev_state);
bio_init(bio, device->bdev, NULL, 0,
REQ_OP_WRITE | REQ_SYNC | REQ_PREFLUSH);
@ -3859,7 +3859,7 @@ static bool wait_dev_flush(struct btrfs_device *device)
wait_for_completion_io(&device->flush_wait);
if (bio->bi_status) {
device->last_flush_error = bio->bi_status;
set_bit(BTRFS_DEV_STATE_FLUSH_FAILED, &device->dev_state);
btrfs_dev_stat_inc_and_print(device, BTRFS_DEV_STAT_FLUSH_ERRS);
return true;
}
@ -3909,7 +3909,7 @@ static int barrier_all_devices(struct btrfs_fs_info *info)
}
/*
* Checks last_flush_error of disks in order to determine the device
* Checks flush failure of disks in order to determine the device
* state.
*/
if (unlikely(errors_wait && !btrfs_check_rw_degradable(info, NULL)))

View File

@ -1169,7 +1169,7 @@ static void btrfs_close_one_device(struct btrfs_device *device)
* any transaction and set the error state, guaranteeing no commits of
* unsafe super blocks.
*/
device->last_flush_error = 0;
clear_bit(BTRFS_DEV_STATE_FLUSH_FAILED, &device->dev_state);
/* Verify the device is back in a pristine state */
WARN_ON(test_bit(BTRFS_DEV_STATE_FLUSH_SENT, &device->dev_state));
@ -7375,7 +7375,7 @@ bool btrfs_check_rw_degradable(struct btrfs_fs_info *fs_info,
if (!dev || !dev->bdev ||
test_bit(BTRFS_DEV_STATE_MISSING, &dev->dev_state) ||
dev->last_flush_error)
test_bit(BTRFS_DEV_STATE_FLUSH_FAILED, &dev->dev_state))
missing++;
else if (failing_dev && failing_dev == dev)
missing++;

View File

@ -99,6 +99,7 @@ enum btrfs_raid_types {
#define BTRFS_DEV_STATE_REPLACE_TGT (3)
#define BTRFS_DEV_STATE_FLUSH_SENT (4)
#define BTRFS_DEV_STATE_NO_READA (5)
#define BTRFS_DEV_STATE_FLUSH_FAILED (6)
/* Set when the device item is found in chunk tree, used to catch unexpected registered device. */
#define BTRFS_DEV_STATE_ITEM_FOUND (7)
@ -125,13 +126,7 @@ struct btrfs_device {
struct btrfs_zoned_device_info *zone_info;
/*
* Device's major-minor number. Must be set even if the device is not
* opened (bdev == NULL), unless the device is missing.
*/
dev_t devt;
unsigned long dev_state;
blk_status_t last_flush_error;
#ifdef __BTRFS_NEED_DEVICE_DATA_ORDERED
seqcount_t data_seqcount;
@ -195,6 +190,12 @@ struct btrfs_device {
atomic_t dev_stats_ccnt;
atomic_t dev_stat_values[BTRFS_DEV_STAT_VALUES_MAX];
/*
* Device's major-minor number. Must be set even if the device is not
* opened (bdev == NULL), unless the device is missing.
*/
dev_t devt;
struct extent_io_tree alloc_state;
struct completion kobj_unregister;