diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-08-21 20:16:42 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:25 -0400 |
commit | 4b0a66d508d7bfcd2dd2513d4f41a0f3a20f64d5 (patch) | |
tree | c2e9ef73d30aef0f93efaac303c38fbcf6a67e62 | |
parent | 41fcd6215093b0c40fb4072e04a2b34f09eb4235 (diff) | |
download | lwn-4b0a66d508d7bfcd2dd2513d4f41a0f3a20f64d5.tar.gz lwn-4b0a66d508d7bfcd2dd2513d4f41a0f3a20f64d5.zip |
bcachefs: Check alignment in write path
Also - fix alignment in bch2_set_page_dirty()
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/fs-io.c | 8 | ||||
-rw-r--r-- | fs/bcachefs/io.c | 21 |
2 files changed, 19 insertions, 10 deletions
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c index 771fb111550d..1873bbb9afda 100644 --- a/fs/bcachefs/fs-io.c +++ b/fs/bcachefs/fs-io.c @@ -684,8 +684,8 @@ static int bch2_page_reservation_get(struct bch_fs *c, if (!s) return -ENOMEM; - for (i = offset / 512; - i < DIV_ROUND_UP(offset + len, 512); + for (i = round_down(offset, block_bytes(c)) >> 9; + i < round_up(offset + len, block_bytes(c)) >> 9; i++) { disk_sectors += sectors_to_reserve(&s->s[i], res->disk.nr_replicas); @@ -757,8 +757,8 @@ static void bch2_set_page_dirty(struct bch_fs *c, struct bch_page_state *s = bch2_page_state(page); unsigned i, dirty_sectors = 0; - for (i = offset / 512; - i < DIV_ROUND_UP(offset + len, 512); + for (i = round_down(offset, block_bytes(c)) >> 9; + i < round_up(offset + len, block_bytes(c)) >> 9; i++) { unsigned sectors = sectors_to_reserve(&s->s[i], res->disk.nr_replicas); diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c index 4d359931edb3..5db83374403b 100644 --- a/fs/bcachefs/io.c +++ b/fs/bcachefs/io.c @@ -920,30 +920,39 @@ flush_io: void bch2_write(struct closure *cl) { struct bch_write_op *op = container_of(cl, struct bch_write_op, cl); + struct bio *bio = &op->wbio.bio; struct bch_fs *c = op->c; BUG_ON(!op->nr_replicas); BUG_ON(!op->write_point.v); BUG_ON(!bkey_cmp(op->pos, POS_MAX)); + if (bio_sectors(bio) & (c->opts.block_size - 1)) { + __bcache_io_error(c, "misaligned write"); + op->error = -EIO; + goto err; + } + op->start_time = local_clock(); bch2_keylist_init(&op->insert_keys, op->inline_keys); - wbio_init(&op->wbio.bio)->put_bio = false; + wbio_init(bio)->put_bio = false; if (c->opts.nochanges || !percpu_ref_tryget(&c->writes)) { __bcache_io_error(c, "read only"); op->error = -EROFS; - if (!(op->flags & BCH_WRITE_NOPUT_RESERVATION)) - bch2_disk_reservation_put(c, &op->res); - closure_return(cl); - return; + goto err; } - bch2_increment_clock(c, bio_sectors(&op->wbio.bio), WRITE); + bch2_increment_clock(c, bio_sectors(bio), WRITE); continue_at_nobarrier(cl, __bch2_write, NULL); + return; +err: + if (!(op->flags & BCH_WRITE_NOPUT_RESERVATION)) + bch2_disk_reservation_put(c, &op->res); + closure_return(cl); } /* Cache promotion on read */ |