Commit e0178b54 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-6.4-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fix from David Sterba:
 "One regression fix.

  The rewrite of scrub code in 6.4 broke device replace in zoned mode,
  some of the writes could happen out of order so this had to be
  adjusted for all cases"

* tag 'for-6.4-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: zoned: fix dev-replace after the scrub rework
parents 5321d1b1 b675df02
......@@ -811,10 +811,6 @@ void btrfs_submit_repair_write(struct btrfs_bio *bbio, int mirror_num, bool dev_
goto fail;
if (dev_replace) {
if (btrfs_op(&bbio->bio) == BTRFS_MAP_WRITE && btrfs_is_zoned(fs_info)) {
bbio->bio.bi_opf &= ~REQ_OP_WRITE;
bbio->bio.bi_opf |= REQ_OP_ZONE_APPEND;
}
ASSERT(smap.dev == fs_info->dev_replace.srcdev);
smap.dev = fs_info->dev_replace.tgtdev;
}
......
......@@ -1137,6 +1137,35 @@ static void scrub_write_endio(struct btrfs_bio *bbio)
wake_up(&stripe->io_wait);
}
static void scrub_submit_write_bio(struct scrub_ctx *sctx,
struct scrub_stripe *stripe,
struct btrfs_bio *bbio, bool dev_replace)
{
struct btrfs_fs_info *fs_info = sctx->fs_info;
u32 bio_len = bbio->bio.bi_iter.bi_size;
u32 bio_off = (bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT) -
stripe->logical;
fill_writer_pointer_gap(sctx, stripe->physical + bio_off);
atomic_inc(&stripe->pending_io);
btrfs_submit_repair_write(bbio, stripe->mirror_num, dev_replace);
if (!btrfs_is_zoned(fs_info))
return;
/*
* For zoned writeback, queue depth must be 1, thus we must wait for
* the write to finish before the next write.
*/
wait_scrub_stripe_io(stripe);
/*
* And also need to update the write pointer if write finished
* successfully.
*/
if (!test_bit(bio_off >> fs_info->sectorsize_bits,
&stripe->write_error_bitmap))
sctx->write_pointer += bio_len;
}
/*
* Submit the write bio(s) for the sectors specified by @write_bitmap.
*
......@@ -1155,7 +1184,6 @@ static void scrub_write_sectors(struct scrub_ctx *sctx, struct scrub_stripe *str
{
struct btrfs_fs_info *fs_info = stripe->bg->fs_info;
struct btrfs_bio *bbio = NULL;
const bool zoned = btrfs_is_zoned(fs_info);
int sector_nr;
for_each_set_bit(sector_nr, &write_bitmap, stripe->nr_sectors) {
......@@ -1168,13 +1196,7 @@ static void scrub_write_sectors(struct scrub_ctx *sctx, struct scrub_stripe *str
/* Cannot merge with previous sector, submit the current one. */
if (bbio && sector_nr && !test_bit(sector_nr - 1, &write_bitmap)) {
fill_writer_pointer_gap(sctx, stripe->physical +
(sector_nr << fs_info->sectorsize_bits));
atomic_inc(&stripe->pending_io);
btrfs_submit_repair_write(bbio, stripe->mirror_num, dev_replace);
/* For zoned writeback, queue depth must be 1. */
if (zoned)
wait_scrub_stripe_io(stripe);
scrub_submit_write_bio(sctx, stripe, bbio, dev_replace);
bbio = NULL;
}
if (!bbio) {
......@@ -1187,14 +1209,8 @@ static void scrub_write_sectors(struct scrub_ctx *sctx, struct scrub_stripe *str
ret = bio_add_page(&bbio->bio, page, fs_info->sectorsize, pgoff);
ASSERT(ret == fs_info->sectorsize);
}
if (bbio) {
fill_writer_pointer_gap(sctx, bbio->bio.bi_iter.bi_sector <<
SECTOR_SHIFT);
atomic_inc(&stripe->pending_io);
btrfs_submit_repair_write(bbio, stripe->mirror_num, dev_replace);
if (zoned)
wait_scrub_stripe_io(stripe);
}
if (bbio)
scrub_submit_write_bio(sctx, stripe, bbio, dev_replace);
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment