From: Christoph Hellwig <hch@infradead.org>
To: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Cc: David Sterba <dsterba@suse.com>,
Nikolay Borisov <nborisov@suse.com>,
"linux-btrfs @ vger . kernel . org" <linux-btrfs@vger.kernel.org>,
Josef Bacik <josef@toxicpanda.com>
Subject: Re: [PATCH v3 1/5] btrfs: remove buffer heads from super block reading
Date: Tue, 28 Jan 2020 03:47:47 -0800 [thread overview]
Message-ID: <20200128114747.GA17444@infradead.org> (raw)
In-Reply-To: <20200127155931.10818-2-johannes.thumshirn@wdc.com>
On Tue, Jan 28, 2020 at 12:59:27AM +0900, Johannes Thumshirn wrote:
> struct btrfs_fs_info *fs_info = btrfs_sb(sb);
> struct btrfs_root *tree_root;
> struct btrfs_root *chunk_root;
> + struct page *super_page;
> + u8 *superblock;
Any good reason this isn't a struct btrfs_super_block * instead?
> + csum_type = btrfs_super_csum_type((struct btrfs_super_block *)
> + superblock);
> if (!btrfs_supported_super_csum(csum_type)) {
> btrfs_err(fs_info, "unsupported checksum algorithm: %u",
> csum_type);
> err = -EINVAL;
> - brelse(bh);
> + kunmap(super_page);
> + put_page(super_page);
> goto fail_alloc;
> }
>
> ret = btrfs_init_csum_hash(fs_info, csum_type);
> if (ret) {
> err = ret;
> + kunmap(super_page);
> + put_page(super_page);
> goto fail_alloc;
> }
>
> @@ -2861,10 +2867,11 @@ int __cold open_ctree(struct super_block *sb,
> * We want to check superblock checksum, the type is stored inside.
> * Pass the whole disk block of size BTRFS_SUPER_INFO_SIZE (4k).
> */
> - if (btrfs_check_super_csum(fs_info, bh->b_data)) {
> + if (btrfs_check_super_csum(fs_info, superblock)) {
> btrfs_err(fs_info, "superblock checksum mismatch");
> err = -EINVAL;
> - brelse(bh);
> + kunmap(super_page);
> + put_page(super_page);
> goto fail_csum;
> }
>
> @@ -2873,8 +2880,9 @@ int __cold open_ctree(struct super_block *sb,
> * following bytes up to INFO_SIZE, the checksum is calculated from
> * the whole block of INFO_SIZE
> */
> - memcpy(fs_info->super_copy, bh->b_data, sizeof(*fs_info->super_copy));
> - brelse(bh);
> + memcpy(fs_info->super_copy, superblock, sizeof(*fs_info->super_copy));
> + kunmap(super_page);
> + put_page(super_page);
Would it make sense to move the code up to here in a helper to
simplify the error handling?
>
> int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num,
> - struct buffer_head **bh_ret)
> + struct page **super_page)
> {
> - struct buffer_head *bh;
> struct btrfs_super_block *super;
> + struct bio_vec bio_vec;
> + struct bio bio;
> + struct page *page;
> u64 bytenr;
> + struct address_space *mapping = bdev->bd_inode->i_mapping;
> + gfp_t gfp_mask;
> + int ret;
>
> bytenr = btrfs_sb_offset(copy_num);
> if (bytenr + BTRFS_SUPER_INFO_SIZE >= i_size_read(bdev->bd_inode))
> return -EINVAL;
>
> - bh = __bread(bdev, bytenr / BTRFS_BDEV_BLOCKSIZE, BTRFS_SUPER_INFO_SIZE);
> + gfp_mask = mapping_gfp_constraint(mapping, ~__GFP_FS) | __GFP_NOFAIL;
> + page = find_or_create_page(mapping, bytenr >> PAGE_SHIFT, gfp_mask);
Why not simply use read_cache_page_gfp to find or read the page?
> - super = (struct btrfs_super_block *)bh->b_data;
> + super = kmap(page);
> if (btrfs_super_bytenr(super) != bytenr ||
> btrfs_super_magic(super) != BTRFS_MAGIC) {
> - brelse(bh);
> + kunmap(page);
> + put_page(page);
> return -EINVAL;
> }
> + kunmap(page);
>
> - *bh_ret = bh;
> + *super_page = page;
Given that both callers need the kernel virtual address, why not leave it
kmapped? OTOH if you use read_cache_page_gfp, we could just kill
btrfs_read_dev_one_super and open code the call to read_cache_page_gfp
and btrfs_super_bytenr / btrfs_super_magic in the callers.
> + bio_init(&bio, &bio_vec, 1);
> for (copy_num = 0; copy_num < BTRFS_SUPER_MIRROR_MAX;
> copy_num++) {
> + u64 bytenr = btrfs_sb_offset(copy_num);
> + struct page *page;
>
> - if (btrfs_read_dev_one_super(bdev, copy_num, &bh))
> + if (btrfs_read_dev_one_super(bdev, copy_num, &page))
> continue;
>
> - disk_super = (struct btrfs_super_block *)bh->b_data;
> + disk_super = kmap(page) + offset_in_page(bytenr);
>
> memset(&disk_super->magic, 0, sizeof(disk_super->magic));
> - set_buffer_dirty(bh);
> - sync_dirty_buffer(bh);
> - brelse(bh);
> +
> + bio.bi_iter.bi_sector = bytenr >> SECTOR_SHIFT;
> + bio_set_dev(&bio, bdev);
> + bio.bi_opf = REQ_OP_WRITE;
> + bio_add_page(&bio, page, BTRFS_SUPER_INFO_SIZE,
> + offset_in_page(bytenr));
> +
> + lock_page(page);
> + submit_bio_wait(&bio);
> + unlock_page(page);
> + kunmap(page);
> + put_page(page);
> + bio_reset(&bio);
Facoting out the code to write a single sb would clean this up a bit.
Also no real need to keep the page kmapped when under I/O.
next prev parent reply other threads:[~2020-01-28 11:47 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-27 15:59 [PATCH v3 0/5] btrfs: remove buffer heads form superblock handling Johannes Thumshirn
2020-01-27 15:59 ` [PATCH v3 1/5] btrfs: remove buffer heads from super block reading Johannes Thumshirn
2020-01-28 11:47 ` Christoph Hellwig [this message]
2020-01-30 10:12 ` Johannes Thumshirn
2020-01-27 15:59 ` [PATCH v3 2/5] btrfs: remove use of buffer_heads from superblock writeout Johannes Thumshirn
2020-01-28 11:52 ` Christoph Hellwig
2020-01-27 15:59 ` [PATCH v3 3/5] btrfs: remove btrfsic_submit_bh() Johannes Thumshirn
2020-01-27 15:59 ` [PATCH v3 4/5] btrfs: remove buffer_heads from btrfsic_process_written_block() Johannes Thumshirn
2020-01-27 15:59 ` [PATCH v3 5/5] btrfs: remove buffer_heads form superblock mirror integrity checking Johannes Thumshirn
2020-01-29 14:25 ` [PATCH v3 0/5] btrfs: remove buffer heads form superblock handling David Sterba
2020-01-30 11:23 ` Johannes Thumshirn
2020-01-30 12:15 ` David Sterba
2020-01-30 13:39 ` Christoph Hellwig
2020-01-30 15:53 ` Johannes Thumshirn
2020-01-30 15:56 ` Christoph Hellwig
2020-01-30 16:09 ` Johannes Thumshirn
2020-01-30 16:15 ` Christoph Hellwig
2020-01-30 16:16 ` David Sterba
2020-01-31 13:43 ` Johannes Thumshirn
2020-02-03 8:29 ` Christoph Hellwig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200128114747.GA17444@infradead.org \
--to=hch@infradead.org \
--cc=dsterba@suse.com \
--cc=johannes.thumshirn@wdc.com \
--cc=josef@toxicpanda.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=nborisov@suse.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox