btrfs-progs: mkfs: add dev stats and device items

The kernel adds a zeroed btrfs_dev_stats_item for each device on the
first mount. Preempt this by doing it at mkfs time.

Signed-off-by: Mark Harmstone <maharmstone@fb.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Mark Harmstone 2025-02-06 14:32:11 +00:00 committed by David Sterba
parent 7535901b06
commit 80cd98ee59
3 changed files with 52 additions and 1 deletions

View File

@ -831,6 +831,16 @@ static inline u64 btrfs_dev_stats_value(const struct extent_buffer *eb,
return val;
}
static inline void btrfs_set_dev_stats_value(struct extent_buffer *eb,
struct btrfs_dev_stats_item *ptr,
int index, u64 val)
{
write_extent_buffer(eb, &val,
offsetof(struct btrfs_dev_stats_item, values) +
((unsigned long)ptr) + (index * sizeof(u64)),
sizeof(val));
}
/* struct btrfs_ioctl_search_header */
static inline u64 btrfs_search_header_transid(struct btrfs_ioctl_search_header *sh)
{

View File

@ -1135,6 +1135,7 @@ int btrfs_add_device(struct btrfs_trans_handle *trans,
int ret;
struct btrfs_path *path;
struct btrfs_dev_item *dev_item;
struct btrfs_dev_stats_item *dev_stats;
struct extent_buffer *leaf;
struct btrfs_key key;
struct btrfs_root *root = fs_info->chunk_root;
@ -1149,6 +1150,7 @@ int btrfs_add_device(struct btrfs_trans_handle *trans,
if (ret)
goto out;
/* Add DEV_ITEM. */
key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
key.type = BTRFS_DEV_ITEM_KEY;
key.offset = free_devid;
@ -1182,6 +1184,27 @@ int btrfs_add_device(struct btrfs_trans_handle *trans,
BTRFS_UUID_SIZE);
btrfs_mark_buffer_dirty(leaf);
fs_info->fs_devices->total_rw_bytes += device->total_bytes;
btrfs_release_path(path);
/* Add DEV STATS item. */
key.objectid = BTRFS_DEV_STATS_OBJECTID;
key.type = BTRFS_PERSISTENT_ITEM_KEY;
key.offset = free_devid;
ret = btrfs_insert_empty_item(trans, fs_info->dev_root, path, &key,
sizeof(*dev_stats));
if (ret)
goto out;
leaf = path->nodes[0];
dev_stats = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dev_stats_item);
for (int i = 0; i < BTRFS_DEV_STAT_VALUES_MAX; i++)
btrfs_set_dev_stats_value(leaf, dev_stats, i, 0);
btrfs_mark_buffer_dirty(leaf);
ret = 0;
out:

View File

@ -369,6 +369,7 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg)
struct btrfs_chunk *chunk;
struct btrfs_dev_item *dev_item;
struct btrfs_dev_extent *dev_extent;
struct btrfs_dev_stats_item *dev_stats;
enum btrfs_mkfs_block blocks[MKFS_BLOCK_COUNT];
u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
u8 *ptr;
@ -673,8 +674,25 @@ int make_btrfs(int fd, struct btrfs_mkfs_config *cfg)
memset(buf->data + sizeof(struct btrfs_header), 0,
cfg->nodesize - sizeof(struct btrfs_header));
nritems = 0;
itemoff = cfg->leaf_data_size - sizeof(struct btrfs_dev_extent);
itemoff = cfg->leaf_data_size;
/* Add a DEV_STATS item for device 1. */
itemoff -= sizeof(struct btrfs_dev_stats_item);
btrfs_set_disk_key_objectid(&disk_key, BTRFS_DEV_STATS_OBJECTID);
btrfs_set_disk_key_type(&disk_key, BTRFS_PERSISTENT_ITEM_KEY);
btrfs_set_disk_key_offset(&disk_key, 1);
btrfs_set_item_key(buf, &disk_key, nritems);
btrfs_set_item_offset(buf, nritems, itemoff);
btrfs_set_item_size(buf, nritems, sizeof(struct btrfs_dev_stats_item));
dev_stats = btrfs_item_ptr(buf, nritems, struct btrfs_dev_stats_item);
for (i = 0; i < BTRFS_DEV_STAT_VALUES_MAX; i++)
btrfs_set_dev_stats_value(buf, dev_stats, i, 0);
nritems++;
/* Add the DEV_EXTENT item for the system chunk. */
itemoff -= sizeof(struct btrfs_dev_extent);
btrfs_set_disk_key_objectid(&disk_key, 1);
btrfs_set_disk_key_offset(&disk_key, system_group_offset);
btrfs_set_disk_key_type(&disk_key, BTRFS_DEV_EXTENT_KEY);