bcachefs: Eliminate more PAGE_SIZE uses
authorKent Overstreet <kent.overstreet@gmail.com>
Tue, 6 Apr 2021 18:00:56 +0000 (14:00 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:59 +0000 (17:08 -0400)
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>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/debug.c
fs/bcachefs/super-io.c
fs/bcachefs/super.c
fs/bcachefs/super_types.h
fs/bcachefs/util.c

index 111310344cec2a5c3708c15b8bcdebd6c4de5e7e..eb8c57d253fba3f1b3632302c5ad302319c990ad 100644 (file)
@@ -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++;
 
index e397a2a70c9cf73fe7970211db5e06b78b36cb4b..bf36a5743607ac2842be3e6072e3002e0198faab 100644 (file)
@@ -53,8 +53,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: */
@@ -105,18 +104,23 @@ void bch2_free_super(struct bch_sb_handle *sb)
                blkdev_put(sb->bdev, sb->holder);
        kfree(sb->holder);
 
-       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) {
@@ -129,14 +133,14 @@ 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) {
-               unsigned nr_bvecs = 1 << order;
+               unsigned nr_bvecs = DIV_ROUND_UP(new_buffer_size, PAGE_SIZE);
 
                bio = bio_kmalloc(nr_bvecs, GFP_KERNEL);
                if (!bio)
@@ -149,17 +153,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;
 }
@@ -480,7 +479,7 @@ static const char *read_one_super(struct bch_sb_handle *sb, u64 offset)
 reread:
        bio_reset(sb->bio, sb->bdev, REQ_OP_READ|REQ_SYNC|REQ_META);
        sb->bio->bi_iter.bi_sector = offset;
-       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";
@@ -498,7 +497,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;
index 529d33f4a6d7bcd33d701a90ea3221b53265a897..385b41f167549e68811e3b7b943ae995ff460163 100644 (file)
@@ -509,8 +509,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);
 }
index e3a989e3e9d91e28834d34f8f278425f84a47562..b14b2d82c655a43ee2730c1368df06e26fa54602 100644 (file)
@@ -7,7 +7,7 @@ struct bch_sb_handle {
        struct block_device     *bdev;
        struct bio              *bio;
        void                    *holder;
-       unsigned                page_order;
+       size_t                  buffer_size;
        fmode_t                 mode;
        unsigned                have_layout:1;
        unsigned                have_bio:1;
index 6e665f7f25a3190b920d855223f2e5a9b096f776..f183c9d80e2c2dab2d3c0d6eddb0a4d9946e4c85 100644 (file)
@@ -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;