From 94bc95c468344d6a329dd87ab4461532584a7b71 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sun, 26 Feb 2023 17:12:36 -0500 Subject: [PATCH] bcachefs: ec: zero_out_rest_of_ec_bucket() Occasionally, we won't write to an entire bucket. This fixes the EC code to handle this case, zeroing out the rest of the bucket as needed. Signed-off-by: Kent Overstreet --- fs/bcachefs/ec.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c index 473f1c09e106..88f319992c37 100644 --- a/fs/bcachefs/ec.c +++ b/fs/bcachefs/ec.c @@ -1003,6 +1003,35 @@ err: return ret; } +static void zero_out_rest_of_ec_bucket(struct bch_fs *c, + struct ec_stripe_new *s, + unsigned block, + struct open_bucket *ob) +{ + struct bch_dev *ca = bch_dev_bkey_exists(c, ob->dev); + unsigned offset = ca->mi.bucket_size - ob->sectors_free; + int ret; + + if (!bch2_dev_get_ioref(ca, WRITE)) { + s->err = -EROFS; + return; + } + + memset(s->new_stripe.data[block] + (offset << 9), + 0, + ob->sectors_free << 9); + + ret = blkdev_issue_zeroout(ca->disk_sb.bdev, + ob->bucket * ca->mi.bucket_size + offset, + ob->sectors_free, + GFP_KERNEL, 0); + + percpu_ref_put(&ca->io_ref); + + if (ret) + s->err = ret; +} + /* * data buckets of new stripe all written: create the stripe */ @@ -1018,6 +1047,14 @@ static void ec_stripe_create(struct ec_stripe_new *s) closure_sync(&s->iodone); + for (i = 0; i < nr_data; i++) + if (s->blocks[i]) { + ob = c->open_buckets + s->blocks[i]; + + if (ob->sectors_free) + zero_out_rest_of_ec_bucket(c, s, i, ob); + } + if (s->err) { if (!bch2_err_matches(s->err, EROFS)) bch_err(c, "error creating stripe: error writing data buckets"); @@ -1159,9 +1196,6 @@ void bch2_ec_bucket_written(struct bch_fs *c, struct open_bucket *ob) { struct ec_stripe_new *s = ob->ec; - if (ob->sectors_free) - s->err = -1; - ec_stripe_new_put(c, s); } -- 2.20.1