Commit 9d8022db authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet
Browse files

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: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent a0857785
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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++;

+15 −16
Original line number Diff line number Diff line
@@ -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 @@ static const char *read_one_super(struct bch_sb_handle *sb, u64 offset)
	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;
+1 −2
Original line number Diff line number Diff line
@@ -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);
}
+1 −1
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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;