btrfs-progs: check: introduce function to check dir_item
[platform/upstream/btrfs-progs.git] / extent-tree.c
index 6cc8d3f..b52c515 100644 (file)
@@ -1664,7 +1664,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
                cond_resched();
                if (level == 0) {
                        btrfs_item_key_to_cpu(buf, &key, i);
-                       if (btrfs_key_type(&key) != BTRFS_EXTENT_DATA_KEY)
+                       if (key.type != BTRFS_EXTENT_DATA_KEY)
                                continue;
                        fi = btrfs_item_ptr(buf, i,
                                            struct btrfs_file_extent_item);
@@ -2467,6 +2467,17 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
        return err;
 }
 
+
+int btrfs_free_tree_block(struct btrfs_trans_handle *trans,
+                         struct btrfs_root *root,
+                         struct extent_buffer *buf,
+                         u64 parent, int last_ref)
+{
+       return btrfs_free_extent(trans, root, buf->start, buf->len, parent,
+                                root->root_key.objectid,
+                                btrfs_header_level(buf), 0);
+}
+
 /*
  * remove an extent from the root, returns 0 on success
  */
@@ -2538,7 +2549,7 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
        int wrapped = 0;
 
        WARN_ON(num_bytes < root->sectorsize);
-       btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
+       ins->type = BTRFS_EXTENT_ITEM_KEY;
 
        search_start = stripe_align(root, search_start);
 
@@ -2606,11 +2617,20 @@ check_failed:
        }
 
        if (!(data & BTRFS_BLOCK_GROUP_DATA)) {
-               if (check_crossing_stripes(ins->objectid, num_bytes)) {
-                       search_start = round_down(ins->objectid + num_bytes,
-                                                 BTRFS_STRIPE_LEN);
+               if (check_crossing_stripes(info, ins->objectid, num_bytes)) {
+                       struct btrfs_block_group_cache *bg_cache;
+                       u64 bg_offset;
+
+                       bg_cache = btrfs_lookup_block_group(info, ins->objectid);
+                       if (!bg_cache)
+                               goto no_bg_cache;
+                       bg_offset = ins->objectid - bg_cache->key.objectid;
+
+                       search_start = round_up(bg_offset + num_bytes,
+                                               BTRFS_STRIPE_LEN) + bg_offset;
                        goto new_group;
                }
+no_bg_cache:
                block_group = btrfs_lookup_block_group(info, ins->objectid);
                if (block_group)
                        trans->block_group = block_group;
@@ -2714,7 +2734,8 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
                size += sizeof(*block_info);
 
        path = btrfs_alloc_path();
-       BUG_ON(!path);
+       if (!path)
+               return -ENOMEM;
 
        ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path,
                                      ins, size);
@@ -3230,7 +3251,7 @@ int btrfs_read_block_groups(struct btrfs_root *root)
        root = info->extent_root;
        key.objectid = 0;
        key.offset = 0;
-       btrfs_set_key_type(&key, BTRFS_BLOCK_GROUP_ITEM_KEY);
+       key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
@@ -3259,6 +3280,8 @@ int btrfs_read_block_groups(struct btrfs_root *root)
                cache->cached = 0;
                cache->pinned = 0;
                key.objectid = found_key.objectid + found_key.offset;
+               if (found_key.offset == 0)
+                       key.objectid++;
                btrfs_release_path(path);
                cache->flags = btrfs_block_group_flags(&cache->item);
                bit = 0;
@@ -3310,7 +3333,7 @@ btrfs_add_block_group(struct btrfs_fs_info *fs_info, u64 bytes_used, u64 type,
        cache->key.objectid = chunk_offset;
        cache->key.offset = size;
 
-       btrfs_set_key_type(&cache->key, BTRFS_BLOCK_GROUP_ITEM_KEY);
+       cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
        btrfs_set_block_group_used(&cache->item, bytes_used);
        btrfs_set_block_group_chunk_objectid(&cache->item, chunk_objectid);
        cache->flags = type;
@@ -3422,7 +3445,7 @@ int btrfs_make_block_groups(struct btrfs_trans_handle *trans,
 
                cache->key.objectid = cur_start;
                cache->key.offset = group_size;
-               btrfs_set_key_type(&cache->key, BTRFS_BLOCK_GROUP_ITEM_KEY);
+               cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
 
                btrfs_set_block_group_used(&cache->item, 0);
                btrfs_set_block_group_chunk_objectid(&cache->item,
@@ -3866,7 +3889,7 @@ int btrfs_fix_block_accounting(struct btrfs_trans_handle *trans,
        btrfs_init_path(&path);
        key.offset = 0;
        key.objectid = 0;
-       btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
+       key.type = BTRFS_EXTENT_ITEM_KEY;
        ret = btrfs_search_slot(trans, root->fs_info->extent_root,
                                &key, &path, 0, 0);
        if (ret < 0)
@@ -4058,7 +4081,7 @@ static int __btrfs_record_file_extent(struct btrfs_trans_handle *trans,
        btrfs_release_path(path);
        ins_key.objectid = objectid;
        ins_key.offset = file_pos;
-       btrfs_set_key_type(&ins_key, BTRFS_EXTENT_DATA_KEY);
+       ins_key.type = BTRFS_EXTENT_DATA_KEY;
        ret = btrfs_insert_empty_item(trans, root, path, &ins_key,
                                      sizeof(*fi));
        if (ret)