btrfs-progs: recieve: add missing short option E to getopt
[platform/upstream/btrfs-progs.git] / cmds-check.c
index 204bd4c..f6320b2 100644 (file)
@@ -1528,6 +1528,14 @@ static int process_dir_item(struct extent_buffer *eb,
 
                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,
@@ -1967,6 +1975,7 @@ out:
 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;
@@ -1979,11 +1988,11 @@ static void reada_walk_down(struct btrfs_root *root,
                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);
        }
 }
 
@@ -2104,6 +2113,7 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path,
        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;
@@ -2155,7 +2165,7 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path,
                }
                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];
@@ -2179,7 +2189,7 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path,
                        }
                }
 
-               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]);
@@ -2242,6 +2252,7 @@ static int walk_down_tree_v2(struct btrfs_root *root, struct btrfs_path *path,
        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;
@@ -2284,7 +2295,7 @@ static int walk_down_tree_v2(struct btrfs_root *root, struct btrfs_path *path,
                }
                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)
@@ -2294,11 +2305,11 @@ static int walk_down_tree_v2(struct btrfs_root *root, struct btrfs_path *path,
                        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;
@@ -2306,10 +2317,10 @@ static int walk_down_tree_v2(struct btrfs_root *root, struct btrfs_path *path,
                                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;
@@ -4669,6 +4680,15 @@ static int check_dir_item(struct btrfs_root *root, struct btrfs_key *key,
                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);
 
@@ -6623,7 +6643,7 @@ static int process_chunk_item(struct cache_tree *chunk_cache,
         * 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",
@@ -7608,6 +7628,7 @@ static int run_next_block(struct btrfs_root *root,
                          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;
@@ -7637,7 +7658,7 @@ static int run_next_block(struct btrfs_root *root,
                                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);
                }
        }
@@ -10923,7 +10944,7 @@ static int check_dev_extent_item(struct btrfs_fs_info *fs_info,
 
        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;
@@ -11181,7 +11202,7 @@ static int check_chunk_item(struct btrfs_fs_info *fs_info,
        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,
@@ -12741,7 +12762,7 @@ int cmd_check(int argc, char **argv)
                        { 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) {