aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.c3
-rw-r--r--fs/btrfs/ctree.h22
-rw-r--r--fs/btrfs/disk-io.c3
-rw-r--r--fs/btrfs/extent-tree.c224
-rw-r--r--fs/btrfs/inode.c2
-rw-r--r--fs/btrfs/relocation.c73
-rw-r--r--fs/btrfs/scrub.c30
7 files changed, 290 insertions, 67 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index ca9d8f1a3bb6..fe032ab6bd8a 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -867,7 +867,8 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
867 867
868 if (btrfs_block_can_be_shared(root, buf)) { 868 if (btrfs_block_can_be_shared(root, buf)) {
869 ret = btrfs_lookup_extent_info(trans, root, buf->start, 869 ret = btrfs_lookup_extent_info(trans, root, buf->start,
870 buf->len, &refs, &flags); 870 btrfs_header_level(buf), 1,
871 &refs, &flags);
871 if (ret) 872 if (ret)
872 return ret; 873 return ret;
873 if (refs == 0) { 874 if (refs == 0) {
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index e2f14b5258b6..efb2feb7cd4a 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -509,6 +509,7 @@ struct btrfs_super_block {
509 509
510#define BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF (1ULL << 6) 510#define BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF (1ULL << 6)
511#define BTRFS_FEATURE_INCOMPAT_RAID56 (1ULL << 7) 511#define BTRFS_FEATURE_INCOMPAT_RAID56 (1ULL << 7)
512#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8)
512 513
513#define BTRFS_FEATURE_COMPAT_SUPP 0ULL 514#define BTRFS_FEATURE_COMPAT_SUPP 0ULL
514#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL 515#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL
@@ -519,7 +520,8 @@ struct btrfs_super_block {
519 BTRFS_FEATURE_INCOMPAT_BIG_METADATA | \ 520 BTRFS_FEATURE_INCOMPAT_BIG_METADATA | \
520 BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO | \ 521 BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO | \
521 BTRFS_FEATURE_INCOMPAT_RAID56 | \ 522 BTRFS_FEATURE_INCOMPAT_RAID56 | \
522 BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF) 523 BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF | \
524 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA)
523 525
524/* 526/*
525 * A leaf is full of items. offset and size tell us where to find 527 * A leaf is full of items. offset and size tell us where to find
@@ -1809,6 +1811,12 @@ struct btrfs_ioctl_defrag_range_args {
1809 */ 1811 */
1810#define BTRFS_EXTENT_ITEM_KEY 168 1812#define BTRFS_EXTENT_ITEM_KEY 168
1811 1813
1814/*
1815 * The same as the BTRFS_EXTENT_ITEM_KEY, except it's metadata we already know
1816 * the length, so we save the level in key->offset instead of the length.
1817 */
1818#define BTRFS_METADATA_ITEM_KEY 169
1819
1812#define BTRFS_TREE_BLOCK_REF_KEY 176 1820#define BTRFS_TREE_BLOCK_REF_KEY 176
1813 1821
1814#define BTRFS_EXTENT_DATA_REF_KEY 178 1822#define BTRFS_EXTENT_DATA_REF_KEY 178
@@ -3006,7 +3014,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
3006int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len); 3014int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len);
3007int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, 3015int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
3008 struct btrfs_root *root, u64 bytenr, 3016 struct btrfs_root *root, u64 bytenr,
3009 u64 num_bytes, u64 *refs, u64 *flags); 3017 u64 offset, int metadata, u64 *refs, u64 *flags);
3010int btrfs_pin_extent(struct btrfs_root *root, 3018int btrfs_pin_extent(struct btrfs_root *root,
3011 u64 bytenr, u64 num, int reserved); 3019 u64 bytenr, u64 num, int reserved);
3012int btrfs_pin_extent_for_log_replay(struct btrfs_root *root, 3020int btrfs_pin_extent_for_log_replay(struct btrfs_root *root,
@@ -3669,6 +3677,16 @@ static inline void __btrfs_set_fs_incompat(struct btrfs_fs_info *fs_info,
3669 } 3677 }
3670} 3678}
3671 3679
3680#define btrfs_fs_incompat(fs_info, opt) \
3681 __btrfs_fs_incompat((fs_info), BTRFS_FEATURE_INCOMPAT_##opt)
3682
3683static inline int __btrfs_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag)
3684{
3685 struct btrfs_super_block *disk_super;
3686 disk_super = fs_info->super_copy;
3687 return !!(btrfs_super_incompat_flags(disk_super) & flag);
3688}
3689
3672/* 3690/*
3673 * Call btrfs_abort_transaction as early as possible when an error condition is 3691 * Call btrfs_abort_transaction as early as possible when an error condition is
3674 * detected, that way the exact line number is reported. 3692 * detected, that way the exact line number is reported.
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index e0665488e512..f47754a2fee4 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2290,6 +2290,9 @@ int open_ctree(struct super_block *sb,
2290 if (tree_root->fs_info->compress_type == BTRFS_COMPRESS_LZO) 2290 if (tree_root->fs_info->compress_type == BTRFS_COMPRESS_LZO)
2291 features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO; 2291 features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
2292 2292
2293 if (features & BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA)
2294 printk(KERN_ERR "btrfs: has skinny extents\n");
2295
2293 /* 2296 /*
2294 * flag our filesystem as having big metadata blocks if 2297 * flag our filesystem as having big metadata blocks if
2295 * they are bigger than the page size 2298 * they are bigger than the page size
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 3d551231caba..7505856df9f3 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -442,11 +442,16 @@ again:
442 block_group->key.offset) 442 block_group->key.offset)
443 break; 443 break;
444 444
445 if (key.type == BTRFS_EXTENT_ITEM_KEY) { 445 if (key.type == BTRFS_EXTENT_ITEM_KEY ||
446 key.type == BTRFS_METADATA_ITEM_KEY) {
446 total_found += add_new_free_space(block_group, 447 total_found += add_new_free_space(block_group,
447 fs_info, last, 448 fs_info, last,
448 key.objectid); 449 key.objectid);
449 last = key.objectid + key.offset; 450 if (key.type == BTRFS_METADATA_ITEM_KEY)
451 last = key.objectid +
452 fs_info->tree_root->leafsize;
453 else
454 last = key.objectid + key.offset;
450 455
451 if (total_found > (1024 * 1024 * 2)) { 456 if (total_found > (1024 * 1024 * 2)) {
452 total_found = 0; 457 total_found = 0;
@@ -718,15 +723,21 @@ int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len)
718 723
719 key.objectid = start; 724 key.objectid = start;
720 key.offset = len; 725 key.offset = len;
721 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 726 key.type = BTRFS_EXTENT_ITEM_KEY;
722 ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path, 727 ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path,
723 0, 0); 728 0, 0);
729 if (ret > 0) {
730 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
731 if (key.objectid == start &&
732 key.type == BTRFS_METADATA_ITEM_KEY)
733 ret = 0;
734 }
724 btrfs_free_path(path); 735 btrfs_free_path(path);
725 return ret; 736 return ret;
726} 737}
727 738
728/* 739/*
729 * helper function to lookup reference count and flags of extent. 740 * helper function to lookup reference count and flags of a tree block.
730 * 741 *
731 * the head node for delayed ref is used to store the sum of all the 742 * the head node for delayed ref is used to store the sum of all the
732 * reference count modifications queued up in the rbtree. the head 743 * reference count modifications queued up in the rbtree. the head
@@ -736,7 +747,7 @@ int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len)
736 */ 747 */
737int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans, 748int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
738 struct btrfs_root *root, u64 bytenr, 749 struct btrfs_root *root, u64 bytenr,
739 u64 num_bytes, u64 *refs, u64 *flags) 750 u64 offset, int metadata, u64 *refs, u64 *flags)
740{ 751{
741 struct btrfs_delayed_ref_head *head; 752 struct btrfs_delayed_ref_head *head;
742 struct btrfs_delayed_ref_root *delayed_refs; 753 struct btrfs_delayed_ref_root *delayed_refs;
@@ -749,13 +760,29 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
749 u64 extent_flags; 760 u64 extent_flags;
750 int ret; 761 int ret;
751 762
763 /*
764 * If we don't have skinny metadata, don't bother doing anything
765 * different
766 */
767 if (metadata && !btrfs_fs_incompat(root->fs_info, SKINNY_METADATA)) {
768 offset = root->leafsize;
769 metadata = 0;
770 }
771
752 path = btrfs_alloc_path(); 772 path = btrfs_alloc_path();
753 if (!path) 773 if (!path)
754 return -ENOMEM; 774 return -ENOMEM;
755 775
756 key.objectid = bytenr; 776 if (metadata) {
757 key.type = BTRFS_EXTENT_ITEM_KEY; 777 key.objectid = bytenr;
758 key.offset = num_bytes; 778 key.type = BTRFS_METADATA_ITEM_KEY;
779 key.offset = offset;
780 } else {
781 key.objectid = bytenr;
782 key.type = BTRFS_EXTENT_ITEM_KEY;
783 key.offset = offset;
784 }
785
759 if (!trans) { 786 if (!trans) {
760 path->skip_locking = 1; 787 path->skip_locking = 1;
761 path->search_commit_root = 1; 788 path->search_commit_root = 1;
@@ -766,6 +793,13 @@ again:
766 if (ret < 0) 793 if (ret < 0)
767 goto out_free; 794 goto out_free;
768 795
796 if (ret > 0 && metadata && key.type == BTRFS_METADATA_ITEM_KEY) {
797 key.type = BTRFS_EXTENT_ITEM_KEY;
798 key.offset = root->leafsize;
799 btrfs_release_path(path);
800 goto again;
801 }
802
769 if (ret == 0) { 803 if (ret == 0) {
770 leaf = path->nodes[0]; 804 leaf = path->nodes[0];
771 item_size = btrfs_item_size_nr(leaf, path->slots[0]); 805 item_size = btrfs_item_size_nr(leaf, path->slots[0]);
@@ -1453,6 +1487,8 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
1453 int want; 1487 int want;
1454 int ret; 1488 int ret;
1455 int err = 0; 1489 int err = 0;
1490 bool skinny_metadata = btrfs_fs_incompat(root->fs_info,
1491 SKINNY_METADATA);
1456 1492
1457 key.objectid = bytenr; 1493 key.objectid = bytenr;
1458 key.type = BTRFS_EXTENT_ITEM_KEY; 1494 key.type = BTRFS_EXTENT_ITEM_KEY;
@@ -1464,11 +1500,46 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
1464 path->keep_locks = 1; 1500 path->keep_locks = 1;
1465 } else 1501 } else
1466 extra_size = -1; 1502 extra_size = -1;
1503
1504 /*
1505 * Owner is our parent level, so we can just add one to get the level
1506 * for the block we are interested in.
1507 */
1508 if (skinny_metadata && owner < BTRFS_FIRST_FREE_OBJECTID) {
1509 key.type = BTRFS_METADATA_ITEM_KEY;
1510 key.offset = owner;
1511 }
1512
1513again:
1467 ret = btrfs_search_slot(trans, root, &key, path, extra_size, 1); 1514 ret = btrfs_search_slot(trans, root, &key, path, extra_size, 1);
1468 if (ret < 0) { 1515 if (ret < 0) {
1469 err = ret; 1516 err = ret;
1470 goto out; 1517 goto out;
1471 } 1518 }
1519
1520 /*
1521 * We may be a newly converted file system which still has the old fat
1522 * extent entries for metadata, so try and see if we have one of those.
1523 */
1524 if (ret > 0 && skinny_metadata) {
1525 skinny_metadata = false;
1526 if (path->slots[0]) {
1527 path->slots[0]--;
1528 btrfs_item_key_to_cpu(path->nodes[0], &key,
1529 path->slots[0]);
1530 if (key.objectid == bytenr &&
1531 key.type == BTRFS_EXTENT_ITEM_KEY &&
1532 key.offset == num_bytes)
1533 ret = 0;
1534 }
1535 if (ret) {
1536 key.type = BTRFS_EXTENT_ITEM_KEY;
1537 key.offset = num_bytes;
1538 btrfs_release_path(path);
1539 goto again;
1540 }
1541 }
1542
1472 if (ret && !insert) { 1543 if (ret && !insert) {
1473 err = -ENOENT; 1544 err = -ENOENT;
1474 goto out; 1545 goto out;
@@ -1504,11 +1575,9 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans,
1504 ptr = (unsigned long)(ei + 1); 1575 ptr = (unsigned long)(ei + 1);
1505 end = (unsigned long)ei + item_size; 1576 end = (unsigned long)ei + item_size;
1506 1577
1507 if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) { 1578 if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK && !skinny_metadata) {
1508 ptr += sizeof(struct btrfs_tree_block_info); 1579 ptr += sizeof(struct btrfs_tree_block_info);
1509 BUG_ON(ptr > end); 1580 BUG_ON(ptr > end);
1510 } else {
1511 BUG_ON(!(flags & BTRFS_EXTENT_FLAG_DATA));
1512 } 1581 }
1513 1582
1514 err = -ENOENT; 1583 err = -ENOENT;
@@ -1973,10 +2042,8 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans,
1973 ref_root = ref->root; 2042 ref_root = ref->root;
1974 2043
1975 if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { 2044 if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) {
1976 if (extent_op) { 2045 if (extent_op)
1977 BUG_ON(extent_op->update_key);
1978 flags |= extent_op->flags_to_set; 2046 flags |= extent_op->flags_to_set;
1979 }
1980 ret = alloc_reserved_file_extent(trans, root, 2047 ret = alloc_reserved_file_extent(trans, root,
1981 parent, ref_root, flags, 2048 parent, ref_root, flags,
1982 ref->objectid, ref->offset, 2049 ref->objectid, ref->offset,
@@ -2029,18 +2096,33 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans,
2029 u32 item_size; 2096 u32 item_size;
2030 int ret; 2097 int ret;
2031 int err = 0; 2098 int err = 0;
2099 int metadata = (node->type == BTRFS_TREE_BLOCK_REF_KEY ||
2100 node->type == BTRFS_SHARED_BLOCK_REF_KEY);
2032 2101
2033 if (trans->aborted) 2102 if (trans->aborted)
2034 return 0; 2103 return 0;
2035 2104
2105 if (metadata && !btrfs_fs_incompat(root->fs_info, SKINNY_METADATA))
2106 metadata = 0;
2107
2036 path = btrfs_alloc_path(); 2108 path = btrfs_alloc_path();
2037 if (!path) 2109 if (!path)
2038 return -ENOMEM; 2110 return -ENOMEM;
2039 2111
2040 key.objectid = node->bytenr; 2112 key.objectid = node->bytenr;
2041 key.type = BTRFS_EXTENT_ITEM_KEY;
2042 key.offset = node->num_bytes;
2043 2113
2114 if (metadata) {
2115 struct btrfs_delayed_tree_ref *tree_ref;
2116
2117 tree_ref = btrfs_delayed_node_to_tree_ref(node);
2118 key.type = BTRFS_METADATA_ITEM_KEY;
2119 key.offset = tree_ref->level;
2120 } else {
2121 key.type = BTRFS_EXTENT_ITEM_KEY;
2122 key.offset = node->num_bytes;
2123 }
2124
2125again:
2044 path->reada = 1; 2126 path->reada = 1;
2045 path->leave_spinning = 1; 2127 path->leave_spinning = 1;
2046 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, 2128 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key,
@@ -2050,6 +2132,14 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans,
2050 goto out; 2132 goto out;
2051 } 2133 }
2052 if (ret > 0) { 2134 if (ret > 0) {
2135 if (metadata) {
2136 btrfs_release_path(path);
2137 metadata = 0;
2138
2139 key.offset = node->num_bytes;
2140 key.type = BTRFS_EXTENT_ITEM_KEY;
2141 goto again;
2142 }
2053 err = -EIO; 2143 err = -EIO;
2054 goto out; 2144 goto out;
2055 } 2145 }
@@ -2089,10 +2179,8 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
2089 struct btrfs_key ins; 2179 struct btrfs_key ins;
2090 u64 parent = 0; 2180 u64 parent = 0;
2091 u64 ref_root = 0; 2181 u64 ref_root = 0;
2092 2182 bool skinny_metadata = btrfs_fs_incompat(root->fs_info,
2093 ins.objectid = node->bytenr; 2183 SKINNY_METADATA);
2094 ins.offset = node->num_bytes;
2095 ins.type = BTRFS_EXTENT_ITEM_KEY;
2096 2184
2097 ref = btrfs_delayed_node_to_tree_ref(node); 2185 ref = btrfs_delayed_node_to_tree_ref(node);
2098 if (node->type == BTRFS_SHARED_BLOCK_REF_KEY) 2186 if (node->type == BTRFS_SHARED_BLOCK_REF_KEY)
@@ -2100,10 +2188,18 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
2100 else 2188 else
2101 ref_root = ref->root; 2189 ref_root = ref->root;
2102 2190
2191 ins.objectid = node->bytenr;
2192 if (skinny_metadata) {
2193 ins.offset = ref->level;
2194 ins.type = BTRFS_METADATA_ITEM_KEY;
2195 } else {
2196 ins.offset = node->num_bytes;
2197 ins.type = BTRFS_EXTENT_ITEM_KEY;
2198 }
2199
2103 BUG_ON(node->ref_mod != 1); 2200 BUG_ON(node->ref_mod != 1);
2104 if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) { 2201 if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) {
2105 BUG_ON(!extent_op || !extent_op->update_flags || 2202 BUG_ON(!extent_op || !extent_op->update_flags);
2106 !extent_op->update_key);
2107 ret = alloc_reserved_tree_block(trans, root, 2203 ret = alloc_reserved_tree_block(trans, root,
2108 parent, ref_root, 2204 parent, ref_root,
2109 extent_op->flags_to_set, 2205 extent_op->flags_to_set,
@@ -5312,6 +5408,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
5312 int num_to_del = 1; 5408 int num_to_del = 1;
5313 u32 item_size; 5409 u32 item_size;
5314 u64 refs; 5410 u64 refs;
5411 bool skinny_metadata = btrfs_fs_incompat(root->fs_info,
5412 SKINNY_METADATA);
5315 5413
5316 path = btrfs_alloc_path(); 5414 path = btrfs_alloc_path();
5317 if (!path) 5415 if (!path)
@@ -5323,6 +5421,9 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
5323 is_data = owner_objectid >= BTRFS_FIRST_FREE_OBJECTID; 5421 is_data = owner_objectid >= BTRFS_FIRST_FREE_OBJECTID;
5324 BUG_ON(!is_data && refs_to_drop != 1); 5422 BUG_ON(!is_data && refs_to_drop != 1);
5325 5423
5424 if (is_data)
5425 skinny_metadata = 0;
5426
5326 ret = lookup_extent_backref(trans, extent_root, path, &iref, 5427 ret = lookup_extent_backref(trans, extent_root, path, &iref,
5327 bytenr, num_bytes, parent, 5428 bytenr, num_bytes, parent,
5328 root_objectid, owner_objectid, 5429 root_objectid, owner_objectid,
@@ -5339,6 +5440,11 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
5339 found_extent = 1; 5440 found_extent = 1;
5340 break; 5441 break;
5341 } 5442 }
5443 if (key.type == BTRFS_METADATA_ITEM_KEY &&
5444 key.offset == owner_objectid) {
5445 found_extent = 1;
5446 break;
5447 }
5342 if (path->slots[0] - extent_slot > 5) 5448 if (path->slots[0] - extent_slot > 5)
5343 break; 5449 break;
5344 extent_slot--; 5450 extent_slot--;
@@ -5364,8 +5470,36 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
5364 key.type = BTRFS_EXTENT_ITEM_KEY; 5470 key.type = BTRFS_EXTENT_ITEM_KEY;
5365 key.offset = num_bytes; 5471 key.offset = num_bytes;
5366 5472
5473 if (!is_data && skinny_metadata) {
5474 key.type = BTRFS_METADATA_ITEM_KEY;
5475 key.offset = owner_objectid;
5476 }
5477
5367 ret = btrfs_search_slot(trans, extent_root, 5478 ret = btrfs_search_slot(trans, extent_root,
5368 &key, path, -1, 1); 5479 &key, path, -1, 1);
5480 if (ret > 0 && skinny_metadata && path->slots[0]) {
5481 /*
5482 * Couldn't find our skinny metadata item,
5483 * see if we have ye olde extent item.
5484 */
5485 path->slots[0]--;
5486 btrfs_item_key_to_cpu(path->nodes[0], &key,
5487 path->slots[0]);
5488 if (key.objectid == bytenr &&
5489 key.type == BTRFS_EXTENT_ITEM_KEY &&
5490 key.offset == num_bytes)
5491 ret = 0;
5492 }
5493
5494 if (ret > 0 && skinny_metadata) {
5495 skinny_metadata = false;
5496 key.type = BTRFS_EXTENT_ITEM_KEY;
5497 key.offset = num_bytes;
5498 btrfs_release_path(path);
5499 ret = btrfs_search_slot(trans, extent_root,
5500 &key, path, -1, 1);
5501 }
5502
5369 if (ret) { 5503 if (ret) {
5370 printk(KERN_ERR "umm, got %d back from search" 5504 printk(KERN_ERR "umm, got %d back from search"
5371 ", was looking for %llu\n", ret, 5505 ", was looking for %llu\n", ret,
@@ -5435,7 +5569,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
5435 BUG_ON(item_size < sizeof(*ei)); 5569 BUG_ON(item_size < sizeof(*ei));
5436 ei = btrfs_item_ptr(leaf, extent_slot, 5570 ei = btrfs_item_ptr(leaf, extent_slot,
5437 struct btrfs_extent_item); 5571 struct btrfs_extent_item);
5438 if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID) { 5572 if (owner_objectid < BTRFS_FIRST_FREE_OBJECTID &&
5573 key.type == BTRFS_EXTENT_ITEM_KEY) {
5439 struct btrfs_tree_block_info *bi; 5574 struct btrfs_tree_block_info *bi;
5440 BUG_ON(item_size < sizeof(*ei) + sizeof(*bi)); 5575 BUG_ON(item_size < sizeof(*ei) + sizeof(*bi));
5441 bi = (struct btrfs_tree_block_info *)(ei + 1); 5576 bi = (struct btrfs_tree_block_info *)(ei + 1);
@@ -6349,7 +6484,12 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
6349 struct btrfs_extent_inline_ref *iref; 6484 struct btrfs_extent_inline_ref *iref;
6350 struct btrfs_path *path; 6485 struct btrfs_path *path;
6351 struct extent_buffer *leaf; 6486 struct extent_buffer *leaf;
6352 u32 size = sizeof(*extent_item) + sizeof(*block_info) + sizeof(*iref); 6487 u32 size = sizeof(*extent_item) + sizeof(*iref);
6488 bool skinny_metadata = btrfs_fs_incompat(root->fs_info,
6489 SKINNY_METADATA);
6490
6491 if (!skinny_metadata)
6492 size += sizeof(*block_info);
6353 6493
6354 path = btrfs_alloc_path(); 6494 path = btrfs_alloc_path();
6355 if (!path) 6495 if (!path)
@@ -6370,12 +6510,16 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
6370 btrfs_set_extent_generation(leaf, extent_item, trans->transid); 6510 btrfs_set_extent_generation(leaf, extent_item, trans->transid);
6371 btrfs_set_extent_flags(leaf, extent_item, 6511 btrfs_set_extent_flags(leaf, extent_item,
6372 flags | BTRFS_EXTENT_FLAG_TREE_BLOCK); 6512 flags | BTRFS_EXTENT_FLAG_TREE_BLOCK);
6373 block_info = (struct btrfs_tree_block_info *)(extent_item + 1);
6374 6513
6375 btrfs_set_tree_block_key(leaf, block_info, key); 6514 if (skinny_metadata) {
6376 btrfs_set_tree_block_level(leaf, block_info, level); 6515 iref = (struct btrfs_extent_inline_ref *)(extent_item + 1);
6516 } else {
6517 block_info = (struct btrfs_tree_block_info *)(extent_item + 1);
6518 btrfs_set_tree_block_key(leaf, block_info, key);
6519 btrfs_set_tree_block_level(leaf, block_info, level);
6520 iref = (struct btrfs_extent_inline_ref *)(block_info + 1);
6521 }
6377 6522
6378 iref = (struct btrfs_extent_inline_ref *)(block_info + 1);
6379 if (parent > 0) { 6523 if (parent > 0) {
6380 BUG_ON(!(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)); 6524 BUG_ON(!(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF));
6381 btrfs_set_extent_inline_ref_type(leaf, iref, 6525 btrfs_set_extent_inline_ref_type(leaf, iref,
@@ -6390,7 +6534,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
6390 btrfs_mark_buffer_dirty(leaf); 6534 btrfs_mark_buffer_dirty(leaf);
6391 btrfs_free_path(path); 6535 btrfs_free_path(path);
6392 6536
6393 ret = update_block_group(root, ins->objectid, ins->offset, 1); 6537 ret = update_block_group(root, ins->objectid, root->leafsize, 1);
6394 if (ret) { /* -ENOENT, logic error */ 6538 if (ret) { /* -ENOENT, logic error */
6395 printk(KERN_ERR "btrfs update block group failed for %llu " 6539 printk(KERN_ERR "btrfs update block group failed for %llu "
6396 "%llu\n", (unsigned long long)ins->objectid, 6540 "%llu\n", (unsigned long long)ins->objectid,
@@ -6594,7 +6738,8 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
6594 struct extent_buffer *buf; 6738 struct extent_buffer *buf;
6595 u64 flags = 0; 6739 u64 flags = 0;
6596 int ret; 6740 int ret;
6597 6741 bool skinny_metadata = btrfs_fs_incompat(root->fs_info,
6742 SKINNY_METADATA);
6598 6743
6599 block_rsv = use_block_rsv(trans, root, blocksize); 6744 block_rsv = use_block_rsv(trans, root, blocksize);
6600 if (IS_ERR(block_rsv)) 6745 if (IS_ERR(block_rsv))
@@ -6627,7 +6772,10 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
6627 else 6772 else
6628 memset(&extent_op->key, 0, sizeof(extent_op->key)); 6773 memset(&extent_op->key, 0, sizeof(extent_op->key));
6629 extent_op->flags_to_set = flags; 6774 extent_op->flags_to_set = flags;
6630 extent_op->update_key = 1; 6775 if (skinny_metadata)
6776 extent_op->update_key = 0;
6777 else
6778 extent_op->update_key = 1;
6631 extent_op->update_flags = 1; 6779 extent_op->update_flags = 1;
6632 extent_op->is_data = 0; 6780 extent_op->is_data = 0;
6633 6781
@@ -6704,8 +6852,9 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans,
6704 continue; 6852 continue;
6705 6853
6706 /* We don't lock the tree block, it's OK to be racy here */ 6854 /* We don't lock the tree block, it's OK to be racy here */
6707 ret = btrfs_lookup_extent_info(trans, root, bytenr, blocksize, 6855 ret = btrfs_lookup_extent_info(trans, root, bytenr,
6708 &refs, &flags); 6856 wc->level - 1, 1, &refs,
6857 &flags);
6709 /* We don't care about errors in readahead. */ 6858 /* We don't care about errors in readahead. */
6710 if (ret < 0) 6859 if (ret < 0)
6711 continue; 6860 continue;
@@ -6772,7 +6921,7 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,
6772 (wc->stage == UPDATE_BACKREF && !(wc->flags[level] & flag)))) { 6921 (wc->stage == UPDATE_BACKREF && !(wc->flags[level] & flag)))) {
6773 BUG_ON(!path->locks[level]); 6922 BUG_ON(!path->locks[level]);
6774 ret = btrfs_lookup_extent_info(trans, root, 6923 ret = btrfs_lookup_extent_info(trans, root,
6775 eb->start, eb->len, 6924 eb->start, level, 1,
6776 &wc->refs[level], 6925 &wc->refs[level],
6777 &wc->flags[level]); 6926 &wc->flags[level]);
6778 BUG_ON(ret == -ENOMEM); 6927 BUG_ON(ret == -ENOMEM);
@@ -6870,7 +7019,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
6870 btrfs_tree_lock(next); 7019 btrfs_tree_lock(next);
6871 btrfs_set_lock_blocking(next); 7020 btrfs_set_lock_blocking(next);
6872 7021
6873 ret = btrfs_lookup_extent_info(trans, root, bytenr, blocksize, 7022 ret = btrfs_lookup_extent_info(trans, root, bytenr, level - 1, 1,
6874 &wc->refs[level - 1], 7023 &wc->refs[level - 1],
6875 &wc->flags[level - 1]); 7024 &wc->flags[level - 1]);
6876 if (ret < 0) { 7025 if (ret < 0) {
@@ -7001,7 +7150,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
7001 path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING; 7150 path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING;
7002 7151
7003 ret = btrfs_lookup_extent_info(trans, root, 7152 ret = btrfs_lookup_extent_info(trans, root,
7004 eb->start, eb->len, 7153 eb->start, level, 1,
7005 &wc->refs[level], 7154 &wc->refs[level],
7006 &wc->flags[level]); 7155 &wc->flags[level]);
7007 if (ret < 0) { 7156 if (ret < 0) {
@@ -7211,8 +7360,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
7211 7360
7212 ret = btrfs_lookup_extent_info(trans, root, 7361 ret = btrfs_lookup_extent_info(trans, root,
7213 path->nodes[level]->start, 7362 path->nodes[level]->start,
7214 path->nodes[level]->len, 7363 level, 1, &wc->refs[level],
7215 &wc->refs[level],
7216 &wc->flags[level]); 7364 &wc->flags[level]);
7217 if (ret < 0) { 7365 if (ret < 0) {
7218 err = ret; 7366 err = ret;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 24e8a356a36c..c69145b66ea4 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3660,7 +3660,7 @@ static int check_path_shared(struct btrfs_root *root,
3660 eb = path->nodes[level]; 3660 eb = path->nodes[level];
3661 if (!btrfs_block_can_be_shared(root, eb)) 3661 if (!btrfs_block_can_be_shared(root, eb))
3662 continue; 3662 continue;
3663 ret = btrfs_lookup_extent_info(NULL, root, eb->start, eb->len, 3663 ret = btrfs_lookup_extent_info(NULL, root, eb->start, level, 1,
3664 &refs, NULL); 3664 &refs, NULL);
3665 if (refs > 1) 3665 if (refs > 1)
3666 return 1; 3666 return 1;
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index b67171e6d688..86f192ffc212 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -619,10 +619,13 @@ static noinline_for_stack
619int find_inline_backref(struct extent_buffer *leaf, int slot, 619int find_inline_backref(struct extent_buffer *leaf, int slot,
620 unsigned long *ptr, unsigned long *end) 620 unsigned long *ptr, unsigned long *end)
621{ 621{
622 struct btrfs_key key;
622 struct btrfs_extent_item *ei; 623 struct btrfs_extent_item *ei;
623 struct btrfs_tree_block_info *bi; 624 struct btrfs_tree_block_info *bi;
624 u32 item_size; 625 u32 item_size;
625 626
627 btrfs_item_key_to_cpu(leaf, &key, slot);
628
626 item_size = btrfs_item_size_nr(leaf, slot); 629 item_size = btrfs_item_size_nr(leaf, slot);
627#ifdef BTRFS_COMPAT_EXTENT_TREE_V0 630#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
628 if (item_size < sizeof(*ei)) { 631 if (item_size < sizeof(*ei)) {
@@ -634,13 +637,18 @@ int find_inline_backref(struct extent_buffer *leaf, int slot,
634 WARN_ON(!(btrfs_extent_flags(leaf, ei) & 637 WARN_ON(!(btrfs_extent_flags(leaf, ei) &
635 BTRFS_EXTENT_FLAG_TREE_BLOCK)); 638 BTRFS_EXTENT_FLAG_TREE_BLOCK));
636 639
637 if (item_size <= sizeof(*ei) + sizeof(*bi)) { 640 if (key.type == BTRFS_EXTENT_ITEM_KEY &&
641 item_size <= sizeof(*ei) + sizeof(*bi)) {
638 WARN_ON(item_size < sizeof(*ei) + sizeof(*bi)); 642 WARN_ON(item_size < sizeof(*ei) + sizeof(*bi));
639 return 1; 643 return 1;
640 } 644 }
641 645
642 bi = (struct btrfs_tree_block_info *)(ei + 1); 646 if (key.type == BTRFS_EXTENT_ITEM_KEY) {
643 *ptr = (unsigned long)(bi + 1); 647 bi = (struct btrfs_tree_block_info *)(ei + 1);
648 *ptr = (unsigned long)(bi + 1);
649 } else {
650 *ptr = (unsigned long)(ei + 1);
651 }
644 *end = (unsigned long)ei + item_size; 652 *end = (unsigned long)ei + item_size;
645 return 0; 653 return 0;
646} 654}
@@ -708,7 +716,7 @@ again:
708 end = 0; 716 end = 0;
709 ptr = 0; 717 ptr = 0;
710 key.objectid = cur->bytenr; 718 key.objectid = cur->bytenr;
711 key.type = BTRFS_EXTENT_ITEM_KEY; 719 key.type = BTRFS_METADATA_ITEM_KEY;
712 key.offset = (u64)-1; 720 key.offset = (u64)-1;
713 721
714 path1->search_commit_root = 1; 722 path1->search_commit_root = 1;
@@ -766,7 +774,8 @@ again:
766 break; 774 break;
767 } 775 }
768 776
769 if (key.type == BTRFS_EXTENT_ITEM_KEY) { 777 if (key.type == BTRFS_EXTENT_ITEM_KEY ||
778 key.type == BTRFS_METADATA_ITEM_KEY) {
770 ret = find_inline_backref(eb, path1->slots[0], 779 ret = find_inline_backref(eb, path1->slots[0],
771 &ptr, &end); 780 &ptr, &end);
772 if (ret) 781 if (ret)
@@ -2768,8 +2777,13 @@ static int reada_tree_block(struct reloc_control *rc,
2768 struct tree_block *block) 2777 struct tree_block *block)
2769{ 2778{
2770 BUG_ON(block->key_ready); 2779 BUG_ON(block->key_ready);
2771 readahead_tree_block(rc->extent_root, block->bytenr, 2780 if (block->key.type == BTRFS_METADATA_ITEM_KEY)
2772 block->key.objectid, block->key.offset); 2781 readahead_tree_block(rc->extent_root, block->bytenr,
2782 block->key.objectid,
2783 rc->extent_root->leafsize);
2784 else
2785 readahead_tree_block(rc->extent_root, block->bytenr,
2786 block->key.objectid, block->key.offset);
2773 return 0; 2787 return 0;
2774} 2788}
2775 2789
@@ -3176,12 +3190,17 @@ static int add_tree_block(struct reloc_control *rc,
3176 eb = path->nodes[0]; 3190 eb = path->nodes[0];
3177 item_size = btrfs_item_size_nr(eb, path->slots[0]); 3191 item_size = btrfs_item_size_nr(eb, path->slots[0]);
3178 3192
3179 if (item_size >= sizeof(*ei) + sizeof(*bi)) { 3193 if (extent_key->type == BTRFS_METADATA_ITEM_KEY ||
3194 item_size >= sizeof(*ei) + sizeof(*bi)) {
3180 ei = btrfs_item_ptr(eb, path->slots[0], 3195 ei = btrfs_item_ptr(eb, path->slots[0],
3181 struct btrfs_extent_item); 3196 struct btrfs_extent_item);
3182 bi = (struct btrfs_tree_block_info *)(ei + 1); 3197 if (extent_key->type == BTRFS_EXTENT_ITEM_KEY) {
3198 bi = (struct btrfs_tree_block_info *)(ei + 1);
3199 level = btrfs_tree_block_level(eb, bi);
3200 } else {
3201 level = (int)extent_key->offset;
3202 }
3183 generation = btrfs_extent_generation(eb, ei); 3203 generation = btrfs_extent_generation(eb, ei);
3184 level = btrfs_tree_block_level(eb, bi);
3185 } else { 3204 } else {
3186#ifdef BTRFS_COMPAT_EXTENT_TREE_V0 3205#ifdef BTRFS_COMPAT_EXTENT_TREE_V0
3187 u64 ref_owner; 3206 u64 ref_owner;
@@ -3210,7 +3229,7 @@ static int add_tree_block(struct reloc_control *rc,
3210 return -ENOMEM; 3229 return -ENOMEM;
3211 3230
3212 block->bytenr = extent_key->objectid; 3231 block->bytenr = extent_key->objectid;
3213 block->key.objectid = extent_key->offset; 3232 block->key.objectid = rc->extent_root->leafsize;
3214 block->key.offset = generation; 3233 block->key.offset = generation;
3215 block->level = level; 3234 block->level = level;
3216 block->key_ready = 0; 3235 block->key_ready = 0;
@@ -3252,9 +3271,15 @@ static int __add_tree_block(struct reloc_control *rc,
3252 ret = btrfs_search_slot(NULL, rc->extent_root, &key, path, 0, 0); 3271 ret = btrfs_search_slot(NULL, rc->extent_root, &key, path, 0, 0);
3253 if (ret < 0) 3272 if (ret < 0)
3254 goto out; 3273 goto out;
3255 BUG_ON(ret);
3256 3274
3257 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); 3275 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
3276 if (ret > 0) {
3277 if (key.objectid == bytenr &&
3278 key.type == BTRFS_METADATA_ITEM_KEY)
3279 ret = 0;
3280 }
3281 BUG_ON(ret);
3282
3258 ret = add_tree_block(rc, &key, path, blocks); 3283 ret = add_tree_block(rc, &key, path, blocks);
3259out: 3284out:
3260 btrfs_free_path(path); 3285 btrfs_free_path(path);
@@ -3275,7 +3300,8 @@ static int block_use_full_backref(struct reloc_control *rc,
3275 return 1; 3300 return 1;
3276 3301
3277 ret = btrfs_lookup_extent_info(NULL, rc->extent_root, 3302 ret = btrfs_lookup_extent_info(NULL, rc->extent_root,
3278 eb->start, eb->len, NULL, &flags); 3303 eb->start, btrfs_header_level(eb), 1,
3304 NULL, &flags);
3279 BUG_ON(ret); 3305 BUG_ON(ret);
3280 3306
3281 if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) 3307 if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)
@@ -3644,12 +3670,25 @@ next:
3644 break; 3670 break;
3645 } 3671 }
3646 3672
3647 if (key.type != BTRFS_EXTENT_ITEM_KEY || 3673 if (key.type != BTRFS_EXTENT_ITEM_KEY &&
3674 key.type != BTRFS_METADATA_ITEM_KEY) {
3675 path->slots[0]++;
3676 goto next;
3677 }
3678
3679 if (key.type == BTRFS_EXTENT_ITEM_KEY &&
3648 key.objectid + key.offset <= rc->search_start) { 3680 key.objectid + key.offset <= rc->search_start) {
3649 path->slots[0]++; 3681 path->slots[0]++;
3650 goto next; 3682 goto next;
3651 } 3683 }
3652 3684
3685 if (key.type == BTRFS_METADATA_ITEM_KEY &&
3686 key.objectid + rc->extent_root->leafsize <=
3687 rc->search_start) {
3688 path->slots[0]++;
3689 goto next;
3690 }
3691
3653 ret = find_first_extent_bit(&rc->processed_blocks, 3692 ret = find_first_extent_bit(&rc->processed_blocks,
3654 key.objectid, &start, &end, 3693 key.objectid, &start, &end,
3655 EXTENT_DIRTY, NULL); 3694 EXTENT_DIRTY, NULL);
@@ -3658,7 +3697,11 @@ next:
3658 btrfs_release_path(path); 3697 btrfs_release_path(path);
3659 rc->search_start = end + 1; 3698 rc->search_start = end + 1;
3660 } else { 3699 } else {
3661 rc->search_start = key.objectid + key.offset; 3700 if (key.type == BTRFS_EXTENT_ITEM_KEY)
3701 rc->search_start = key.objectid + key.offset;
3702 else
3703 rc->search_start = key.objectid +
3704 rc->extent_root->leafsize;
3662 memcpy(extent_key, &key, sizeof(key)); 3705 memcpy(extent_key, &key, sizeof(key));
3663 return 0; 3706 return 0;
3664 } 3707 }
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 3d29d60bdaf8..28db5dcde0aa 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -2312,8 +2312,8 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
2312 key_start.type = BTRFS_EXTENT_ITEM_KEY; 2312 key_start.type = BTRFS_EXTENT_ITEM_KEY;
2313 key_start.offset = (u64)0; 2313 key_start.offset = (u64)0;
2314 key_end.objectid = base + offset + nstripes * increment; 2314 key_end.objectid = base + offset + nstripes * increment;
2315 key_end.type = BTRFS_EXTENT_ITEM_KEY; 2315 key_end.type = BTRFS_METADATA_ITEM_KEY;
2316 key_end.offset = (u64)0; 2316 key_end.offset = (u64)-1;
2317 reada1 = btrfs_reada_add(root, &key_start, &key_end); 2317 reada1 = btrfs_reada_add(root, &key_start, &key_end);
2318 2318
2319 key_start.objectid = BTRFS_EXTENT_CSUM_OBJECTID; 2319 key_start.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
@@ -2401,6 +2401,7 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
2401 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 2401 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
2402 if (ret < 0) 2402 if (ret < 0)
2403 goto out; 2403 goto out;
2404
2404 if (ret > 0) { 2405 if (ret > 0) {
2405 ret = btrfs_previous_item(root, path, 0, 2406 ret = btrfs_previous_item(root, path, 0,
2406 BTRFS_EXTENT_ITEM_KEY); 2407 BTRFS_EXTENT_ITEM_KEY);
@@ -2418,6 +2419,8 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
2418 } 2419 }
2419 2420
2420 while (1) { 2421 while (1) {
2422 u64 bytes;
2423
2421 l = path->nodes[0]; 2424 l = path->nodes[0];
2422 slot = path->slots[0]; 2425 slot = path->slots[0];
2423 if (slot >= btrfs_header_nritems(l)) { 2426 if (slot >= btrfs_header_nritems(l)) {
@@ -2431,14 +2434,21 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
2431 } 2434 }
2432 btrfs_item_key_to_cpu(l, &key, slot); 2435 btrfs_item_key_to_cpu(l, &key, slot);
2433 2436
2434 if (key.objectid + key.offset <= logical) 2437 if (key.type != BTRFS_EXTENT_ITEM_KEY &&
2438 key.type != BTRFS_METADATA_ITEM_KEY)
2439 goto next;
2440
2441 if (key.type == BTRFS_METADATA_ITEM_KEY)
2442 bytes = root->leafsize;
2443 else
2444 bytes = key.offset;
2445
2446 if (key.objectid + bytes <= logical)
2435 goto next; 2447 goto next;
2436 2448
2437 if (key.objectid >= logical + map->stripe_len) 2449 if (key.objectid >= logical + map->stripe_len)
2438 break; 2450 break;
2439 2451
2440 if (btrfs_key_type(&key) != BTRFS_EXTENT_ITEM_KEY)
2441 goto next;
2442 2452
2443 extent = btrfs_item_ptr(l, slot, 2453 extent = btrfs_item_ptr(l, slot,
2444 struct btrfs_extent_item); 2454 struct btrfs_extent_item);
@@ -2459,18 +2469,18 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
2459 * trim extent to this stripe 2469 * trim extent to this stripe
2460 */ 2470 */
2461 if (key.objectid < logical) { 2471 if (key.objectid < logical) {
2462 key.offset -= logical - key.objectid; 2472 bytes -= logical - key.objectid;
2463 key.objectid = logical; 2473 key.objectid = logical;
2464 } 2474 }
2465 if (key.objectid + key.offset > 2475 if (key.objectid + bytes >
2466 logical + map->stripe_len) { 2476 logical + map->stripe_len) {
2467 key.offset = logical + map->stripe_len - 2477 bytes = logical + map->stripe_len -
2468 key.objectid; 2478 key.objectid;
2469 } 2479 }
2470 2480
2471 extent_logical = key.objectid; 2481 extent_logical = key.objectid;
2472 extent_physical = key.objectid - logical + physical; 2482 extent_physical = key.objectid - logical + physical;
2473 extent_len = key.offset; 2483 extent_len = bytes;
2474 extent_dev = scrub_dev; 2484 extent_dev = scrub_dev;
2475 extent_mirror_num = mirror_num; 2485 extent_mirror_num = mirror_num;
2476 if (is_dev_replace) 2486 if (is_dev_replace)