@@ -85,13 +85,15 @@ struct btrfs_dio_private {
8585 */
8686 refcount_t refs ;
8787
88- /* dio_bio came from fs/direct-io.c */
89- struct bio * dio_bio ;
90-
9188 /* Array of checksums */
92- u8 csums [];
89+ u8 * csums ;
90+
91+ /* This must be last */
92+ struct bio bio ;
9393};
9494
95+ static struct bio_set btrfs_dio_bioset ;
96+
9597struct btrfs_rename_ctx {
9698 /* Output field. Stores the index number of the old directory entry. */
9799 u64 index ;
@@ -7828,19 +7830,19 @@ static void btrfs_dio_private_put(struct btrfs_dio_private *dip)
78287830 if (!refcount_dec_and_test (& dip -> refs ))
78297831 return ;
78307832
7831- if (btrfs_op (dip -> dio_bio ) == BTRFS_MAP_WRITE ) {
7833+ if (btrfs_op (& dip -> bio ) == BTRFS_MAP_WRITE ) {
78327834 __endio_write_update_ordered (BTRFS_I (dip -> inode ),
78337835 dip -> file_offset ,
78347836 dip -> bytes ,
7835- !dip -> dio_bio -> bi_status );
7837+ !dip -> bio . bi_status );
78367838 } else {
78377839 unlock_extent (& BTRFS_I (dip -> inode )-> io_tree ,
78387840 dip -> file_offset ,
78397841 dip -> file_offset + dip -> bytes - 1 );
78407842 }
78417843
7842- bio_endio (dip -> dio_bio );
7843- kfree ( dip );
7844+ kfree (dip -> csums );
7845+ bio_endio ( & dip -> bio );
78447846}
78457847
78467848static void submit_dio_repair_bio (struct inode * inode , struct bio * bio ,
@@ -7942,7 +7944,7 @@ static void btrfs_end_dio_bio(struct bio *bio)
79427944 err = btrfs_check_read_dio_bio (dip , bbio , !err );
79437945
79447946 if (err )
7945- dip -> dio_bio -> bi_status = err ;
7947+ dip -> bio . bi_status = err ;
79467948
79477949 btrfs_record_physical_zoned (dip -> inode , bbio -> file_offset , bio );
79487950
@@ -7997,49 +7999,16 @@ static inline blk_status_t btrfs_submit_dio_bio(struct bio *bio,
79977999 return ret ;
79988000}
79998001
8000- /*
8001- * If this succeeds, the btrfs_dio_private is responsible for cleaning up locked
8002- * or ordered extents whether or not we submit any bios.
8003- */
8004- static struct btrfs_dio_private * btrfs_create_dio_private (struct bio * dio_bio ,
8005- struct inode * inode ,
8006- loff_t file_offset )
8007- {
8008- const bool write = (btrfs_op (dio_bio ) == BTRFS_MAP_WRITE );
8009- const bool csum = !(BTRFS_I (inode )-> flags & BTRFS_INODE_NODATASUM );
8010- size_t dip_size ;
8011- struct btrfs_dio_private * dip ;
8012-
8013- dip_size = sizeof (* dip );
8014- if (!write && csum ) {
8015- struct btrfs_fs_info * fs_info = btrfs_sb (inode -> i_sb );
8016- size_t nblocks ;
8017-
8018- nblocks = dio_bio -> bi_iter .bi_size >> fs_info -> sectorsize_bits ;
8019- dip_size += fs_info -> csum_size * nblocks ;
8020- }
8021-
8022- dip = kzalloc (dip_size , GFP_NOFS );
8023- if (!dip )
8024- return NULL ;
8025-
8026- dip -> inode = inode ;
8027- dip -> file_offset = file_offset ;
8028- dip -> bytes = dio_bio -> bi_iter .bi_size ;
8029- dip -> dio_bio = dio_bio ;
8030- refcount_set (& dip -> refs , 1 );
8031- return dip ;
8032- }
8033-
80348002static void btrfs_submit_direct (const struct iomap_iter * iter ,
80358003 struct bio * dio_bio , loff_t file_offset )
80368004{
8005+ struct btrfs_dio_private * dip =
8006+ container_of (dio_bio , struct btrfs_dio_private , bio );
80378007 struct inode * inode = iter -> inode ;
80388008 const bool write = (btrfs_op (dio_bio ) == BTRFS_MAP_WRITE );
80398009 struct btrfs_fs_info * fs_info = btrfs_sb (inode -> i_sb );
80408010 const bool raid56 = (btrfs_data_alloc_profile (fs_info ) &
80418011 BTRFS_BLOCK_GROUP_RAID56_MASK );
8042- struct btrfs_dio_private * dip ;
80438012 struct bio * bio ;
80448013 u64 start_sector ;
80458014 int async_submit = 0 ;
@@ -8053,24 +8022,25 @@ static void btrfs_submit_direct(const struct iomap_iter *iter,
80538022 struct btrfs_dio_data * dio_data = iter -> private ;
80548023 struct extent_map * em = NULL ;
80558024
8056- dip = btrfs_create_dio_private (dio_bio , inode , file_offset );
8057- if (!dip ) {
8058- if (!write ) {
8059- unlock_extent (& BTRFS_I (inode )-> io_tree , file_offset ,
8060- file_offset + dio_bio -> bi_iter .bi_size - 1 );
8061- }
8062- dio_bio -> bi_status = BLK_STS_RESOURCE ;
8063- bio_endio (dio_bio );
8064- return ;
8065- }
8025+ dip -> inode = inode ;
8026+ dip -> file_offset = file_offset ;
8027+ dip -> bytes = dio_bio -> bi_iter .bi_size ;
8028+ refcount_set (& dip -> refs , 1 );
8029+ dip -> csums = NULL ;
8030+
8031+ if (!write && !(BTRFS_I (inode )-> flags & BTRFS_INODE_NODATASUM )) {
8032+ unsigned int nr_sectors =
8033+ (dio_bio -> bi_iter .bi_size >> fs_info -> sectorsize_bits );
80668034
8067- if (!write ) {
80688035 /*
80698036 * Load the csums up front to reduce csum tree searches and
80708037 * contention when submitting bios.
8071- *
8072- * If we have csums disabled this will do nothing.
80738038 */
8039+ status = BLK_STS_RESOURCE ;
8040+ dip -> csums = kcalloc (nr_sectors , fs_info -> csum_size , GFP_NOFS );
8041+ if (!dip )
8042+ goto out_err ;
8043+
80748044 status = btrfs_lookup_bio_sums (inode , dio_bio , dip -> csums );
80758045 if (status != BLK_STS_OK )
80768046 goto out_err ;
@@ -8160,7 +8130,7 @@ static void btrfs_submit_direct(const struct iomap_iter *iter,
81608130out_err_em :
81618131 free_extent_map (em );
81628132out_err :
8163- dip -> dio_bio -> bi_status = status ;
8133+ dio_bio -> bi_status = status ;
81648134 btrfs_dio_private_put (dip );
81658135}
81668136
@@ -8171,6 +8141,7 @@ static const struct iomap_ops btrfs_dio_iomap_ops = {
81718141
81728142static const struct iomap_dio_ops btrfs_dio_ops = {
81738143 .submit_io = btrfs_submit_direct ,
8144+ .bio_set = & btrfs_dio_bioset ,
81748145};
81758146
81768147ssize_t btrfs_dio_rw (struct kiocb * iocb , struct iov_iter * iter , size_t done_before )
@@ -8991,6 +8962,7 @@ void __cold btrfs_destroy_cachep(void)
89918962 * destroy cache.
89928963 */
89938964 rcu_barrier ();
8965+ bioset_exit (& btrfs_dio_bioset );
89948966 kmem_cache_destroy (btrfs_inode_cachep );
89958967 kmem_cache_destroy (btrfs_trans_handle_cachep );
89968968 kmem_cache_destroy (btrfs_path_cachep );
@@ -9031,6 +9003,11 @@ int __init btrfs_init_cachep(void)
90319003 if (!btrfs_free_space_bitmap_cachep )
90329004 goto fail ;
90339005
9006+ if (bioset_init (& btrfs_dio_bioset , BIO_POOL_SIZE ,
9007+ offsetof(struct btrfs_dio_private , bio ),
9008+ BIOSET_NEED_BVECS ))
9009+ goto fail ;
9010+
90349011 return 0 ;
90359012fail :
90369013 btrfs_destroy_cachep ();
0 commit comments