for-6.2-rc2-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAmO3GgQACgkQxWXV+ddt WDt23w/+M7YshE37i5NVRFsFQ4E2/kNQAnbUvSDg5xTmaWkQo/XOMbO9EGUoTLQW vT5LmUxn3ynfLu65jnbBREyqjT1JoFN47gTFud+Y7XayBZvq/EVwkkBu5vd/Xwu+ bE/ms/mWvDNuBnNjBjjKCvMebUZFs2Yn4BGGGCor2zs+u2SL9yd8gHzaBABPr0jd Jt1XcmdlYzIJ/59oWZI9B9yP//3z/ad2cgI6aCcbALocWW3LtUATRgJt5O72IFdO HweiMw/Cvd2EFBmiur3NTsAi80vyV1VUImxMKD8yrWp5vdR4ZSAeMFd7vFQpfCco u/8LHE1xzq3Ael0yGSQIB+UhBTHxFp1lCKTtA1vC9Iv0APVjd2zJlqf18z+hdgr9 ULU3wxVaN9rtHd2vttt+u/YikJYwFnYw+iNK2FNYIKU2q3pidoQHgEKOCJF7s1pY Yrpk6kYJNaS9nT71/sX57aLA/WmIx1KFkA16Yvi+RqnMQVYJtuEleRRp95ZdXAg/ CzjkugN3gmQvsv43FQLiKHFd/8bDnhcft48tIVjikCpSar3VwFoV7A5mgWs18ULO g+vyjWm1P2UagXhjLl/rsULWNLVAYOKsKXEDnRV3993lCA+EXiQbFY8gA16dfKMJ ho1yspX+N2ItORT7lo6ZPmDIWZ37hUyo8Bfhk5RaUKpE/adEBwM= =xM0t -----END PGP SIGNATURE----- Merge tag 'for-6.2-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull btrfs fixes from David Sterba: "A few more regression and regular fixes: - regressions: - fix assertion condition using = instead of == - fix false alert on bad tree level check - fix off-by-one error in delalloc search during lseek - fix compat ro feature check at read-write remount - handle case when read-repair happens with ongoing device replace - updated error messages" * tag 'for-6.2-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: fix compat_ro checks against remount btrfs: always report error in run_one_delayed_ref() btrfs: handle case when repair happens with dev-replace btrfs: fix off-by-one in delalloc search during lseek btrfs: fix false alert on bad tree level check btrfs: add error message for metadata level mismatch btrfs: fix ASSERT em->len condition in btrfs_get_extent
This commit is contained in:
commit
fc7b76c4a4
@ -329,7 +329,16 @@ int btrfs_repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 start,
|
||||
&map_length, &bioc, mirror_num);
|
||||
if (ret)
|
||||
goto out_counter_dec;
|
||||
BUG_ON(mirror_num != bioc->mirror_num);
|
||||
/*
|
||||
* This happens when dev-replace is also running, and the
|
||||
* mirror_num indicates the dev-replace target.
|
||||
*
|
||||
* In this case, we don't need to do anything, as the read
|
||||
* error just means the replace progress hasn't reached our
|
||||
* read range, and later replace routine would handle it well.
|
||||
*/
|
||||
if (mirror_num != bioc->mirror_num)
|
||||
goto out_counter_dec;
|
||||
}
|
||||
|
||||
sector = bioc->stripes[bioc->mirror_num - 1].physical >> 9;
|
||||
|
@ -530,6 +530,9 @@ static int validate_extent_buffer(struct extent_buffer *eb,
|
||||
}
|
||||
|
||||
if (found_level != check->level) {
|
||||
btrfs_err(fs_info,
|
||||
"level verify failed on logical %llu mirror %u wanted %u found %u",
|
||||
eb->start, eb->read_mirror, check->level, found_level);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
@ -3381,6 +3384,8 @@ out:
|
||||
/*
|
||||
* Do various sanity and dependency checks of different features.
|
||||
*
|
||||
* @is_rw_mount: If the mount is read-write.
|
||||
*
|
||||
* This is the place for less strict checks (like for subpage or artificial
|
||||
* feature dependencies).
|
||||
*
|
||||
@ -3391,7 +3396,7 @@ out:
|
||||
* (space cache related) can modify on-disk format like free space tree and
|
||||
* screw up certain feature dependencies.
|
||||
*/
|
||||
int btrfs_check_features(struct btrfs_fs_info *fs_info, struct super_block *sb)
|
||||
int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount)
|
||||
{
|
||||
struct btrfs_super_block *disk_super = fs_info->super_copy;
|
||||
u64 incompat = btrfs_super_incompat_flags(disk_super);
|
||||
@ -3430,7 +3435,7 @@ int btrfs_check_features(struct btrfs_fs_info *fs_info, struct super_block *sb)
|
||||
if (btrfs_super_nodesize(disk_super) > PAGE_SIZE)
|
||||
incompat |= BTRFS_FEATURE_INCOMPAT_BIG_METADATA;
|
||||
|
||||
if (compat_ro_unsupp && !sb_rdonly(sb)) {
|
||||
if (compat_ro_unsupp && is_rw_mount) {
|
||||
btrfs_err(fs_info,
|
||||
"cannot mount read-write because of unknown compat_ro features (0x%llx)",
|
||||
compat_ro);
|
||||
@ -3633,7 +3638,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
|
||||
goto fail_alloc;
|
||||
}
|
||||
|
||||
ret = btrfs_check_features(fs_info, sb);
|
||||
ret = btrfs_check_features(fs_info, !sb_rdonly(sb));
|
||||
if (ret < 0) {
|
||||
err = ret;
|
||||
goto fail_alloc;
|
||||
|
@ -50,7 +50,7 @@ int __cold open_ctree(struct super_block *sb,
|
||||
void __cold close_ctree(struct btrfs_fs_info *fs_info);
|
||||
int btrfs_validate_super(struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_super_block *sb, int mirror_num);
|
||||
int btrfs_check_features(struct btrfs_fs_info *fs_info, struct super_block *sb);
|
||||
int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount);
|
||||
int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors);
|
||||
struct btrfs_super_block *btrfs_read_dev_super(struct block_device *bdev);
|
||||
struct btrfs_super_block *btrfs_read_dev_one_super(struct block_device *bdev,
|
||||
|
@ -1551,7 +1551,7 @@ u64 count_range_bits(struct extent_io_tree *tree,
|
||||
u64 last = 0;
|
||||
int found = 0;
|
||||
|
||||
if (WARN_ON(search_end <= cur_start))
|
||||
if (WARN_ON(search_end < cur_start))
|
||||
return 0;
|
||||
|
||||
spin_lock(&tree->lock);
|
||||
|
@ -1713,6 +1713,11 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
|
||||
BUG();
|
||||
if (ret && insert_reserved)
|
||||
btrfs_pin_extent(trans, node->bytenr, node->num_bytes, 1);
|
||||
if (ret < 0)
|
||||
btrfs_err(trans->fs_info,
|
||||
"failed to run delayed ref for logical %llu num_bytes %llu type %u action %u ref_mod %d: %d",
|
||||
node->bytenr, node->num_bytes, node->type,
|
||||
node->action, node->ref_mod, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1954,8 +1959,6 @@ static int btrfs_run_delayed_refs_for_head(struct btrfs_trans_handle *trans,
|
||||
if (ret) {
|
||||
unselect_delayed_ref_head(delayed_refs, locked_ref);
|
||||
btrfs_put_delayed_ref(ref);
|
||||
btrfs_debug(fs_info, "run_one_delayed_ref returned %d",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -103,6 +103,15 @@ struct btrfs_bio_ctrl {
|
||||
u32 len_to_oe_boundary;
|
||||
btrfs_bio_end_io_t end_io_func;
|
||||
|
||||
/*
|
||||
* This is for metadata read, to provide the extra needed verification
|
||||
* info. This has to be provided for submit_one_bio(), as
|
||||
* submit_one_bio() can submit a bio if it ends at stripe boundary. If
|
||||
* no such parent_check is provided, the metadata can hit false alert at
|
||||
* endio time.
|
||||
*/
|
||||
struct btrfs_tree_parent_check *parent_check;
|
||||
|
||||
/*
|
||||
* Tell writepage not to lock the state bits for this range, it still
|
||||
* does the unlocking.
|
||||
@ -133,13 +142,24 @@ static void submit_one_bio(struct btrfs_bio_ctrl *bio_ctrl)
|
||||
|
||||
btrfs_bio(bio)->file_offset = page_offset(bv->bv_page) + bv->bv_offset;
|
||||
|
||||
if (!is_data_inode(&inode->vfs_inode))
|
||||
if (!is_data_inode(&inode->vfs_inode)) {
|
||||
if (btrfs_op(bio) != BTRFS_MAP_WRITE) {
|
||||
/*
|
||||
* For metadata read, we should have the parent_check,
|
||||
* and copy it to bbio for metadata verification.
|
||||
*/
|
||||
ASSERT(bio_ctrl->parent_check);
|
||||
memcpy(&btrfs_bio(bio)->parent_check,
|
||||
bio_ctrl->parent_check,
|
||||
sizeof(struct btrfs_tree_parent_check));
|
||||
}
|
||||
btrfs_submit_metadata_bio(inode, bio, mirror_num);
|
||||
else if (btrfs_op(bio) == BTRFS_MAP_WRITE)
|
||||
} else if (btrfs_op(bio) == BTRFS_MAP_WRITE) {
|
||||
btrfs_submit_data_write_bio(inode, bio, mirror_num);
|
||||
else
|
||||
} else {
|
||||
btrfs_submit_data_read_bio(inode, bio, mirror_num,
|
||||
bio_ctrl->compress_type);
|
||||
}
|
||||
|
||||
/* The bio is owned by the end_io handler now */
|
||||
bio_ctrl->bio = NULL;
|
||||
@ -4829,6 +4849,7 @@ static int read_extent_buffer_subpage(struct extent_buffer *eb, int wait,
|
||||
struct extent_state *cached_state = NULL;
|
||||
struct btrfs_bio_ctrl bio_ctrl = {
|
||||
.mirror_num = mirror_num,
|
||||
.parent_check = check,
|
||||
};
|
||||
int ret = 0;
|
||||
|
||||
@ -4878,7 +4899,6 @@ static int read_extent_buffer_subpage(struct extent_buffer *eb, int wait,
|
||||
*/
|
||||
atomic_dec(&eb->io_pages);
|
||||
}
|
||||
memcpy(&btrfs_bio(bio_ctrl.bio)->parent_check, check, sizeof(*check));
|
||||
submit_one_bio(&bio_ctrl);
|
||||
if (ret || wait != WAIT_COMPLETE) {
|
||||
free_extent_state(cached_state);
|
||||
@ -4905,6 +4925,7 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num,
|
||||
unsigned long num_reads = 0;
|
||||
struct btrfs_bio_ctrl bio_ctrl = {
|
||||
.mirror_num = mirror_num,
|
||||
.parent_check = check,
|
||||
};
|
||||
|
||||
if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))
|
||||
@ -4996,7 +5017,6 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num,
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&btrfs_bio(bio_ctrl.bio)->parent_check, check, sizeof(*check));
|
||||
submit_one_bio(&bio_ctrl);
|
||||
|
||||
if (ret || wait != WAIT_COMPLETE)
|
||||
|
@ -3354,7 +3354,7 @@ bool btrfs_find_delalloc_in_range(struct btrfs_inode *inode, u64 start, u64 end,
|
||||
bool search_io_tree = true;
|
||||
bool ret = false;
|
||||
|
||||
while (cur_offset < end) {
|
||||
while (cur_offset <= end) {
|
||||
u64 delalloc_start;
|
||||
u64 delalloc_end;
|
||||
bool delalloc;
|
||||
|
@ -7092,7 +7092,7 @@ next:
|
||||
* Other members are not utilized for inline extents.
|
||||
*/
|
||||
ASSERT(em->block_start == EXTENT_MAP_INLINE);
|
||||
ASSERT(em->len = fs_info->sectorsize);
|
||||
ASSERT(em->len == fs_info->sectorsize);
|
||||
|
||||
ret = read_inline_extent(inode, path, page);
|
||||
if (ret < 0)
|
||||
|
@ -1705,7 +1705,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
|
||||
if (ret)
|
||||
goto restore;
|
||||
|
||||
ret = btrfs_check_features(fs_info, sb);
|
||||
ret = btrfs_check_features(fs_info, !(*flags & SB_RDONLY));
|
||||
if (ret < 0)
|
||||
goto restore;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user