libbtrfsutil: always build libbtrfsutil.so.$MAJOR
[platform/upstream/btrfs-progs.git] / check / main.c
index 98e24af..891a6d7 100644 (file)
@@ -43,9 +43,9 @@
 #include "kernel-shared/ulist.h"
 #include "hash.h"
 #include "help.h"
-#include "check/original.h"
-#include "check/lowmem.h"
-#include "check/common.h"
+#include "check/mode-common.h"
+#include "check/mode-original.h"
+#include "check/mode-lowmem.h"
 
 enum task_position {
        TASK_EXTENTS,
@@ -560,6 +560,8 @@ static void print_inode_error(struct btrfs_root *root, struct inode_record *rec)
                fprintf(stderr, ", bad file extent");
        if (errors & I_ERR_FILE_EXTENT_OVERLAP)
                fprintf(stderr, ", file extent overlap");
+       if (errors & I_ERR_FILE_EXTENT_TOO_LARGE)
+               fprintf(stderr, ", inline file extent too large");
        if (errors & I_ERR_FILE_EXTENT_DISCOUNT)
                fprintf(stderr, ", file extent discount");
        if (errors & I_ERR_DIR_ISIZE_WRONG)
@@ -1433,6 +1435,8 @@ static int process_file_extent(struct btrfs_root *root,
        u64 disk_bytenr = 0;
        u64 extent_offset = 0;
        u64 mask = root->fs_info->sectorsize - 1;
+       u32 max_inline_size = min_t(u32, mask,
+                               BTRFS_MAX_INLINE_DATA_SIZE(root->fs_info));
        int extent_type;
        int ret;
 
@@ -1458,9 +1462,21 @@ static int process_file_extent(struct btrfs_root *root,
        extent_type = btrfs_file_extent_type(eb, fi);
 
        if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
+               u8 compression = btrfs_file_extent_compression(eb, fi);
+               struct btrfs_item *item = btrfs_item_nr(slot);
+
                num_bytes = btrfs_file_extent_inline_len(eb, slot, fi);
                if (num_bytes == 0)
                        rec->errors |= I_ERR_BAD_FILE_EXTENT;
+               if (compression) {
+                       if (btrfs_file_extent_inline_item_len(eb, item) >
+                           max_inline_size ||
+                           num_bytes > root->fs_info->sectorsize)
+                               rec->errors |= I_ERR_FILE_EXTENT_TOO_LARGE;
+               } else {
+                       if (num_bytes > max_inline_size)
+                               rec->errors |= I_ERR_FILE_EXTENT_TOO_LARGE;
+               }
                rec->found_size += num_bytes;
                num_bytes = (num_bytes + mask) & ~mask;
        } else if (extent_type == BTRFS_FILE_EXTENT_REG ||
@@ -1511,8 +1527,15 @@ static int process_file_extent(struct btrfs_root *root,
                        if (found < num_bytes)
                                rec->some_csum_missing = 1;
                } else if (extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
-                       if (found > 0)
-                               rec->errors |= I_ERR_ODD_CSUM_ITEM;
+                       if (found > 0) {
+                               ret = check_prealloc_extent_written(root->fs_info,
+                                                                   disk_bytenr,
+                                                                   num_bytes);
+                               if (ret < 0)
+                                       return ret;
+                               if (ret == 0)
+                                       rec->errors |= I_ERR_ODD_CSUM_ITEM;
+                       }
                }
        }
        return 0;
@@ -1720,14 +1743,13 @@ static int walk_up_tree(struct btrfs_root *root, struct btrfs_path *path,
                        path->slots[i]++;
                        *level = i;
                        return 0;
-               } else {
-                       free_extent_buffer(path->nodes[*level]);
-                       path->nodes[*level] = NULL;
-                       BUG_ON(*level > wc->active_node);
-                       if (*level == wc->active_node)
-                               leave_shared_node(root, wc, *level);
-                       *level = i + 1;
                }
+               free_extent_buffer(path->nodes[*level]);
+               path->nodes[*level] = NULL;
+               BUG_ON(*level > wc->active_node);
+               if (*level == wc->active_node)
+                       leave_shared_node(root, wc, *level);
+               *level = i + 1;
        }
        return 1;
 }
