summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2018-11-03 20:04:54 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2018-11-03 20:11:06 -0400
commita780698e2947c2c072071e44aaa9eed1b59258b1 (patch)
tree163d14e94141267072446cfaf4c3a21a819db60e
parentfc7576d28a3fa67088be08df2ac2b986a3b82e9e (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.c2
-rw-r--r--fs/bcachefs/btree_io.c8
-rw-r--r--fs/bcachefs/debug.c4
-rw-r--r--fs/bcachefs/journal_io.c10
-rw-r--r--fs/bcachefs/util.h8
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))