Commit 4681dbcf authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba
Browse files

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: default avatarBoris Burkov <boris@bur.io>
Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 8ecf596e
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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)))
+2 −2
Original line number Diff line number Diff line
@@ -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++;
+7 −6
Original line number Diff line number Diff line
@@ -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;