@@ -75,6 +75,7 @@ struct chunk_record {
u16 sub_stripes;
u32 io_align;
u32 io_width;
+ u32 per_dev_reserved;
u32 sector_size;
struct stripe stripes[0];
};
@@ -5202,6 +5202,7 @@ struct chunk_record *btrfs_new_chunk_record(struct extent_buffer *leaf,
struct btrfs_chunk *ptr;
struct chunk_record *rec;
int num_stripes, i;
+ bool is_journal;
ptr = btrfs_item_ptr(leaf, slot, struct btrfs_chunk);
num_stripes = btrfs_chunk_num_stripes(leaf, ptr);
@@ -5225,12 +5226,19 @@ struct chunk_record *btrfs_new_chunk_record(struct extent_buffer *leaf,
rec->type = key->type;
rec->offset = key->offset;
+ is_journal = btrfs_bg_type_is_journal(btrfs_chunk_type(leaf, ptr));
rec->length = rec->cache.size;
rec->owner = btrfs_chunk_owner(leaf, ptr);
rec->stripe_len = btrfs_chunk_stripe_len(leaf, ptr);
rec->type_flags = btrfs_chunk_type(leaf, ptr);
rec->io_width = btrfs_chunk_io_width(leaf, ptr);
- rec->io_align = btrfs_chunk_io_align(leaf, ptr);
+ if (is_journal) {
+ rec->io_align = rec->io_width;
+ rec->per_dev_reserved = btrfs_chunk_per_dev_reserved(leaf, ptr);
+ } else {
+ rec->io_align = btrfs_chunk_io_align(leaf, ptr);
+ rec->per_dev_reserved = 0;
+ }
rec->sector_size = btrfs_chunk_sector_size(leaf, ptr);
rec->num_stripes = num_stripes;
rec->sub_stripes = btrfs_chunk_sub_stripes(leaf, ptr);
@@ -8445,10 +8453,12 @@ static int check_chunk_refs(struct chunk_record *chunk_rec,
return ret;
length = calc_stripe_length(chunk_rec->type_flags, chunk_rec->length,
- chunk_rec->num_stripes);
+ chunk_rec->num_stripes) +
+ chunk_rec->per_dev_reserved;
for (i = 0; i < chunk_rec->num_stripes; ++i) {
devid = chunk_rec->stripes[i].devid;
- offset = chunk_rec->stripes[i].offset;
+ offset = chunk_rec->stripes[i].offset - chunk_rec->per_dev_reserved;
+
dev_extent_item = lookup_cache_extent2(&dev_extent_cache->tree,
devid, offset, length);
if (dev_extent_item) {
@@ -4435,6 +4435,7 @@ static int check_dev_extent_item(struct extent_buffer *eb, int slot)
struct extent_buffer *l;
int num_stripes;
u64 length;
+ u32 per_dev_reserved = 0;
int i;
int found_chunk = 0;
int ret;
@@ -4458,8 +4459,10 @@ static int check_dev_extent_item(struct extent_buffer *eb, int slot)
chunk_key.offset);
if (ret < 0)
goto out;
+ if (btrfs_bg_type_is_journal(btrfs_chunk_type(l, chunk)))
+ per_dev_reserved = btrfs_chunk_per_dev_reserved(l, chunk);
- if (btrfs_stripe_length(gfs_info, l, chunk) != length)
+ if (btrfs_stripe_length(gfs_info, l, chunk) != length - per_dev_reserved)
goto out;
num_stripes = btrfs_chunk_num_stripes(l, chunk);
@@ -4468,7 +4471,7 @@ static int check_dev_extent_item(struct extent_buffer *eb, int slot)
u64 offset = btrfs_stripe_offset_nr(l, chunk, i);
if (devid == devext_key.objectid &&
- offset == devext_key.offset) {
+ offset == devext_key.offset + per_dev_reserved) {
found_chunk = 1;
break;
}
@@ -4648,6 +4651,7 @@ static int check_chunk_item(struct extent_buffer *eb, int slot)
struct btrfs_chunk *chunk;
struct extent_buffer *leaf;
struct btrfs_dev_extent *ptr;
+ u32 per_dev_reserved = 0;
u64 length;
u64 chunk_end;
u64 stripe_len;
@@ -4672,6 +4676,8 @@ static int check_chunk_item(struct extent_buffer *eb, int slot)
goto out;
}
type = btrfs_chunk_type(eb, chunk);
+ if (btrfs_bg_type_is_journal(type))
+ per_dev_reserved = btrfs_chunk_per_dev_reserved(eb, chunk);
btrfs_init_path(&path);
ret = find_block_group_item(&path, chunk_key.offset, length, type);
@@ -4679,13 +4685,14 @@ static int check_chunk_item(struct extent_buffer *eb, int slot)
err |= REFERENCER_MISSING;
num_stripes = btrfs_chunk_num_stripes(eb, chunk);
- stripe_len = btrfs_stripe_length(gfs_info, eb, chunk);
+ stripe_len = btrfs_stripe_length(gfs_info, eb, chunk) + per_dev_reserved;
for (i = 0; i < num_stripes; i++) {
btrfs_release_path(&path);
btrfs_init_path(&path);
devext_key.objectid = btrfs_stripe_devid_nr(eb, chunk, i);
devext_key.type = BTRFS_DEV_EXTENT_KEY;
- devext_key.offset = btrfs_stripe_offset_nr(eb, chunk, i);
+ devext_key.offset = btrfs_stripe_offset_nr(eb, chunk, i) -
+ per_dev_reserved;
ret = btrfs_search_slot(NULL, dev_root, &devext_key, &path,
0, 0);
This patch will make both orginal and lowmem mode to take per device reservation into consideration for dev extent and chunk verification. Signed-off-by: Qu Wenruo <wqu@suse.com> --- check/common.h | 1 + check/main.c | 16 +++++++++++++--- check/mode-lowmem.c | 15 +++++++++++---- 3 files changed, 25 insertions(+), 7 deletions(-)