read_extent_buffer(eb, namebuf, (unsigned long)(di + 1), len);
+ if (key->type == BTRFS_DIR_ITEM_KEY &&
+ key->offset != btrfs_name_hash(namebuf, len)) {
+ rec->errors |= I_ERR_ODD_DIR_ITEM;
+ error("DIR_ITEM[%llu %llu] name %s namelen %u filetype %u mismatch with its hash, wanted %llu have %llu",
+ key->objectid, key->offset, namebuf, len, filetype,
+ key->offset, btrfs_name_hash(namebuf, len));
+ }
+
if (location.type == BTRFS_INODE_ITEM_KEY) {
add_inode_backref(inode_cache, location.objectid,
key->objectid, key->offset, namebuf,
static void reada_walk_down(struct btrfs_root *root,
struct extent_buffer *node, int slot)
{
+ struct btrfs_fs_info *fs_info = root->fs_info;
u64 bytenr;
u64 ptr_gen;
u32 nritems;
return;
nritems = btrfs_header_nritems(node);
- blocksize = root->fs_info->nodesize;
+ blocksize = fs_info->nodesize;
for (i = slot; i < nritems; i++) {
bytenr = btrfs_node_blockptr(node, i);
ptr_gen = btrfs_node_ptr_generation(node, i);
- readahead_tree_block(root, bytenr, blocksize, ptr_gen);
+ readahead_tree_block(fs_info, bytenr, blocksize, ptr_gen);
}
}
enum btrfs_tree_block_status status;
u64 bytenr;
u64 ptr_gen;
+ struct btrfs_fs_info *fs_info = root->fs_info;
struct extent_buffer *next;
struct extent_buffer *cur;
u32 blocksize;
}
bytenr = btrfs_node_blockptr(cur, path->slots[*level]);
ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]);
- blocksize = root->fs_info->nodesize;
+ blocksize = fs_info->nodesize;
if (bytenr == nrefs->bytenr[*level - 1]) {
refs = nrefs->refs[*level - 1];
}
}
- next = btrfs_find_tree_block(root, bytenr, blocksize);
+ next = btrfs_find_tree_block(fs_info, bytenr, blocksize);
if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) {
free_extent_buffer(next);
reada_walk_down(root, cur, path->slots[*level]);
enum btrfs_tree_block_status status;
u64 bytenr;
u64 ptr_gen;
+ struct btrfs_fs_info *fs_info = root->fs_info;
struct extent_buffer *next;
struct extent_buffer *cur;
u32 blocksize;
}
bytenr = btrfs_node_blockptr(cur, path->slots[*level]);
ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]);
- blocksize = root->fs_info->nodesize;
+ blocksize = fs_info->nodesize;
ret = update_nodes_refs(root, bytenr, nrefs, *level - 1);
if (ret)
continue;
}
- next = btrfs_find_tree_block(root, bytenr, blocksize);
+ next = btrfs_find_tree_block(fs_info, bytenr, blocksize);
if (!next || !btrfs_buffer_uptodate(next, ptr_gen)) {
free_extent_buffer(next);
reada_walk_down(root, cur, path->slots[*level]);
- next = read_tree_block(root->fs_info, bytenr, blocksize,
+ next = read_tree_block(fs_info, bytenr, blocksize,
ptr_gen);
if (!extent_buffer_uptodate(next)) {
struct btrfs_key node_key;
btrfs_node_key_to_cpu(path->nodes[*level],
&node_key,
path->slots[*level]);
- btrfs_add_corrupt_extent_record(root->fs_info,
+ btrfs_add_corrupt_extent_record(fs_info,
&node_key,
path->nodes[*level]->start,
- root->fs_info->nodesize,
+ fs_info->nodesize,
*level);
ret = -EIO;
break;
read_extent_buffer(node, namebuf, (unsigned long)(di + 1), len);
filetype = btrfs_dir_type(node, di);
+ if (key->type == BTRFS_DIR_ITEM_KEY &&
+ key->offset != btrfs_name_hash(namebuf, len)) {
+ err |= -EIO;
+ error("root %llu DIR_ITEM[%llu %llu] name %s namelen %u filetype %u mismatch with its hash, wanted %llu have %llu",
+ root->objectid, key->objectid, key->offset,
+ namebuf, len, filetype, key->offset,
+ btrfs_name_hash(namebuf, len));
+ }
+
btrfs_init_path(&path);
btrfs_dir_item_key_to_cpu(node, di, &location);
* wrong onwer(3) out of chunk tree, to pass both chunk tree check
* and owner<->key_type check.
*/
- ret = btrfs_check_chunk_valid(global_info->tree_root, eb, chunk, slot,
+ ret = btrfs_check_chunk_valid(global_info, eb, chunk, slot,
key->offset);
if (ret < 0) {
error("chunk(%llu, %llu) is not valid, ignore it",
struct device_extent_tree *dev_extent_cache,
struct root_item_record *ri)
{
+ struct btrfs_fs_info *fs_info = root->fs_info;
struct extent_buffer *buf;
struct extent_record *rec = NULL;
u64 bytenr;
continue;
/* fixme, get the parent transid */
- readahead_tree_block(root, bits[i].start,
+ readahead_tree_block(fs_info, bits[i].start,
bits[i].size, 0);
}
}
l = path.nodes[0];
chunk = btrfs_item_ptr(l, path.slots[0], struct btrfs_chunk);
- ret = btrfs_check_chunk_valid(chunk_root, l, chunk, path.slots[0],
+ ret = btrfs_check_chunk_valid(fs_info, l, chunk, path.slots[0],
chunk_key.offset);
if (ret < 0)
goto out;
chunk = btrfs_item_ptr(eb, slot, struct btrfs_chunk);
length = btrfs_chunk_length(eb, chunk);
chunk_end = chunk_key.offset + length;
- ret = btrfs_check_chunk_valid(extent_root, eb, chunk, slot,
+ ret = btrfs_check_chunk_valid(fs_info, eb, chunk, slot,
chunk_key.offset);
if (ret < 0) {
error("chunk[%llu %llu) is invalid", chunk_key.offset,
{ NULL, 0, NULL, 0}
};
- c = getopt_long(argc, argv, "as:br:p", long_options, NULL);
+ c = getopt_long(argc, argv, "as:br:pEQ", long_options, NULL);
if (c < 0)
break;
switch(c) {