@@ -1790,7 +1812,7 @@ static int repair_inode_isize(struct btrfs_trans_handle *trans,
        btrfs_set_inode_size(path->nodes[0], ei, rec->found_size);
        btrfs_mark_buffer_dirty(path->nodes[0]);
        rec->errors &= ~I_ERR_DIR_ISIZE_WRONG;
-       printf("reset isize for dir %Lu root %Lu\n", rec->ino,
+       printf("reset isize for dir %llu root %llu\n", rec->ino,
               root->root_key.objectid);
 out:
        btrfs_release_path(path);
@@ -3465,7 +3487,7 @@ static int do_check_fs_roots(struct btrfs_fs_info *fs_info,
        if (!ctx.progress_enabled)
                fprintf(stderr, "checking fs roots\n");
        if (check_mode == CHECK_MODE_LOWMEM)
-               ret = check_fs_roots_v2(fs_info);
+               ret = check_fs_roots_lowmem(fs_info);
        else
                ret = check_fs_roots(fs_info, root_cache);
 
@@ -3488,22 +3510,21 @@ static int all_backpointers_checked(struct extent_record *rec, int print_errs)
                                goto out;
                        if (back->is_data) {
                                dback = to_data_backref(back);
-                               fprintf(stderr, "Data backref %llu %s %llu"
-                                       " owner %llu offset %llu num_refs %lu"
-                                       " not found in extent tree\n",
+                               fprintf(stderr,
+"data backref %llu %s %llu owner %llu offset %llu num_refs %lu not found in extent tree\n",
                                        (unsigned long long)rec->start,
                                        back->full_backref ?
                                        "parent" : "root",
                                        back->full_backref ?
-                                       (unsigned long long)dback->parent:
+                                       (unsigned long long)dback->parent :
                                        (unsigned long long)dback->root,
                                        (unsigned long long)dback->owner,
                                        (unsigned long long)dback->offset,
                                        (unsigned long)dback->num_refs);
                        } else {
                                tback = to_tree_backref(back);
-                               fprintf(stderr, "Tree backref %llu parent %llu"
-                                       " root %llu not found in extent tree\n",
+                               fprintf(stderr,
+"tree backref %llu parent %llu root %llu not found in extent tree\n",
                                        (unsigned long long)rec->start,
                                        (unsigned long long)tback->parent,
                                        (unsigned long long)tback->root);
@@ -3514,7 +3535,8 @@ static int all_backpointers_checked(struct extent_record *rec, int print_errs)
                        if (!print_errs)
                                goto out;
                        tback = to_tree_backref(back);
-                       fprintf(stderr, "Backref %llu %s %llu not referenced back %p\n",
+                       fprintf(stderr,
+                               "backref %llu %s %llu not referenced back %p\n",
                                (unsigned long long)rec->start,
                                back->full_backref ? "parent" : "root",
                                back->full_backref ?
@@ -3527,26 +3549,25 @@ static int all_backpointers_checked(struct extent_record *rec, int print_errs)
                                err = 1;
                                if (!print_errs)
                                        goto out;
-                               fprintf(stderr, "Incorrect local backref count"
-                                       " on %llu %s %llu owner %llu"
-                                       " offset %llu found %u wanted %u back %p\n",
+                               fprintf(stderr,
+"incorrect local backref count on %llu %s %llu owner %llu offset %llu found %u wanted %u back %p\n",
                                        (unsigned long long)rec->start,
                                        back->full_backref ?
                                        "parent" : "root",
                                        back->full_backref ?
-                                       (unsigned long long)dback->parent:
+                                       (unsigned long long)dback->parent :
                                        (unsigned long long)dback->root,
                                        (unsigned long long)dback->owner,
                                        (unsigned long long)dback->offset,
-                                       dback->found_ref, dback->num_refs, back);
+                                       dback->found_ref, dback->num_refs,
+                                       back);
                        }
                        if (dback->disk_bytenr != rec->start) {
                                err = 1;
                                if (!print_errs)
                                        goto out;
-                               fprintf(stderr, "Backref disk bytenr does not"
-                                       " match extent record, bytenr=%llu, "
-                                       "ref bytenr=%llu\n",
+                               fprintf(stderr,
+"backref disk bytenr does not match extent record, bytenr=%llu, ref bytenr=%llu\n",
                                        (unsigned long long)rec->start,
                                        (unsigned long long)dback->disk_bytenr);
                        }
@@ -3555,9 +3576,8 @@ static int all_backpointers_checked(struct extent_record *rec, int print_errs)
                                err = 1;
                                if (!print_errs)
                                        goto out;
-                               fprintf(stderr, "Backref bytes do not match "
-                                       "extent backref, bytenr=%llu, ref "
-                                       "bytes=%llu, backref bytes=%llu\n",
+                               fprintf(stderr,
+"backref bytes do not match extent backref, bytenr=%llu, ref bytes=%llu, backref bytes=%llu\n",
                                        (unsigned long long)rec->start,
                                        (unsigned long long)rec->nr,
                                        (unsigned long long)dback->bytes);
@@ -3574,8 +3594,8 @@ static int all_backpointers_checked(struct extent_record *rec, int print_errs)
                err = 1;
                if (!print_errs)
                        goto out;
-               fprintf(stderr, "Incorrect global backref count "
-                       "on %llu found %llu wanted %llu\n",
+               fprintf(stderr,
+       "incorrect global backref count on %llu found %llu wanted %llu\n",
                        (unsigned long long)rec->start,
                        (unsigned long long)found,
                        (unsigned long long)rec->refs);
@@ -3745,6 +3765,7 @@ static int swap_values(struct btrfs_root *root, struct btrfs_path *path,
                                    sizeof(struct btrfs_key_ptr));
                if (slot == 0) {
                        struct btrfs_disk_key key;
+
                        btrfs_node_key(buf, &key, 0);
                        btrfs_fixup_low_keys(root, path, &key,
                                             btrfs_header_level(buf) + 1);
@@ -3877,8 +3898,8 @@ again:
                                ret = delete_bogus_item(root, path, buf, i);
                                if (!ret)
                                        goto again;
-                               fprintf(stderr, "item is off the end of the "
-                                       "leaf, can't fix\n");
+                               fprintf(stderr,
+                               "item is off the end of the leaf, can't fix\n");
                                ret = -EIO;
                                break;
                        }
@@ -4066,7 +4087,7 @@ static struct tree_backref *find_tree_backref(struct extent_record *rec,
        struct extent_backref *node;
        struct tree_backref *back;
 
-       while(cur != &rec->backrefs) {
+       while (cur != &rec->backrefs) {
                node = to_extent_backref(cur);
                cur = cur->next;
                if (node->is_data)
@@ -4118,7 +4139,7 @@ static struct data_backref *find_data_backref(struct extent_record *rec,
        struct extent_backref *node;
        struct data_backref *back;
 
-       while(cur != &rec->backrefs) {
+       while (cur != &rec->backrefs) {
                node = to_extent_backref(cur);
                cur = cur->next;
                if (!node->is_data)
@@ -4344,12 +4365,13 @@ static int add_extent_rec(struct cache_tree *extent_cache,
 
                if (tmpl->extent_item_refs && !dup) {
                        if (rec->extent_item_refs) {
-                               fprintf(stderr, "block %llu rec "
-                                       "extent_item_refs %llu, passed %llu\n",
+                               fprintf(stderr,
+                       "block %llu rec extent_item_refs %llu, passed %llu\n",
                                        (unsigned long long)tmpl->start,
                                        (unsigned long long)
                                                        rec->extent_item_refs,
-                                       (unsigned long long)tmpl->extent_item_refs);
+                                       (unsigned long long)
+                                                       tmpl->extent_item_refs);
                        }
                        rec->extent_item_refs = tmpl->extent_item_refs;
                }
@@ -4433,8 +4455,8 @@ static int add_tree_backref(struct cache_tree *extent_cache, u64 bytenr,
 
        if (found_ref) {
                if (back->node.found_ref) {
-                       fprintf(stderr, "Extent back ref already exists "
-                               "for %llu parent %llu root %llu \n",
+                       fprintf(stderr,
+       "Extent back ref already exists for %llu parent %llu root %llu\n",
                                (unsigned long long)bytenr,
                                (unsigned long long)parent,
                                (unsigned long long)root);
@@ -4442,8 +4464,8 @@ static int add_tree_backref(struct cache_tree *extent_cache, u64 bytenr,
                back->node.found_ref = 1;
        } else {
                if (back->node.found_extent_tree) {
-                       fprintf(stderr, "Extent back ref already exists "
-                               "for %llu parent %llu root %llu \n",
+                       fprintf(stderr,
+       "extent back ref already exists for %llu parent %llu root %llu\n",
                                (unsigned long long)bytenr,
                                (unsigned long long)parent,
                                (unsigned long long)root);
@@ -4530,9 +4552,8 @@ static int add_data_backref(struct cache_tree *extent_cache, u64 bytenr,
                rec->owner_ref_checked = 1;
        } else {
                if (back->node.found_extent_tree) {
-                       fprintf(stderr, "Extent back ref already exists "
-                               "for %llu parent %llu root %llu "
-                               "owner %llu offset %llu num_refs %lu\n",
+                       fprintf(stderr,
+"Extent back ref already exists for %llu parent %llu root %llu owner %llu offset %llu num_refs %lu\n",
                                (unsigned long long)bytenr,
                                (unsigned long long)parent,
                                (unsigned long long)root,
@@ -4555,6 +4576,7 @@ static int add_pending(struct cache_tree *pending,
                       struct cache_tree *seen, u64 bytenr, u32 size)
 {
        int ret;
+
        ret = add_cache_extent(seen, bytenr, size);
        if (ret)
                return ret;
@@ -4588,17 +4610,17 @@ static int pick_next_pending(struct cache_tree *pending,
                cache = search_cache_extent(nodes, 0);
 
        if (!cache) {
-                cache = search_cache_extent(pending, 0);
-                if (!cache)
-                        return 0;
-                ret = 0;
-                do {
-                        bits[ret].start = cache->start;
-                        bits[ret].size = cache->size;
-                        cache = next_cache_extent(cache);
-                        ret++;
-                } while (cache && ret < bits_nr);
-                return ret;
+               cache = search_cache_extent(pending, 0);
+               if (!cache)
+                       return 0;
+               ret = 0;
+               do {
+                       bits[ret].start = cache->start;
+                       bits[ret].size = cache->size;
+                       cache = next_cache_extent(cache);
+                       ret++;
+               } while (cache && ret < bits_nr);
+               return ret;
        }
 
        ret = 0;
@@ -4612,8 +4634,9 @@ static int pick_next_pending(struct cache_tree *pending,
        if (bits_nr - ret > 8) {
                u64 lookup = bits[0].start + bits[0].size;
                struct cache_extent *next;
+
                next = search_cache_extent(pending, lookup);
-               while(next) {
+               while (next) {
                        if (next->start - lookup > 32768)
                                break;
                        bits[ret].start = next->start;
@@ -5004,6 +5027,7 @@ static int process_extent_item(struct btrfs_root *root,
        if (item_size < sizeof(*ei)) {
 #ifdef BTRFS_COMPAT_EXTENT_TREE_V0
                struct btrfs_extent_item_v0 *ei0;
+
                if (item_size != sizeof(*ei0)) {
                        error(
        "invalid extent item format: ITEM[%llu %u %llu] leaf: %llu slot: %d",
@@ -5098,7 +5122,8 @@ static int process_extent_item(struct btrfs_root *root,
                                        0, num_bytes);
                        break;
                default:
-                       fprintf(stderr, "corrupt extent record: key %Lu %u %Lu\n",
+                       fprintf(stderr,
+                               "corrupt extent record: key [%llu,%u,%llu]\n",
                                key.objectid, key.type, num_bytes);
                        goto out;
                }
@@ -5181,19 +5206,19 @@ static int check_cache_range(struct btrfs_root *root,
 
        entry = btrfs_find_free_space(cache->free_space_ctl, offset, bytes);
        if (!entry) {
-               fprintf(stderr, "There is no free space entry for %Lu-%Lu\n",
+               fprintf(stderr, "there is no free space entry for %llu-%llu\n",
                        offset, offset+bytes);
                return -EINVAL;
        }
 
        if (entry->offset != offset) {
-               fprintf(stderr, "Wanted offset %Lu, found %Lu\n", offset,
+               fprintf(stderr, "wanted offset %llu, found %llu\n", offset,
                        entry->offset);
                return -EINVAL;
        }
 
        if (entry->bytes != bytes) {
-               fprintf(stderr, "Wanted bytes %Lu, found %Lu for off %Lu\n",
+               fprintf(stderr, "wanted bytes %llu, found %llu for off %llu\n",
                        bytes, entry->bytes, offset);
                return -EINVAL;
        }
@@ -5337,13 +5362,15 @@ static int check_space_cache(struct btrfs_root *root)
                        error += ret;
                } else {
                        ret = load_free_space_cache(root->fs_info, cache);
-                       if (!ret)
+                       if (ret < 0)
+                               error++;
+                       if (ret <= 0)
                                continue;
                }
 
                ret = verify_space_cache(root, cache);
                if (ret) {
-                       fprintf(stderr, "cache appears valid but isn't %Lu\n",
+                       fprintf(stderr, "cache appears valid but isn't %llu\n",
                                cache->key.objectid);
                        error++;
                }
@@ -5356,8 +5383,8 @@ static int check_space_cache(struct btrfs_root *root)
 
 static int check_extent_csums(struct btrfs_root *root, u64 bytenr,
                        u64 num_bytes, unsigned long leaf_offset,
-                       struct extent_buffer *eb) {
-
+                       struct extent_buffer *eb)
+{
        struct btrfs_fs_info *fs_info = root->fs_info;
        u64 offset = 0;
        u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
@@ -5553,8 +5580,9 @@ again:
 
 out:
        if (num_bytes && !ret) {
-               fprintf(stderr, "There are no extents for csum range "
-                       "%Lu-%Lu\n", bytenr, bytenr+num_bytes);
+               fprintf(stderr,
+                       "there are no extents for csum range %llu-%llu\n",
+                       bytenr, bytenr+num_bytes);
                ret = 1;
        }
 
@@ -5629,8 +5657,8 @@ skip_csum_check:
                } else if (key.offset != offset + num_bytes) {
                        ret = check_extent_exists(root, offset, num_bytes);
                        if (ret) {
-                               fprintf(stderr, "Csum exists for %Lu-%Lu but "
-                                       "there is no extent record\n",
+                               fprintf(stderr,
+               "csum exists for %llu-%llu but there is no extent record\n",
                                        offset, offset+num_bytes);
                                errors++;
                        }
@@ -5646,7 +5674,8 @@ skip_csum_check:
 }
 
 static int is_dropped_key(struct btrfs_key *key,
-                         struct btrfs_key *drop_key) {
+                         struct btrfs_key *drop_key)
+{
        if (key->objectid < drop_key->objectid)
                return 1;
        else if (key->objectid == drop_key->objectid) {
@@ -5823,7 +5852,7 @@ static int run_next_block(struct btrfs_root *root,
                return 1;
 
        if (!reada_bits) {
-               for(i = 0; i < nritems; i++) {
+               for (i = 0; i < nritems; i++) {
                        ret = add_cache_extent(reada, bits[i].start,
                                               bits[i].size);
                        if (ret == -EEXIST)
@@ -5933,6 +5962,7 @@ static int run_next_block(struct btrfs_root *root,
                btree_space_waste += btrfs_leaf_free_space(root, buf);
                for (i = 0; i < nritems; i++) {
                        struct btrfs_file_extent_item *fi;
+
                        btrfs_item_key_to_cpu(buf, &key, i);
                        /*
                         * Check key type against the leaf owner.
@@ -6007,6 +6037,7 @@ static int run_next_block(struct btrfs_root *root,
                        }
                        if (key.type == BTRFS_EXTENT_DATA_REF_KEY) {
                                struct btrfs_extent_data_ref *ref;
+
                                ref = btrfs_item_ptr(buf, i,
                                                struct btrfs_extent_data_ref);
                                add_data_backref(extent_cache,
@@ -6021,6 +6052,7 @@ static int run_next_block(struct btrfs_root *root,
                        }
                        if (key.type == BTRFS_SHARED_DATA_REF_KEY) {
                                struct btrfs_shared_data_ref *ref;
+
                                ref = btrfs_item_ptr(buf, i,
                                                struct btrfs_shared_data_ref);
                                add_data_backref(extent_cache,
@@ -6058,9 +6090,9 @@ static int run_next_block(struct btrfs_root *root,
 
                        data_bytes_allocated +=
                                btrfs_file_extent_disk_num_bytes(buf, fi);
-                       if (data_bytes_allocated < root->fs_info->sectorsize) {
+                       if (data_bytes_allocated < root->fs_info->sectorsize)
                                abort();
-                       }
+
                        data_bytes_referenced +=
                                btrfs_file_extent_num_bytes(buf, fi);
                        add_data_backref(extent_cache,
@@ -6071,12 +6103,7 @@ static int run_next_block(struct btrfs_root *root,
                }
        } else {
                int level;
-               struct btrfs_key first_key;
-
-               first_key.objectid = 0;
 
-               if (nritems > 0)
-                       btrfs_item_key_to_cpu(buf, &first_key, 0);
                level = btrfs_header_level(buf);
                for (i = 0; i < nritems; i++) {
                        struct extent_record tmpl;
@@ -6093,7 +6120,8 @@ static int run_next_block(struct btrfs_root *root,
 
                        memset(&tmpl, 0, sizeof(tmpl));
                        btrfs_cpu_key_to_disk(&tmpl.parent_key, &key);
-                       tmpl.parent_generation = btrfs_node_ptr_generation(buf, i);
+                       tmpl.parent_generation =
+                               btrfs_node_ptr_generation(buf, i);
                        tmpl.start = ptr;
                        tmpl.nr = size;
                        tmpl.refs = 1;
@@ -6112,11 +6140,10 @@ static int run_next_block(struct btrfs_root *root,
                                continue;
                        }
 
-                       if (level > 1) {
+                       if (level > 1)
                                add_pending(nodes, seen, ptr, size);
-                       } else {
+                       else
                                add_pending(pending, seen, ptr, size);
-                       }
                }
                btree_space_waste += (BTRFS_NODEPTRS_PER_BLOCK(fs_info) -
                                      nritems) * sizeof(struct btrfs_key_ptr);
@@ -6188,6 +6215,7 @@ static int free_extent_hook(struct btrfs_trans_handle *trans,
        rec = container_of(cache, struct extent_record, cache);
        if (is_data) {
                struct data_backref *back;
+
                back = find_data_backref(rec, parent, root_objectid, owner,
                                         offset, 1, bytenr, num_bytes);
                if (!back)
@@ -6213,6 +6241,7 @@ static int free_extent_hook(struct btrfs_trans_handle *trans,
                }
        } else {
                struct tree_backref *back;
+
                back = find_tree_backref(rec, parent, root_objectid);
                if (!back)
                        goto out;
@@ -6252,7 +6281,7 @@ static int delete_extent_records(struct btrfs_trans_handle *trans,
        key.type = (u8)-1;
        key.offset = (u64)-1;
 
-       while(1) {
+       while (1) {
                ret = btrfs_search_slot(trans, root->fs_info->extent_root,
                                        &key, path, 0, 1);
                if (ret < 0)
@@ -6292,7 +6321,8 @@ static int delete_extent_records(struct btrfs_trans_handle *trans,
                        continue;
                }
 
-               fprintf(stderr, "repair deleting extent record: key %Lu %u %Lu\n",
+               fprintf(stderr,
+                       "repair deleting extent record: key [%llu,%u,%llu]\n",
                        found_key.objectid, found_key.type, found_key.offset);
 
                ret = btrfs_del_item(trans, root->fs_info->extent_root, path);
@@ -6365,7 +6395,7 @@ static int record_extent(struct btrfs_trans_handle *trans,
                        btrfs_set_extent_flags(leaf, ei,
                                               BTRFS_EXTENT_FLAG_DATA);
                } else {
-                       struct btrfs_disk_key copy_key;;
+                       struct btrfs_disk_key copy_key;
 
                        bi = (struct btrfs_tree_block_info *)(ei + 1);
                        memset_extent_buffer(leaf, 0, (unsigned long)bi,
@@ -6380,7 +6410,7 @@ static int record_extent(struct btrfs_trans_handle *trans,
                        btrfs_set_tree_block_key(leaf, bi, &copy_key);
 
                        btrfs_set_extent_flags(leaf, ei,
-                                              BTRFS_EXTENT_FLAG_TREE_BLOCK | flags);
+                                       flags | BTRFS_EXTENT_FLAG_TREE_BLOCK);
                }
 
                btrfs_mark_buffer_dirty(leaf);
@@ -6418,18 +6448,14 @@ static int record_extent(struct btrfs_trans_handle *trans,
                        if (ret)
                                break;
                }
-               fprintf(stderr, "adding new data backref"
-                               " on %llu %s %llu owner %llu"
-                               " offset %llu found %d\n",
-                               (unsigned long long)rec->start,
-                               back->full_backref ?
-                               "parent" : "root",
-                               back->full_backref ?
-                               (unsigned long long)parent :
-                               (unsigned long long)dback->root,
-                               (unsigned long long)dback->owner,
-                               (unsigned long long)dback->offset,
-                               dback->found_ref);
+               fprintf(stderr,
+"adding new data backref on %llu %s %llu owner %llu offset %llu found %d\n",
+                       (unsigned long long)rec->start,
+                       back->full_backref ? "parent" : "root",
+                       back->full_backref ? (unsigned long long)parent :
+                                            (unsigned long long)dback->root,
+                       (unsigned long long)dback->owner,
+                       (unsigned long long)dback->offset, dback->found_ref);
        } else {
                u64 parent;
                struct tree_backref *tback;
@@ -6443,8 +6469,8 @@ static int record_extent(struct btrfs_trans_handle *trans,
                ret = btrfs_inc_extent_ref(trans, info->extent_root,
                                           rec->start, rec->max_size,
                                           parent, tback->root, 0, 0);
-               fprintf(stderr, "adding new tree backref on "
-                       "start %llu len %llu parent %llu root %llu\n",
+               fprintf(stderr,
+"adding new tree backref on start %llu len %llu parent %llu root %llu\n",
                        rec->start, rec->max_size, parent, tback->root);
        }
 fail:
@@ -6582,14 +6608,14 @@ static int repair_ref(struct btrfs_fs_info *info, struct btrfs_path *path,
         */
        ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
        if (ret < 0) {
-               fprintf(stderr, "Error cowing down to ref [%Lu, %u, %Lu]: %d\n",
+               fprintf(stderr, "error cowing down to ref [%llu,%u,%llu]: %d\n",
                        key.objectid, key.type, key.offset, ret);
                goto out;
        }
        if (ret > 0) {
-               fprintf(stderr, "Well that's odd, we just found this key "
-                       "[%Lu, %u, %Lu]\n", key.objectid, key.type,
-                       key.offset);
+               fprintf(stderr,
+               "well that's odd, we just found this key [%llu,%u,%llu]\n",
+                       key.objectid, key.type, key.offset);
                ret = -EINVAL;
                goto out;
        }
@@ -6599,10 +6625,8 @@ static int repair_ref(struct btrfs_fs_info *info, struct btrfs_path *path,
 
        if (btrfs_file_extent_compression(leaf, fi) &&
            dback->disk_bytenr != entry->bytenr) {
-               fprintf(stderr, "Ref doesn't match the record start and is "
-                       "compressed, please take a btrfs-image of this file "
-                       "system and send it to a btrfs developer so they can "
-                       "complete this functionality for bytenr %Lu\n",
+               fprintf(stderr,
+"ref doesn't match the record start and is compressed, please take a btrfs-image of this file system and send it to a btrfs developer so they can complete this functionality for bytenr %llu\n",
                        dback->disk_bytenr);
                ret = -EINVAL;
                goto out;
@@ -6618,9 +6642,8 @@ static int repair_ref(struct btrfs_fs_info *info, struct btrfs_path *path,
                if (dback->disk_bytenr + offset +
                    btrfs_file_extent_num_bytes(leaf, fi) >
                    entry->bytenr + entry->bytes) {
-                       fprintf(stderr, "Ref is past the entry end, please "
-                               "take a btrfs-image of this file system and "
-                               "send it to a btrfs developer, ref %Lu\n",
+                       fprintf(stderr,
+"ref is past the entry end, please take a btrfs-image of this file system and send it to a btrfs developer, ref %llu\n",
                                dback->disk_bytenr);
                        ret = -EINVAL;
                        goto out;
@@ -6633,9 +6656,8 @@ static int repair_ref(struct btrfs_fs_info *info, struct btrfs_path *path,
 
                offset = btrfs_file_extent_offset(leaf, fi);
                if (dback->disk_bytenr + offset < entry->bytenr) {
-                       fprintf(stderr, "Ref is before the entry start, please"
-                               " take a btrfs-image of this file system and "
-                               "send it to a btrfs developer, ref %Lu\n",
+                       fprintf(stderr,
+"ref is before the entry start, please take a btrfs-image of this file system and send it to a btrfs developer, ref %llu\n",
                                dback->disk_bytenr);
                        ret = -EINVAL;
                        goto out;
@@ -6741,8 +6763,9 @@ static int verify_backrefs(struct btrfs_fs_info *info, struct btrfs_path *path,
        if (nr_entries <= 1 && !mismatch)
                goto out;
 
-       fprintf(stderr, "attempting to repair backref discrepency for bytenr "
-               "%Lu\n", rec->start);
+       fprintf(stderr,
+               "attempting to repair backref discrepency for bytenr %llu\n",
+               rec->start);
 
        /*
         * First we want to see if the backrefs can agree amongst themselves who
@@ -6758,9 +6781,8 @@ static int verify_backrefs(struct btrfs_fs_info *info, struct btrfs_path *path,
        if (!best) {
                entry = find_entry(&entries, rec->start, rec->nr);
                if (!entry && (!broken_entries || !rec->found_rec)) {
-                       fprintf(stderr, "Backrefs don't agree with each other "
-                               "and extent record doesn't agree with anybody,"
-                               " so we can't fix bytenr %Lu bytes %Lu\n",
+                       fprintf(stderr,
+"backrefs don't agree with each other and extent record doesn't agree with anybody, so we can't fix bytenr %llu bytes %llu\n",
                                rec->start, rec->nr);
                        ret = -EINVAL;
                        goto out;
@@ -6783,10 +6805,9 @@ static int verify_backrefs(struct btrfs_fs_info *info, struct btrfs_path *path,
                entry->count++;
                best = find_most_right_entry(&entries);
                if (!best) {
-                       fprintf(stderr, "Backrefs and extent record evenly "
-                               "split on who is right, this is going to "
-                               "require user input to fix bytenr %Lu bytes "
-                               "%Lu\n", rec->start, rec->nr);
+                       fprintf(stderr,
+"backrefs and extent record evenly split on who is right, this is going to require user input to fix bytenr %llu bytes %llu\n",
+                               rec->start, rec->nr);
                        ret = -EINVAL;
                        goto out;
                }
@@ -6798,10 +6819,8 @@ static int verify_backrefs(struct btrfs_fs_info *info, struct btrfs_path *path,
         * deal with it properly here yet, so just bail out of that's the case.
         */
        if (best->bytenr != rec->start) {
-               fprintf(stderr, "Extent start and backref starts don't match, "
-                       "please use btrfs-image on this file system and send "
-                       "it to a btrfs developer so they can make fsck fix "
-                       "this particular case.  bytenr is %Lu, bytes is %Lu\n",
+               fprintf(stderr,
+"extent start and backref starts don't match, please use btrfs-image on this file system and send it to a btrfs developer so they can make fsck fix this particular case.  bytenr is %llu, bytes is %llu\n",
                        rec->start, rec->nr);
                ret = -EINVAL;
                goto out;
@@ -6951,10 +6970,8 @@ static int delete_duplicate_records(struct btrfs_root *root,
                        continue;
 
                if (tmp->start + tmp->nr < good->start + good->nr) {
-                       fprintf(stderr, "Ok we have overlapping extents that "
-                               "aren't completely covered by each other, this "
-                               "is going to require more careful thought.  "
-                               "The extents are [%Lu-%Lu] and [%Lu-%Lu]\n",
+                       fprintf(stderr,
+"Ok we have overlapping extents that aren't completely covered by each other, this is going to require more careful thought. The extents are [%llu-%llu] and [%llu-%llu]\n",
                                tmp->start, tmp->nr, good->start, good->nr);
                        abort();
                }
@@ -6986,9 +7003,9 @@ static int delete_duplicate_records(struct btrfs_root *root,
 
                /* Shouldn't happen but just in case */
                if (tmp->metadata) {
-                       fprintf(stderr, "Well this shouldn't happen, extent "
-                               "record overlaps but is metadata? "
-                               "[%Lu, %Lu]\n", tmp->start, tmp->nr);
+                       fprintf(stderr,
+"well this shouldn't happen, extent record overlaps but is metadata? [%llu, %llu]\n",
+                               tmp->start, tmp->nr);
                        abort();
                }
 
@@ -7090,6 +7107,7 @@ static int find_possible_backrefs(struct btrfs_fs_info *info,
                cache = lookup_cache_extent(extent_cache, bytenr, 1);
                if (cache) {
                        struct extent_record *tmp;
+
                        tmp = container_of(cache, struct extent_record, cache);
 
                        /*
@@ -7271,7 +7289,8 @@ static int fixup_extent_refs(struct btrfs_fs_info *info,
                        continue;
 
                rec->bad_full_backref = 0;
-               ret = record_extent(trans, info, &path, rec, back, allocated, flags);
+               ret = record_extent(trans, info, &path, rec, back, allocated,
+                                   flags);
                allocated = 1;
 
                if (ret)
@@ -7280,6 +7299,7 @@ static int fixup_extent_refs(struct btrfs_fs_info *info,
 out:
        if (trans) {
                int err = btrfs_commit_transaction(trans, info->extent_root);
+
                if (!ret)
                        ret = err;
        }
@@ -7401,8 +7421,8 @@ again:
                        goto del_ptr;
        }
        /*
-        * we couldn't find the bad block.  TODO, search all the nodes for pointers
-        * to this block
+        * We couldn't find the bad block.
+        * TODO: search all the nodes for pointers to this block
         */
        if (eb == info->extent_root->node) {
                ret = -ENOENT;
@@ -7414,7 +7434,7 @@ again:
        }
 
 del_ptr:
-       printk("deleting pointer to block %Lu\n", corrupt->cache.start);
+       printk("deleting pointer to block %llu\n", corrupt->cache.start);
        ret = btrfs_del_ptr(info->extent_root, &path, level, slot);
 
 out:
@@ -7463,7 +7483,7 @@ static int check_extent_refs(struct btrfs_root *root,
                 * extents in the FS
                 */
                cache = search_cache_extent(extent_cache, 0);
-               while(cache) {
+               while (cache) {
                        rec = container_of(cache, struct extent_record, cache);
                        set_extent_dirty(root->fs_info->excluded_extents,
                                         rec->start,
@@ -7473,7 +7493,7 @@ static int check_extent_refs(struct btrfs_root *root,
 
                /* pin down all the corrupted blocks too */
                cache = search_cache_extent(root->fs_info->corrupt_blocks, 0);
-               while(cache) {
+               while (cache) {
                        set_extent_dirty(root->fs_info->excluded_extents,
                                         cache->start,
                                         cache->start + cache->size - 1);
@@ -7518,7 +7538,7 @@ static int check_extent_refs(struct btrfs_root *root,
        if (had_dups)
                return -EAGAIN;
 
-       while(1) {
+       while (1) {
                int cur_err = 0;
                int fix = 0;
 
@@ -7527,8 +7547,9 @@ static int check_extent_refs(struct btrfs_root *root,
                        break;
                rec = container_of(cache, struct extent_record, cache);
                if (rec->num_duplicates) {
-                       fprintf(stderr, "extent item %llu has multiple extent "
-                               "items\n", (unsigned long long)rec->start);
+                       fprintf(stderr,
+                               "extent item %llu has multiple extent items\n",
+                               (unsigned long long)rec->start);
                        cur_err = 1;
                }
 
@@ -7561,7 +7582,8 @@ static int check_extent_refs(struct btrfs_root *root,
                }
 
                if (repair && fix) {
-                       ret = fixup_extent_refs(root->fs_info, extent_cache, rec);
+                       ret = fixup_extent_refs(root->fs_info, extent_cache,
+                                               rec);
                        if (ret)
                                goto repair_abort;
                }
@@ -7636,28 +7658,6 @@ repair_abort:
        return err;
 }
 
-u64 calc_stripe_length(u64 type, u64 length, int num_stripes)
-{
-       u64 stripe_size;
-
-       if (type & BTRFS_BLOCK_GROUP_RAID0) {
-               stripe_size = length;
-               stripe_size /= num_stripes;
-       } else if (type & BTRFS_BLOCK_GROUP_RAID10) {
-               stripe_size = length * 2;
-               stripe_size /= num_stripes;
-       } else if (type & BTRFS_BLOCK_GROUP_RAID5) {
-               stripe_size = length;
-               stripe_size /= (num_stripes - 1);
-       } else if (type & BTRFS_BLOCK_GROUP_RAID6) {
-               stripe_size = length;
-               stripe_size /= (num_stripes - 2);
-       } else {
-               stripe_size = length;
-       }
-       return stripe_size;
-}
-
 /*
  * Check the chunk with its block group/dev list ref:
  * Return 0 if all refs seems valid.
@@ -7943,8 +7943,8 @@ static int add_root_item_to_list(struct list_head *head,
                                  u8 level, u8 drop_level,
                                  struct btrfs_key *drop_key)
 {
-
        struct root_item_record *ri_rec;
+
        ri_rec = malloc(sizeof(*ri_rec));
        if (!ri_rec)
                return -ENOMEM;
@@ -7992,6 +7992,7 @@ static int deal_root_from_list(struct list_head *list,
        while (!list_empty(list)) {
                struct root_item_record *rec;
                struct extent_buffer *buf;
+
                rec = list_entry(list->next,
                                 struct root_item_record, list);
                last = 0;
@@ -8123,7 +8124,7 @@ again:
        ret = btrfs_search_slot(NULL, fs_info->tree_root, &key, &path, 0, 0);
        if (ret < 0)
                goto out;
-       while(1) {
+       while (1) {
                leaf = path.nodes[0];
                slot = path.slots[0];
                if (slot >= btrfs_header_nritems(path.nodes[0])) {
@@ -8257,7 +8258,7 @@ static int do_check_chunks_and_extents(struct btrfs_fs_info *fs_info)
        if (!ctx.progress_enabled)
                fprintf(stderr, "checking extents\n");
        if (check_mode == CHECK_MODE_LOWMEM)
-               ret = check_chunks_and_extents_v2(fs_info);
+               ret = check_chunks_and_extents_lowmem(fs_info);
        else
                ret = check_chunks_and_extents(fs_info);
 
@@ -9051,6 +9052,7 @@ static int build_roots_info_cache(struct btrfs_fs_info *info)
                struct btrfs_key found_key;
                struct btrfs_extent_item *ei;
                struct btrfs_extent_inline_ref *iref;
+               unsigned long item_end;
                int slot = path.slots[0];
                int type;
                u64 flags;
@@ -9079,6 +9081,7 @@ static int build_roots_info_cache(struct btrfs_fs_info *info)
 
                ei = btrfs_item_ptr(leaf, slot, struct btrfs_extent_item);
                flags = btrfs_extent_flags(leaf, ei);
+               item_end = (unsigned long)ei + btrfs_item_size_nr(leaf, slot);
 
                if (found_key.type == BTRFS_EXTENT_ITEM_KEY &&
                    !(flags & BTRFS_EXTENT_FLAG_TREE_BLOCK))
@@ -9096,6 +9099,15 @@ static int build_roots_info_cache(struct btrfs_fs_info *info)
                }
 
                /*
+                * It's a valid extent/metadata item that has no inline ref,
+                * but SHARED_BLOCK_REF or other shared references.
+                * So we need to do extra check to avoid reading beyond leaf
+                * boudnary.
+                */
+               if ((unsigned long)iref >= item_end)
+                       goto next;
+
+               /*
                 * For a root extent, it must be of the following type and the
                 * first (and only one) iref in the item.
                 */