Commit 94bc95c4 authored by Kent Overstreet's avatar Kent Overstreet

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: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 039c45fe
...@@ -1003,6 +1003,35 @@ static int ec_stripe_update_extents(struct bch_fs *c, struct ec_stripe_buf *s) ...@@ -1003,6 +1003,35 @@ static int ec_stripe_update_extents(struct bch_fs *c, struct ec_stripe_buf *s)
return ret; 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 * data buckets of new stripe all written: create the stripe
*/ */
...@@ -1018,6 +1047,14 @@ static void ec_stripe_create(struct ec_stripe_new *s) ...@@ -1018,6 +1047,14 @@ static void ec_stripe_create(struct ec_stripe_new *s)
closure_sync(&s->iodone); 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 (s->err) {
if (!bch2_err_matches(s->err, EROFS)) if (!bch2_err_matches(s->err, EROFS))
bch_err(c, "error creating stripe: error writing data buckets"); 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) ...@@ -1159,9 +1196,6 @@ void bch2_ec_bucket_written(struct bch_fs *c, struct open_bucket *ob)
{ {
struct ec_stripe_new *s = ob->ec; struct ec_stripe_new *s = ob->ec;
if (ob->sectors_free)
s->err = -1;
ec_stripe_new_put(c, s); ec_stripe_new_put(c, s);
} }
......
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