On 12/02/2020 18:06, David Sterba wrote: > On Wed, Feb 12, 2020 at 04:17:04PM +0900, Johannes Thumshirn wrote: >> @@ -762,29 +761,45 @@ static int btrfsic_process_superblock_dev_mirror( >> struct btrfs_fs_info *fs_info = state->fs_info; >> struct btrfs_super_block *super_tmp; >> u64 dev_bytenr; >> - struct buffer_head *bh; >> struct btrfsic_block *superblock_tmp; >> int pass; >> struct block_device *const superblock_bdev = device->bdev; >> + struct page *page; >> + struct bio bio; >> + struct bio_vec bio_vec; >> + struct address_space *mapping = superblock_bdev->bd_inode->i_mapping; >> + int ret; >> >> /* super block bytenr is always the unmapped device bytenr */ >> dev_bytenr = btrfs_sb_offset(superblock_mirror_num); >> if (dev_bytenr + BTRFS_SUPER_INFO_SIZE > device->commit_total_bytes) >> return -1; >> - bh = __bread(superblock_bdev, dev_bytenr / BTRFS_BDEV_BLOCKSIZE, >> - BTRFS_SUPER_INFO_SIZE); >> - if (NULL == bh) >> + >> + page = find_or_create_page(mapping, dev_bytenr >> PAGE_SHIFT, GFP_NOFS); >> + if (!page) >> + return -1; >> + >> + bio_init(&bio, &bio_vec, 1); >> + bio.bi_iter.bi_sector = dev_bytenr >> SECTOR_SHIFT; >> + bio_set_dev(&bio, superblock_bdev); >> + bio_set_op_attrs(&bio, REQ_OP_READ, 0); >> + bio_add_page(&bio, page, BTRFS_SUPER_INFO_SIZE, 0); >> + >> + ret = submit_bio_wait(&bio); >> + if (ret) >> return -1; >> - super_tmp = (struct btrfs_super_block *) >> - (bh->b_data + (dev_bytenr & (BTRFS_BDEV_BLOCKSIZE - 1))); >> + >> + unlock_page(page); >> + >> + super_tmp = kmap(page); > > I beleve the same reasoning applies here regarding kmap, it's the bdev > mapping and we won't get a highmem page. > Ah damn it my bad and __bio_add_page() as well. Can I send you a follow-on patch to fold in?
