bcachefs: Check alignment in write path
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 22 Aug 2019 00:16:42 +0000 (20:16 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:25 +0000 (17:08 -0400)
Also - fix alignment in bch2_set_page_dirty()

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/fs-io.c
fs/bcachefs/io.c

index 771fb111550d1e231554711b8cb6a67ae07b00c0..1873bbb9afda3701d96e4fa605856d5a766c061d 100644 (file)
@@ -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);
index 4d359931edb3090d6c3e1113de371e9d8096c5bd..5db83374403b83534f4c46925c2695a94d57146a 100644 (file)
@@ -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 */