@@ -8918,6 +8918,7 @@ static int check_dev_extents(void)
struct btrfs_key key;
struct btrfs_root *dev_root = gfs_info->dev_root;
int ret;
+ u32 super_reserved = BTRFS_BLOCK_RESERVED_1M_FOR_SUPER;
u64 prev_devid = 0;
u64 prev_dev_ext_end = 0;
@@ -8927,6 +8928,10 @@ static int check_dev_extents(void)
key.type = BTRFS_DEV_EXTENT_KEY;
key.offset = 0;
+ if (btrfs_fs_compat_ro(gfs_info, EXTRA_SUPER_RESERVED) &&
+ btrfs_super_reserved_bytes(gfs_info->super_copy) >= super_reserved)
+ super_reserved = btrfs_super_reserved_bytes(gfs_info->super_copy);
+
ret = btrfs_search_slot(NULL, dev_root, &key, &path, 0, 0);
if (ret < 0) {
errno = -ret;
@@ -8983,6 +8988,13 @@ static int check_dev_extents(void)
ret = -EUCLEAN;
goto out;
}
+ if (physical_offset < super_reserved) {
+ warning(
+"dev extent devid %llu physical offset %llu is inside the reserved range (%u)",
+ devid, physical_offset,
+ super_reserved);
+ gfs_info->found_dev_extents_in_reserved = 1;
+ }
prev_devid = devid;
prev_dev_ext_end = physical_offset + physical_len;
@@ -8998,6 +9010,11 @@ static int check_dev_extents(void)
}
}
out:
+ if (gfs_info->found_dev_extents_in_reserved) {
+ warning("to relocate the dev extents in reserved range, mount the fs and run:");
+ warning("\tbtrfs balance start -mdrange=0..%u -ddrange=0..%u -sdrange=0..%u",
+ super_reserved, super_reserved, super_reserved);
+ }
btrfs_release_path(&path);
return ret;
}
@@ -4433,12 +4433,17 @@ static int check_dev_extent_item(struct extent_buffer *eb, int slot)
struct btrfs_key devext_key;
struct btrfs_chunk *chunk;
struct extent_buffer *l;
+ u32 super_reserved = BTRFS_BLOCK_RESERVED_1M_FOR_SUPER;
int num_stripes;
u64 length;
int i;
int found_chunk = 0;
int ret;
+ if (btrfs_fs_compat_ro(gfs_info, EXTRA_SUPER_RESERVED) &&
+ btrfs_super_reserved_bytes(gfs_info->super_copy) >= super_reserved)
+ super_reserved = btrfs_super_reserved_bytes(gfs_info->super_copy);
+
btrfs_item_key_to_cpu(eb, &devext_key, slot);
ptr = btrfs_item_ptr(eb, slot, struct btrfs_dev_extent);
length = btrfs_dev_extent_length(eb, ptr);
@@ -4447,6 +4452,13 @@ static int check_dev_extent_item(struct extent_buffer *eb, int slot)
chunk_key.type = BTRFS_CHUNK_ITEM_KEY;
chunk_key.offset = btrfs_dev_extent_chunk_offset(eb, ptr);
+ if (devext_key.offset < super_reserved) {
+ warning(
+"dev extent devid %llu physical offset %llu is inside the reserved range (%u)",
+ devext_key.objectid, devext_key.offset,
+ super_reserved);
+ gfs_info->found_dev_extents_in_reserved = 1;
+ }
btrfs_init_path(&path);
ret = btrfs_search_slot(NULL, chunk_root, &chunk_key, &path, 0, 0);
if (ret)
@@ -5526,9 +5538,14 @@ int check_chunks_and_extents_lowmem(void)
struct btrfs_key key;
struct btrfs_root *root;
struct btrfs_root *cur_root;
+ u32 super_reserved = BTRFS_BLOCK_RESERVED_1M_FOR_SUPER;
int err = 0;
int ret;
+ if (btrfs_fs_compat_ro(gfs_info, EXTRA_SUPER_RESERVED) &&
+ btrfs_super_reserved_bytes(gfs_info->super_copy) >= super_reserved)
+ super_reserved = btrfs_super_reserved_bytes(gfs_info->super_copy);
+
root = gfs_info->chunk_root;
ret = check_btrfs_root(root, 1);
err |= ret;
@@ -5590,6 +5607,11 @@ out:
total_used);
err |= SUPER_BYTES_USED_ERROR;
}
+ if (gfs_info->found_dev_extents_in_reserved) {
+ warning("to relocate the dev extents in reserved range, mount the fs and run:");
+ warning("\tbtrfs balance start -mdrange=0..%u -ddrange=0..%u -sdrange=0..%u",
+ super_reserved, super_reserved, super_reserved);
+ }
if (repair) {
ret = end_avoid_extents_overwrite();
@@ -1271,6 +1271,7 @@ struct btrfs_fs_info {
unsigned int finalize_on_close:1;
unsigned int hide_names:1;
unsigned int allow_transid_mismatch:1;
+ unsigned int found_dev_extents_in_reserved:1;
int transaction_aborted;
int force_csum_type;
Since kernel can handle it without problem, and we rely on balance to relocate those offending dev extents, we only need to output warning when such dev extents are detected. Signed-off-by: Qu Wenruo <wqu@suse.com> --- check/main.c | 17 +++++++++++++++++ check/mode-lowmem.c | 22 ++++++++++++++++++++++ kernel-shared/ctree.h | 1 + 3 files changed, 40 insertions(+)