On 17.01.20 г. 14:51 ч., Johannes Thumshirn wrote:
> Super-block reading in BTRFS is done using buffer_heads. Buffer_heads have
> some drawbacks, like not being able to propagate errors from the lower
> layers.
>
> Change the buffer_heads to BIOs.
>
Generally this looks good. I guess as a follow up I can send the rest of
my code which cleans up a bit parameters of the involved function and
let people decide if it makes the code more readable. One minor nit
below. In any case:
Reviewed-by: Nikolay Borisov <nborisov@xxxxxxxx>
<snip>
> @@ -7270,25 +7268,41 @@ int btrfs_get_dev_stats(struct btrfs_fs_info *fs_info,
>
> void btrfs_scratch_superblocks(struct block_device *bdev, const char *device_path)
> {
> - struct buffer_head *bh;
> + struct page *super_page;
> + struct bio_vec bio_vec;
> + struct bio bio;
> struct btrfs_super_block *disk_super;
> int copy_num;
> + int ret;
>
> if (!bdev)
> return;
>
> + bio_init(&bio, &bio_vec, 1);
> for (copy_num = 0; copy_num < BTRFS_SUPER_MIRROR_MAX;
> copy_num++) {
> + u64 bytenr;
nit: super_page is only used in this loop so IMO it will be better if
it's declared inside of it.
>
> - if (btrfs_read_dev_one_super(bdev, copy_num, &bh))
> + if (btrfs_read_dev_one_super(bdev, copy_num, &super_page))
> continue;
>
> - disk_super = (struct btrfs_super_block *)bh->b_data;
> + disk_super = page_address(super_page);
>
> memset(&disk_super->magic, 0, sizeof(disk_super->magic));
> - set_buffer_dirty(bh);
> - sync_dirty_buffer(bh);
> - brelse(bh);
> +
> + bytenr = btrfs_sb_offset(copy_num);
> +
> + bio.bi_iter.bi_sector = bytenr >> SECTOR_SHIFT;
> + bio_set_dev(&bio, bdev);
> + bio_set_op_attrs(&bio, REQ_OP_WRITE, 0);
> + bio_add_page(&bio, super_page, PAGE_SIZE, 0);
> +
> + ret = submit_bio_wait(&bio);
> + WARN_ON(ret);
> +
> + __free_page(super_page);
> + bio_reset(&bio);
> +
> }
>
> /* Notify udev that device has changed */
> diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
> index 9c7d4fe5c39a..46a65b15eb93 100644
> --- a/fs/btrfs/volumes.h
> +++ b/fs/btrfs/volumes.h
> @@ -17,8 +17,6 @@ extern struct mutex uuid_mutex;
>
> #define BTRFS_STRIPE_LEN SZ_64K
>
> -struct buffer_head;
> -
> struct btrfs_io_geometry {
> /* remaining bytes before crossing a stripe */
> u64 len;
>