for-5.5-rc8-tag
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE8rQSAMVO+zA4DBdWxWXV+ddtWDsFAl4sLasACgkQxWXV+ddt WDsegg/8CBQ1/pGj+8mvf+ws6f71Av8jspY2Ebr+HCjaGhD2MG3HI1kA5gC9Qnbb fQVd12M5ma2BTrIcszxwm+VMIMlDotRFzfAp8uuFJtW0aAEGMCboX6VRYWa/4I0o SmgJg0RYh926VL73qSe3S72pfIYjar30RwjVIVTmsHxL/D/lEkrHg6IGKRCe/MaN eQipth3iuFtcWmGm1+DxEySsOs7AMPg3wL8KVnQcYoDI2kg3BXFH9a4wTE6VmWsU ZjonJBA/Rl8oA2YOVDum4mL5j2c5RulWEymdVKyo1oH+8kLDOQ8snd7Bxp3qtJ1C gdVbS8gi7gT5/C+yex+ZWlAdfmCSGWj7dr7jjiELZhTrsBhtS7y+GM52GivSrJ3z TciNQtF/Y0SrZGprPMgVGAHuIKWWwSmWJPmkRB4zv/5efFFdKg8/UmcRmh6dMo83 IF4VPEBQgJLj3ja9Wns5yvW9asKNcynGeFK7aV+BlGW/wuvBW9o017c4Q04dXSAK iFpipJaR/6ZGmXlRQLa1uyKWVHNIfSFT47WJqa6Dbo6iWRE/S/MhfkZU42z2A3H9 O2qMWmZikZnPCkha6fWyNJEDxF3imC+/LBsYoEuVPR7kZ/irDnI1cJNsTocOlyj1 kgFtL5MnCBHCop9/tPGiVdin9ilHJs3q2kAkR5BNCSEqhC8mo4g= =IPUk -----END PGP SIGNATURE----- Merge tag 'for-5.5-rc8-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux Pull btrfs fix from David Sterba: "Here's a last minute fix for a regression introduced in this development cycle. There's a small chance of a silent corruption when device replace and NOCOW data writes happen at the same time in one block group. Metadata or COW data writes are unaffected. The extra fixup patch is there to silence an unnecessary warning" * tag 'for-5.5-rc8-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: dev-replace: remove warning for unknown return codes when finished btrfs: scrub: Require mandatory block group RO for dev-replace
This commit is contained in:
commit
a075f23dd4
|
@ -500,11 +500,8 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
|
|||
&dev_replace->scrub_progress, 0, 1);
|
||||
|
||||
ret = btrfs_dev_replace_finishing(fs_info, ret);
|
||||
if (ret == -EINPROGRESS) {
|
||||
if (ret == -EINPROGRESS)
|
||||
ret = BTRFS_IOCTL_DEV_REPLACE_RESULT_SCRUB_INPROGRESS;
|
||||
} else if (ret != -ECANCELED) {
|
||||
WARN_ON(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -3577,17 +3577,27 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
|
|||
* This can easily boost the amount of SYSTEM chunks if cleaner
|
||||
* thread can't be triggered fast enough, and use up all space
|
||||
* of btrfs_super_block::sys_chunk_array
|
||||
*
|
||||
* While for dev replace, we need to try our best to mark block
|
||||
* group RO, to prevent race between:
|
||||
* - Write duplication
|
||||
* Contains latest data
|
||||
* - Scrub copy
|
||||
* Contains data from commit tree
|
||||
*
|
||||
* If target block group is not marked RO, nocow writes can
|
||||
* be overwritten by scrub copy, causing data corruption.
|
||||
* So for dev-replace, it's not allowed to continue if a block
|
||||
* group is not RO.
|
||||
*/
|
||||
ret = btrfs_inc_block_group_ro(cache, false);
|
||||
scrub_pause_off(fs_info);
|
||||
|
||||
ret = btrfs_inc_block_group_ro(cache, sctx->is_dev_replace);
|
||||
if (ret == 0) {
|
||||
ro_set = 1;
|
||||
} else if (ret == -ENOSPC) {
|
||||
} else if (ret == -ENOSPC && !sctx->is_dev_replace) {
|
||||
/*
|
||||
* btrfs_inc_block_group_ro return -ENOSPC when it
|
||||
* failed in creating new chunk for metadata.
|
||||
* It is not a problem for scrub/replace, because
|
||||
* It is not a problem for scrub, because
|
||||
* metadata are always cowed, and our scrub paused
|
||||
* commit_transactions.
|
||||
*/
|
||||
|
@ -3596,9 +3606,22 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
|
|||
btrfs_warn(fs_info,
|
||||
"failed setting block group ro: %d", ret);
|
||||
btrfs_put_block_group(cache);
|
||||
scrub_pause_off(fs_info);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now the target block is marked RO, wait for nocow writes to
|
||||
* finish before dev-replace.
|
||||
* COW is fine, as COW never overwrites extents in commit tree.
|
||||
*/
|
||||
if (sctx->is_dev_replace) {
|
||||
btrfs_wait_nocow_writers(cache);
|
||||
btrfs_wait_ordered_roots(fs_info, U64_MAX, cache->start,
|
||||
cache->length);
|
||||
}
|
||||
|
||||
scrub_pause_off(fs_info);
|
||||
down_write(&dev_replace->rwsem);
|
||||
dev_replace->cursor_right = found_key.offset + length;
|
||||
dev_replace->cursor_left = found_key.offset;
|
||||
|
|
Loading…
Reference in New Issue