summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-08-21 20:16:42 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:25 -0400
commit4b0a66d508d7bfcd2dd2513d4f41a0f3a20f64d5 (patch)
treec2e9ef73d30aef0f93efaac303c38fbcf6a67e62
parent41fcd6215093b0c40fb4072e04a2b34f09eb4235 (diff)
downloadlwn-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.c8
-rw-r--r--fs/bcachefs/io.c21
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 */