|
@@ -597,6 +597,7 @@ static int __add_inline_refs(struct btrfs_fs_info *fs_info,
|
|
|
int slot;
|
|
|
struct extent_buffer *leaf;
|
|
|
struct btrfs_key key;
|
|
|
+ struct btrfs_key found_key;
|
|
|
unsigned long ptr;
|
|
|
unsigned long end;
|
|
|
struct btrfs_extent_item *ei;
|
|
@@ -614,17 +615,21 @@ static int __add_inline_refs(struct btrfs_fs_info *fs_info,
|
|
|
|
|
|
ei = btrfs_item_ptr(leaf, slot, struct btrfs_extent_item);
|
|
|
flags = btrfs_extent_flags(leaf, ei);
|
|
|
+ btrfs_item_key_to_cpu(leaf, &found_key, slot);
|
|
|
|
|
|
ptr = (unsigned long)(ei + 1);
|
|
|
end = (unsigned long)ei + item_size;
|
|
|
|
|
|
- if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
|
|
|
+ if (found_key.type == BTRFS_EXTENT_ITEM_KEY &&
|
|
|
+ flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
|
|
|
struct btrfs_tree_block_info *info;
|
|
|
|
|
|
info = (struct btrfs_tree_block_info *)ptr;
|
|
|
*info_level = btrfs_tree_block_level(leaf, info);
|
|
|
ptr += sizeof(struct btrfs_tree_block_info);
|
|
|
BUG_ON(ptr > end);
|
|
|
+ } else if (found_key.type == BTRFS_METADATA_ITEM_KEY) {
|
|
|
+ *info_level = found_key.offset;
|
|
|
} else {
|
|
|
BUG_ON(!(flags & BTRFS_EXTENT_FLAG_DATA));
|
|
|
}
|
|
@@ -796,8 +801,11 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
|
|
|
INIT_LIST_HEAD(&prefs_delayed);
|
|
|
|
|
|
key.objectid = bytenr;
|
|
|
- key.type = BTRFS_EXTENT_ITEM_KEY;
|
|
|
key.offset = (u64)-1;
|
|
|
+ if (btrfs_fs_incompat(fs_info, SKINNY_METADATA))
|
|
|
+ key.type = BTRFS_METADATA_ITEM_KEY;
|
|
|
+ else
|
|
|
+ key.type = BTRFS_EXTENT_ITEM_KEY;
|
|
|
|
|
|
path = btrfs_alloc_path();
|
|
|
if (!path)
|
|
@@ -862,7 +870,8 @@ again:
|
|
|
slot = path->slots[0];
|
|
|
btrfs_item_key_to_cpu(leaf, &key, slot);
|
|
|
if (key.objectid == bytenr &&
|
|
|
- key.type == BTRFS_EXTENT_ITEM_KEY) {
|
|
|
+ (key.type == BTRFS_EXTENT_ITEM_KEY ||
|
|
|
+ key.type == BTRFS_METADATA_ITEM_KEY)) {
|
|
|
ret = __add_inline_refs(fs_info, path, bytenr,
|
|
|
&info_level, &prefs);
|
|
|
if (ret)
|
|
@@ -1276,12 +1285,16 @@ int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
|
|
|
{
|
|
|
int ret;
|
|
|
u64 flags;
|
|
|
+ u64 size = 0;
|
|
|
u32 item_size;
|
|
|
struct extent_buffer *eb;
|
|
|
struct btrfs_extent_item *ei;
|
|
|
struct btrfs_key key;
|
|
|
|
|
|
- key.type = BTRFS_EXTENT_ITEM_KEY;
|
|
|
+ if (btrfs_fs_incompat(fs_info, SKINNY_METADATA))
|
|
|
+ key.type = BTRFS_METADATA_ITEM_KEY;
|
|
|
+ else
|
|
|
+ key.type = BTRFS_EXTENT_ITEM_KEY;
|
|
|
key.objectid = logical;
|
|
|
key.offset = (u64)-1;
|
|
|
|
|
@@ -1294,9 +1307,15 @@ int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
|
|
|
return ret;
|
|
|
|
|
|
btrfs_item_key_to_cpu(path->nodes[0], found_key, path->slots[0]);
|
|
|
- if (found_key->type != BTRFS_EXTENT_ITEM_KEY ||
|
|
|
+ if (found_key->type == BTRFS_METADATA_ITEM_KEY)
|
|
|
+ size = fs_info->extent_root->leafsize;
|
|
|
+ else if (found_key->type == BTRFS_EXTENT_ITEM_KEY)
|
|
|
+ size = found_key->offset;
|
|
|
+
|
|
|
+ if ((found_key->type != BTRFS_EXTENT_ITEM_KEY &&
|
|
|
+ found_key->type != BTRFS_METADATA_ITEM_KEY) ||
|
|
|
found_key->objectid > logical ||
|
|
|
- found_key->objectid + found_key->offset <= logical) {
|
|
|
+ found_key->objectid + size <= logical) {
|
|
|
pr_debug("logical %llu is not within any extent\n",
|
|
|
(unsigned long long)logical);
|
|
|
return -ENOENT;
|