mirror of
https://github.com/kdave/btrfs-progs
synced 2025-02-21 12:26:51 +00:00
btrfs-progs: check: introduce function to check dev used space
Introduce function check_dev_item() to check used space with dev extent items. Signed-off-by: Lu Fengqi <lufq.fnst@cn.fujitsu.com> Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Reviewed-by: Josef Bacik <jbacik@fb.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
d93fde8234
commit
f9ed952b37
65
cmds-check.c
65
cmds-check.c
@ -448,6 +448,7 @@ struct root_item_info {
|
||||
#define CROSSING_STRIPE_BOUNDARY (1 << 4) /* For kernel scrub workaround */
|
||||
#define ITEM_SIZE_MISMATCH (1 << 5) /* Bad item size */
|
||||
#define UNKNOWN_TYPE (1 << 6) /* Unknown type */
|
||||
#define ACCOUNTING_MISMATCH (1 << 7) /* Used space accounting error */
|
||||
|
||||
static void *print_status_check(void *p)
|
||||
{
|
||||
@ -9400,6 +9401,70 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the used space is correct with the dev item
|
||||
*/
|
||||
static int check_dev_item(struct btrfs_fs_info *fs_info,
|
||||
struct extent_buffer *eb, int slot)
|
||||
{
|
||||
struct btrfs_root *dev_root = fs_info->dev_root;
|
||||
struct btrfs_dev_item *dev_item;
|
||||
struct btrfs_path path;
|
||||
struct btrfs_key key;
|
||||
struct btrfs_dev_extent *ptr;
|
||||
u64 dev_id;
|
||||
u64 used;
|
||||
u64 total = 0;
|
||||
int ret;
|
||||
|
||||
dev_item = btrfs_item_ptr(eb, slot, struct btrfs_dev_item);
|
||||
dev_id = btrfs_device_id(eb, dev_item);
|
||||
used = btrfs_device_bytes_used(eb, dev_item);
|
||||
|
||||
key.objectid = dev_id;
|
||||
key.type = BTRFS_DEV_EXTENT_KEY;
|
||||
key.offset = 0;
|
||||
|
||||
btrfs_init_path(&path);
|
||||
ret = btrfs_search_slot(NULL, dev_root, &key, &path, 0, 0);
|
||||
if (ret < 0) {
|
||||
btrfs_item_key_to_cpu(eb, &key, slot);
|
||||
error("cannot find any related dev extent for dev[%llu, %u, %llu]",
|
||||
key.objectid, key.type, key.offset);
|
||||
btrfs_release_path(&path);
|
||||
return REFERENCER_MISSING;
|
||||
}
|
||||
|
||||
/* Iterate dev_extents to calculate the used space of a device */
|
||||
while (1) {
|
||||
btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
|
||||
|
||||
if (key.objectid > dev_id)
|
||||
break;
|
||||
if (key.type != BTRFS_DEV_EXTENT_KEY || key.objectid != dev_id)
|
||||
goto next;
|
||||
|
||||
ptr = btrfs_item_ptr(path.nodes[0], path.slots[0],
|
||||
struct btrfs_dev_extent);
|
||||
total += btrfs_dev_extent_length(path.nodes[0], ptr);
|
||||
next:
|
||||
ret = btrfs_next_item(dev_root, &path);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
btrfs_release_path(&path);
|
||||
|
||||
if (used != total) {
|
||||
btrfs_item_key_to_cpu(eb, &key, slot);
|
||||
error(
|
||||
"Dev extent's total-byte %llu is not equal to bytes-used %llu in dev[%llu, %u, %llu]",
|
||||
total, used, BTRFS_ROOT_TREE_OBJECTID,
|
||||
BTRFS_DEV_EXTENT_KEY, dev_id);
|
||||
return ACCOUNTING_MISMATCH;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btrfs_fsck_reinit_root(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, int overwrite)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user