diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-11-03 20:04:54 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2018-11-03 20:11:06 -0400 |
commit | a780698e2947c2c072071e44aaa9eed1b59258b1 (patch) | |
tree | 163d14e94141267072446cfaf4c3a21a819db60e | |
parent | fc7576d28a3fa67088be08df2ac2b986a3b82e9e (diff) |
bcachefs: Some fixes for building in userspace
userspace allocators don't align allocations as nicely as kernel
allocators, which meant that in some cases we weren't allocating big
enough bvec arrays - just make the calculations more rigorous and
explicit to fix it.
-rw-r--r-- | fs/bcachefs/bset.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/btree_io.c | 8 | ||||
-rw-r--r-- | fs/bcachefs/debug.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/journal_io.c | 10 | ||||
-rw-r--r-- | fs/bcachefs/util.h | 8 |
5 files changed, 25 insertions, 7 deletions
diff --git a/fs/bcachefs/bset.c b/fs/bcachefs/bset.c index 2b1460f55aae..c631e30aca53 100644 --- a/fs/bcachefs/bset.c +++ b/fs/bcachefs/bset.c @@ -1689,7 +1689,7 @@ struct bkey_packed *bch2_btree_node_iter_prev_filter(struct btree_node_iter *ite struct bkey_packed *orig_pos = bch2_btree_node_iter_peek_all(iter, b); struct btree_node_iter_set *set; struct bset_tree *t; - unsigned end; + unsigned end = 0; bch2_btree_node_iter_verify(iter, b); diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c index aee5dba0e1db..beab463b51e1 100644 --- a/fs/bcachefs/btree_io.c +++ b/fs/bcachefs/btree_io.c @@ -1424,7 +1424,9 @@ void bch2_btree_node_read(struct bch_fs *c, struct btree *b, ca = bch_dev_bkey_exists(c, pick.ptr.dev); - bio = bio_alloc_bioset(GFP_NOIO, btree_pages(c), &c->btree_bio); + bio = bio_alloc_bioset(GFP_NOIO, buf_pages(b->data, + btree_bytes(c)), + &c->btree_bio); rb = container_of(bio, struct btree_read_bio, bio); rb->c = c; rb->start_time = local_clock(); @@ -1879,7 +1881,9 @@ void __bch2_btree_node_write(struct bch_fs *c, struct btree *b, trace_btree_write(b, bytes_to_write, sectors_to_write); - wbio = container_of(bio_alloc_bioset(GFP_NOIO, 1 << order, &c->btree_bio), + wbio = container_of(bio_alloc_bioset(GFP_NOIO, + buf_pages(data, sectors_to_write << 9), + &c->btree_bio), struct btree_write_bio, wbio.bio); wbio_init(&wbio->wbio.bio); wbio->data = data; diff --git a/fs/bcachefs/debug.c b/fs/bcachefs/debug.c index 50aac3a4a818..f69d76ec1e78 100644 --- a/fs/bcachefs/debug.c +++ b/fs/bcachefs/debug.c @@ -62,7 +62,9 @@ void __bch2_btree_verify(struct bch_fs *c, struct btree *b) if (!bch2_dev_get_ioref(ca, READ)) return; - bio = bio_alloc_bioset(GFP_NOIO, btree_pages(c), &c->btree_bio); + bio = bio_alloc_bioset(GFP_NOIO, + buf_pages(n_sorted, btree_bytes(c)), + &c->btree_bio); bio_set_dev(bio, ca->disk_sb.bdev); bio->bi_opf = REQ_OP_READ|REQ_META; bio->bi_iter.bi_sector = pick.ptr.offset; diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c index acf7db721fad..0cb1bc3c0df7 100644 --- a/fs/bcachefs/journal_io.c +++ b/fs/bcachefs/journal_io.c @@ -429,7 +429,6 @@ static int journal_read_bucket(struct bch_dev *ca, { struct bch_fs *c = ca->fs; struct journal_device *ja = &ca->journal; - struct bio *bio = ja->bio; struct jset *j = NULL; unsigned sectors, sectors_read = 0; u64 offset = bucket_to_sector(ca, ja->buckets[bucket]), @@ -441,10 +440,14 @@ static int journal_read_bucket(struct bch_dev *ca, while (offset < end) { if (!sectors_read) { -reread: sectors_read = min_t(unsigned, + struct bio *bio; +reread: + sectors_read = min_t(unsigned, end - offset, buf->size >> 9); - bio_reset(bio); + bio = bio_kmalloc(GFP_KERNEL, + buf_pages(buf->data, + sectors_read << 9)); bio_set_dev(bio, ca->disk_sb.bdev); bio->bi_iter.bi_sector = offset; bio->bi_iter.bi_size = sectors_read << 9; @@ -452,6 +455,7 @@ reread: sectors_read = min_t(unsigned, bch2_bio_map(bio, buf->data); ret = submit_bio_wait(bio); + bio_put(bio); if (bch2_dev_io_err_on(ret, ca, "journal read from sector %llu", diff --git a/fs/bcachefs/util.h b/fs/bcachefs/util.h index 66febaea031a..433ba9c14dcb 100644 --- a/fs/bcachefs/util.h +++ b/fs/bcachefs/util.h @@ -83,6 +83,14 @@ struct closure; (__builtin_types_compatible_p(typeof(_val), _type) || \ __builtin_types_compatible_p(typeof(_val), const _type)) +/* Userspace doesn't align allocations as nicely as the kernel allocators: */ +static inline size_t buf_pages(void *p, size_t len) +{ + return DIV_ROUND_UP(len + + ((unsigned long) p & (PAGE_SIZE - 1)), + PAGE_SIZE); +} + static inline void vpfree(void *p, size_t size) { if (is_vmalloc_addr(p)) |