mirror of
https://github.com/kdave/btrfs-progs
synced 2025-01-21 05:00:44 +00:00
btrfs-progs: check: introduce function to check fs root
Introduce a new function check_fs_root_v2() to check fs root, and call check_inode_item to check the items in the tree. Signed-off-by: Lu Fengqi <lufq.fnst@cn.fujitsu.com> Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
b1d1f627ce
commit
262425b650
76
cmds-check.c
76
cmds-check.c
@ -3840,6 +3840,7 @@ out:
|
||||
#define NBYTES_ERROR (1<<11) /* INODE_ITEM nbytes count error */
|
||||
#define ISIZE_ERROR (1<<12) /* INODE_ITEM size count error */
|
||||
#define ORPHAN_ITEM (1<<13) /* INODE_ITEM no reference */
|
||||
#define NO_INODE_ITEM (1<<14) /* no inode_item */
|
||||
#define LAST_ITEM (1<<15) /* Complete this tree traversal */
|
||||
|
||||
/*
|
||||
@ -4658,6 +4659,81 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate all item on the tree and call check_inode_item() to check.
|
||||
*
|
||||
* @root: the root of the tree to be checked.
|
||||
* @ext_ref: the EXTENDED_IREF feature
|
||||
*
|
||||
* Return 0 if no error found.
|
||||
* Return <0 for error.
|
||||
* All internal error bitmap will be converted to -EIO, to avoid
|
||||
* mixing negative and postive return value.
|
||||
*/
|
||||
static int check_fs_root_v2(struct btrfs_root *root, unsigned int ext_ref)
|
||||
{
|
||||
struct btrfs_path *path;
|
||||
struct btrfs_key key;
|
||||
u64 inode_id;
|
||||
int ret, err = 0;
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
||||
key.objectid = 0;
|
||||
key.type = 0;
|
||||
key.offset = 0;
|
||||
|
||||
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
while (1) {
|
||||
btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
|
||||
|
||||
/*
|
||||
* All check must start with inode item, skip if not
|
||||
*/
|
||||
if (key.type == BTRFS_INODE_ITEM_KEY) {
|
||||
ret = check_inode_item(root, path, ext_ref);
|
||||
err |= ret;
|
||||
if (err & LAST_ITEM)
|
||||
goto out;
|
||||
continue;
|
||||
}
|
||||
error("root %llu ITEM[%llu %u %llu] isn't INODE_ITEM, skip to next inode",
|
||||
root->objectid, key.objectid, key.type,
|
||||
key.offset);
|
||||
|
||||
err |= NO_INODE_ITEM;
|
||||
inode_id = key.objectid;
|
||||
|
||||
/*
|
||||
* skip to next inode
|
||||
* TODO: Maybe search_slot() will be faster?
|
||||
*/
|
||||
do {
|
||||
ret = btrfs_next_item(root, path);
|
||||
if (ret > 0) {
|
||||
goto out;
|
||||
} else if (ret < 0) {
|
||||
err = ret;
|
||||
goto out;
|
||||
}
|
||||
btrfs_item_key_to_cpu(path->nodes[0], &key,
|
||||
path->slots[0]);
|
||||
} while (inode_id == key.objectid);
|
||||
}
|
||||
|
||||
out:
|
||||
err &= ~LAST_ITEM;
|
||||
if (err && !ret)
|
||||
ret = -EIO;
|
||||
btrfs_free_path(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int all_backpointers_checked(struct extent_record *rec, int print_errs)
|
||||
{
|
||||
struct list_head *cur = rec->backrefs.next;
|
||||
|
Loading…
Reference in New Issue
Block a user