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;
error += ret;
} else {
ret = load_free_space_cache(root->fs_info, cache);
- if (!ret)
+ if (ret < 0)
+ error++;
+ if (ret <= 0)
continue;
}
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.
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;
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))
}
/*
+ * 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.
*/