summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-04-06 14:00:56 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2022-03-12 20:12:31 -0500
commitf9a9c96ee6bdb8bee937f3e8b333150f9fba4966 (patch)
tree420bb17b78e61c9b9ff8c9b8c29160188aa19a3a
parent84a33a722e5a6434066b1de2f68f4affbadc4b79 (diff)
bcachefs: Eliminate more PAGE_SIZE uses
In userspace, we don't really have a well defined PAGE_SIZE and shouln't be relying on it. This is some more incremental work to remove references to it. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/debug.c4
-rw-r--r--fs/bcachefs/super-io.c32
-rw-r--r--fs/bcachefs/super.c3
-rw-r--r--fs/bcachefs/super_types.h2
-rw-r--r--fs/bcachefs/util.c2
5 files changed, 21 insertions, 22 deletions
diff --git a/fs/bcachefs/debug.c b/fs/bcachefs/debug.c
index acf600387c9f..90364b55aa40 100644
--- a/fs/bcachefs/debug.c
+++ b/fs/bcachefs/debug.c
@@ -150,7 +150,7 @@ struct dump_iter {
struct bch_fs *c;
enum btree_id id;
- char buf[PAGE_SIZE];
+ char buf[1 << 12];
size_t bytes; /* what's currently in buf */
char __user *ubuf; /* destination user buffer */
@@ -230,7 +230,7 @@ static ssize_t bch2_read_btree(struct file *file, char __user *buf,
while (k.k && !(err = bkey_err(k))) {
bch2_bkey_val_to_text(&PBUF(i->buf), i->c, k);
i->bytes = strlen(i->buf);
- BUG_ON(i->bytes >= PAGE_SIZE);
+ BUG_ON(i->bytes >= sizeof(i->buf));
i->buf[i->bytes] = '\n';
i->bytes++;
diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c
index f8f57caa417a..de8d49e3ef02 100644
--- a/fs/bcachefs/super-io.c
+++ b/fs/bcachefs/super-io.c
@@ -50,8 +50,7 @@ static struct bch_sb_field *__bch2_sb_field_resize(struct bch_sb_handle *sb,
unsigned old_u64s = f ? le32_to_cpu(f->u64s) : 0;
unsigned sb_u64s = le32_to_cpu(sb->sb->u64s) + u64s - old_u64s;
- BUG_ON(get_order(__vstruct_bytes(struct bch_sb, sb_u64s)) >
- sb->page_order);
+ BUG_ON(__vstruct_bytes(struct bch_sb, sb_u64s) > sb->buffer_size);
if (!f && !u64s) {
/* nothing to do: */
@@ -101,18 +100,23 @@ void bch2_free_super(struct bch_sb_handle *sb)
if (!IS_ERR_OR_NULL(sb->bdev))
blkdev_put(sb->bdev, sb->mode);
- free_pages((unsigned long) sb->sb, sb->page_order);
+ kfree(sb->sb);
memset(sb, 0, sizeof(*sb));
}
int bch2_sb_realloc(struct bch_sb_handle *sb, unsigned u64s)
{
size_t new_bytes = __vstruct_bytes(struct bch_sb, u64s);
- unsigned order = get_order(new_bytes);
+ size_t new_buffer_size;
struct bch_sb *new_sb;
struct bio *bio;
- if (sb->sb && sb->page_order >= order)
+ if (sb->bdev)
+ new_bytes = max_t(size_t, new_bytes, bdev_logical_block_size(sb->bdev));
+
+ new_buffer_size = roundup_pow_of_two(new_bytes);
+
+ if (sb->sb && sb->buffer_size >= new_buffer_size)
return 0;
if (sb->have_layout) {
@@ -127,14 +131,15 @@ int bch2_sb_realloc(struct bch_sb_handle *sb, unsigned u64s)
}
}
- if (sb->page_order >= order && sb->sb)
+ if (sb->buffer_size >= new_buffer_size && sb->sb)
return 0;
if (dynamic_fault("bcachefs:add:super_realloc"))
return -ENOMEM;
if (sb->have_bio) {
- bio = bio_kmalloc(GFP_KERNEL, 1 << order);
+ bio = bio_kmalloc(GFP_KERNEL,
+ DIV_ROUND_UP(new_buffer_size, PAGE_SIZE));
if (!bio)
return -ENOMEM;
@@ -143,17 +148,12 @@ int bch2_sb_realloc(struct bch_sb_handle *sb, unsigned u64s)
sb->bio = bio;
}
- new_sb = (void *) __get_free_pages(GFP_NOFS|__GFP_ZERO, order);
+ new_sb = krealloc(sb->sb, new_buffer_size, GFP_NOFS|__GFP_ZERO);
if (!new_sb)
return -ENOMEM;
- if (sb->sb)
- memcpy(new_sb, sb->sb, PAGE_SIZE << sb->page_order);
-
- free_pages((unsigned long) sb->sb, sb->page_order);
sb->sb = new_sb;
-
- sb->page_order = order;
+ sb->buffer_size = new_buffer_size;
return 0;
}
@@ -475,7 +475,7 @@ reread:
bio_set_dev(sb->bio, sb->bdev);
sb->bio->bi_iter.bi_sector = offset;
bio_set_op_attrs(sb->bio, REQ_OP_READ, REQ_SYNC|REQ_META);
- bch2_bio_map(sb->bio, sb->sb, PAGE_SIZE << sb->page_order);
+ bch2_bio_map(sb->bio, sb->sb, sb->buffer_size);
if (submit_bio_wait(sb->bio))
return "IO error";
@@ -492,7 +492,7 @@ reread:
if (bytes > 512 << sb->sb->layout.sb_max_size_bits)
return "Bad superblock: too big";
- if (get_order(bytes) > sb->page_order) {
+ if (bytes > sb->buffer_size) {
if (bch2_sb_realloc(sb, le32_to_cpu(sb->sb->u64s)))
return "cannot allocate memory";
goto reread;
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index 70a4d0dcc395..7ce867e5ff0c 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -502,8 +502,7 @@ static void __bch2_fs_free(struct bch_fs *c)
if (c->wq)
destroy_workqueue(c->wq);
- free_pages((unsigned long) c->disk_sb.sb,
- c->disk_sb.page_order);
+ bch2_free_super(&c->disk_sb);
kvpfree(c, sizeof(*c));
module_put(THIS_MODULE);
}
diff --git a/fs/bcachefs/super_types.h b/fs/bcachefs/super_types.h
index 069973a38f12..96023f37afea 100644
--- a/fs/bcachefs/super_types.h
+++ b/fs/bcachefs/super_types.h
@@ -6,7 +6,7 @@ struct bch_sb_handle {
struct bch_sb *sb;
struct block_device *bdev;
struct bio *bio;
- unsigned page_order;
+ size_t buffer_size;
fmode_t mode;
unsigned have_layout:1;
unsigned have_bio:1;
diff --git a/fs/bcachefs/util.c b/fs/bcachefs/util.c
index 2709163e02b5..e3ad26e244ab 100644
--- a/fs/bcachefs/util.c
+++ b/fs/bcachefs/util.c
@@ -154,7 +154,7 @@ void bch2_flags_to_text(struct printbuf *out,
u64 bch2_read_flag_list(char *opt, const char * const list[])
{
u64 ret = 0;
- char *p, *s, *d = kstrndup(opt, PAGE_SIZE - 1, GFP_KERNEL);
+ char *p, *s, *d = kstrdup(opt, GFP_KERNEL);
if (!d)
return -ENOMEM;