mirror of
https://github.com/kdave/btrfs-progs
synced 2025-05-05 09:28:03 +00:00
btrfs-progs: check: introduce function to check inode_extref
Introduce a new function check_inode_extref() to check INODE_EXTREF, and call find_dir_item() to find the related DIR_ITEM/DIR_INDEX. 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
6c9569fac2
commit
ec7b85da52
78
cmds-check.c
78
cmds-check.c
@ -4041,6 +4041,84 @@ next:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Traverse the given INODE_EXTREF and call find_dir_item() to find related
|
||||||
|
* DIR_ITEM/DIR_INDEX.
|
||||||
|
*
|
||||||
|
* @root: the root of the fs/file tree
|
||||||
|
* @ref_key: the key of the INODE_EXTREF
|
||||||
|
* @refs: the count of INODE_EXTREF
|
||||||
|
* @mode: the st_mode of INODE_ITEM
|
||||||
|
*
|
||||||
|
* Return 0 if no error occurred.
|
||||||
|
*/
|
||||||
|
static int check_inode_extref(struct btrfs_root *root,
|
||||||
|
struct btrfs_key *ref_key,
|
||||||
|
struct extent_buffer *node, int slot, u64 *refs,
|
||||||
|
int mode)
|
||||||
|
{
|
||||||
|
struct btrfs_key key;
|
||||||
|
struct btrfs_inode_extref *extref;
|
||||||
|
char namebuf[BTRFS_NAME_LEN] = {0};
|
||||||
|
u32 total;
|
||||||
|
u32 cur = 0;
|
||||||
|
u32 len;
|
||||||
|
u32 name_len;
|
||||||
|
u64 index;
|
||||||
|
u64 parent;
|
||||||
|
int ret;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
extref = btrfs_item_ptr(node, slot, struct btrfs_inode_extref);
|
||||||
|
total = btrfs_item_size_nr(node, slot);
|
||||||
|
|
||||||
|
next:
|
||||||
|
/* update inode ref count */
|
||||||
|
(*refs)++;
|
||||||
|
name_len = btrfs_inode_extref_name_len(node, extref);
|
||||||
|
index = btrfs_inode_extref_index(node, extref);
|
||||||
|
parent = btrfs_inode_extref_parent(node, extref);
|
||||||
|
if (name_len <= BTRFS_NAME_LEN) {
|
||||||
|
len = name_len;
|
||||||
|
} else {
|
||||||
|
len = BTRFS_NAME_LEN;
|
||||||
|
warning("root %llu INODE_EXTREF[%llu %llu] name too long",
|
||||||
|
root->objectid, ref_key->objectid, ref_key->offset);
|
||||||
|
}
|
||||||
|
read_extent_buffer(node, namebuf, (unsigned long)(extref + 1), len);
|
||||||
|
|
||||||
|
/* Check root dir ref name */
|
||||||
|
if (index == 0 && strncmp(namebuf, "..", name_len)) {
|
||||||
|
error("root %llu INODE_EXTREF[%llu %llu] ROOT_DIR name shouldn't be %s",
|
||||||
|
root->objectid, ref_key->objectid, ref_key->offset,
|
||||||
|
namebuf);
|
||||||
|
err |= ROOT_DIR_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find related dir_index */
|
||||||
|
key.objectid = parent;
|
||||||
|
key.type = BTRFS_DIR_INDEX_KEY;
|
||||||
|
key.offset = index;
|
||||||
|
ret = find_dir_item(root, ref_key, &key, index, namebuf, len, mode);
|
||||||
|
err |= ret;
|
||||||
|
|
||||||
|
/* find related dir_item */
|
||||||
|
key.objectid = parent;
|
||||||
|
key.type = BTRFS_DIR_ITEM_KEY;
|
||||||
|
key.offset = btrfs_name_hash(namebuf, len);
|
||||||
|
ret = find_dir_item(root, ref_key, &key, index, namebuf, len, mode);
|
||||||
|
err |= ret;
|
||||||
|
|
||||||
|
len = sizeof(*extref) + name_len;
|
||||||
|
extref = (struct btrfs_inode_extref *)((char *)extref + len);
|
||||||
|
cur += len;
|
||||||
|
|
||||||
|
if (cur < total)
|
||||||
|
goto next;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int all_backpointers_checked(struct extent_record *rec, int print_errs)
|
static int all_backpointers_checked(struct extent_record *rec, int print_errs)
|
||||||
{
|
{
|
||||||
struct list_head *cur = rec->backrefs.next;
|
struct list_head *cur = rec->backrefs.next;
|
||||||
|
Loading…
Reference in New Issue
Block a user