@@ -7751,9 +7751,9 @@ static int btrfs_check_dio_repairable(struct inode *inode,
77517751}
77527752
77537753static int dio_read_error (struct inode * inode , struct bio * failed_bio ,
7754- struct page * page , u64 start , u64 end ,
7755- int failed_mirror , bio_end_io_t * repair_endio ,
7756- void * repair_arg )
7754+ struct page * page , unsigned int pgoff ,
7755+ u64 start , u64 end , int failed_mirror ,
7756+ bio_end_io_t * repair_endio , void * repair_arg )
77577757{
77587758 struct io_failure_record * failrec ;
77597759 struct bio * bio ;
@@ -7774,15 +7774,17 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio,
77747774 return - EIO ;
77757775 }
77767776
7777- if (failed_bio -> bi_vcnt > 1 )
7777+ if ((failed_bio -> bi_vcnt > 1 )
7778+ || (failed_bio -> bi_io_vec -> bv_len
7779+ > BTRFS_I (inode )-> root -> sectorsize ))
77787780 read_mode = READ_SYNC | REQ_FAILFAST_DEV ;
77797781 else
77807782 read_mode = READ_SYNC ;
77817783
77827784 isector = start - btrfs_io_bio (failed_bio )-> logical ;
77837785 isector >>= inode -> i_sb -> s_blocksize_bits ;
77847786 bio = btrfs_create_repair_bio (inode , failed_bio , failrec , page ,
7785- 0 , isector , repair_endio , repair_arg );
7787+ pgoff , isector , repair_endio , repair_arg );
77867788 if (!bio ) {
77877789 free_io_failure (inode , failrec );
77887790 return - EIO ;
@@ -7812,12 +7814,17 @@ struct btrfs_retry_complete {
78127814static void btrfs_retry_endio_nocsum (struct bio * bio )
78137815{
78147816 struct btrfs_retry_complete * done = bio -> bi_private ;
7817+ struct inode * inode ;
78157818 struct bio_vec * bvec ;
78167819 int i ;
78177820
78187821 if (bio -> bi_error )
78197822 goto end ;
78207823
7824+ ASSERT (bio -> bi_vcnt == 1 );
7825+ inode = bio -> bi_io_vec -> bv_page -> mapping -> host ;
7826+ ASSERT (bio -> bi_io_vec -> bv_len == BTRFS_I (inode )-> root -> sectorsize );
7827+
78217828 done -> uptodate = 1 ;
78227829 bio_for_each_segment_all (bvec , bio , i )
78237830 clean_io_failure (done -> inode , done -> start , bvec -> bv_page , 0 );
@@ -7829,36 +7836,51 @@ static void btrfs_retry_endio_nocsum(struct bio *bio)
78297836static int __btrfs_correct_data_nocsum (struct inode * inode ,
78307837 struct btrfs_io_bio * io_bio )
78317838{
7839+ struct btrfs_fs_info * fs_info ;
78327840 struct bio_vec * bvec ;
78337841 struct btrfs_retry_complete done ;
78347842 u64 start ;
7843+ unsigned int pgoff ;
7844+ u32 sectorsize ;
7845+ int nr_sectors ;
78357846 int i ;
78367847 int ret ;
78377848
7849+ fs_info = BTRFS_I (inode )-> root -> fs_info ;
7850+ sectorsize = BTRFS_I (inode )-> root -> sectorsize ;
7851+
78387852 start = io_bio -> logical ;
78397853 done .inode = inode ;
78407854
78417855 bio_for_each_segment_all (bvec , & io_bio -> bio , i ) {
7842- try_again :
7856+ nr_sectors = BTRFS_BYTES_TO_BLKS (fs_info , bvec -> bv_len );
7857+ pgoff = bvec -> bv_offset ;
7858+
7859+ next_block_or_try_again :
78437860 done .uptodate = 0 ;
78447861 done .start = start ;
78457862 init_completion (& done .done );
78467863
7847- ret = dio_read_error (inode , & io_bio -> bio , bvec -> bv_page , start ,
7848- start + bvec -> bv_len - 1 ,
7849- io_bio -> mirror_num ,
7850- btrfs_retry_endio_nocsum , & done );
7864+ ret = dio_read_error (inode , & io_bio -> bio , bvec -> bv_page ,
7865+ pgoff , start , start + sectorsize - 1 ,
7866+ io_bio -> mirror_num ,
7867+ btrfs_retry_endio_nocsum , & done );
78517868 if (ret )
78527869 return ret ;
78537870
78547871 wait_for_completion (& done .done );
78557872
78567873 if (!done .uptodate ) {
78577874 /* We might have another mirror, so try again */
7858- goto try_again ;
7875+ goto next_block_or_try_again ;
78597876 }
78607877
7861- start += bvec -> bv_len ;
7878+ start += sectorsize ;
7879+
7880+ if (nr_sectors -- ) {
7881+ pgoff += sectorsize ;
7882+ goto next_block_or_try_again ;
7883+ }
78627884 }
78637885
78647886 return 0 ;
@@ -7868,7 +7890,9 @@ static void btrfs_retry_endio(struct bio *bio)
78687890{
78697891 struct btrfs_retry_complete * done = bio -> bi_private ;
78707892 struct btrfs_io_bio * io_bio = btrfs_io_bio (bio );
7893+ struct inode * inode ;
78717894 struct bio_vec * bvec ;
7895+ u64 start ;
78727896 int uptodate ;
78737897 int ret ;
78747898 int i ;
@@ -7877,13 +7901,20 @@ static void btrfs_retry_endio(struct bio *bio)
78777901 goto end ;
78787902
78797903 uptodate = 1 ;
7904+
7905+ start = done -> start ;
7906+
7907+ ASSERT (bio -> bi_vcnt == 1 );
7908+ inode = bio -> bi_io_vec -> bv_page -> mapping -> host ;
7909+ ASSERT (bio -> bi_io_vec -> bv_len == BTRFS_I (inode )-> root -> sectorsize );
7910+
78807911 bio_for_each_segment_all (bvec , bio , i ) {
78817912 ret = __readpage_endio_check (done -> inode , io_bio , i ,
7882- bvec -> bv_page , 0 ,
7883- done -> start , bvec -> bv_len );
7913+ bvec -> bv_page , bvec -> bv_offset ,
7914+ done -> start , bvec -> bv_len );
78847915 if (!ret )
78857916 clean_io_failure (done -> inode , done -> start ,
7886- bvec -> bv_page , 0 );
7917+ bvec -> bv_page , bvec -> bv_offset );
78877918 else
78887919 uptodate = 0 ;
78897920 }
@@ -7897,31 +7928,45 @@ static void btrfs_retry_endio(struct bio *bio)
78977928static int __btrfs_subio_endio_read (struct inode * inode ,
78987929 struct btrfs_io_bio * io_bio , int err )
78997930{
7931+ struct btrfs_fs_info * fs_info ;
79007932 struct bio_vec * bvec ;
79017933 struct btrfs_retry_complete done ;
79027934 u64 start ;
79037935 u64 offset = 0 ;
7936+ u32 sectorsize ;
7937+ int nr_sectors ;
7938+ unsigned int pgoff ;
7939+ int csum_pos ;
79047940 int i ;
79057941 int ret ;
79067942
7943+ fs_info = BTRFS_I (inode )-> root -> fs_info ;
7944+ sectorsize = BTRFS_I (inode )-> root -> sectorsize ;
7945+
79077946 err = 0 ;
79087947 start = io_bio -> logical ;
79097948 done .inode = inode ;
79107949
79117950 bio_for_each_segment_all (bvec , & io_bio -> bio , i ) {
7912- ret = __readpage_endio_check (inode , io_bio , i , bvec -> bv_page ,
7913- 0 , start , bvec -> bv_len );
7951+ nr_sectors = BTRFS_BYTES_TO_BLKS (fs_info , bvec -> bv_len );
7952+
7953+ pgoff = bvec -> bv_offset ;
7954+ next_block :
7955+ csum_pos = BTRFS_BYTES_TO_BLKS (fs_info , offset );
7956+ ret = __readpage_endio_check (inode , io_bio , csum_pos ,
7957+ bvec -> bv_page , pgoff , start ,
7958+ sectorsize );
79147959 if (likely (!ret ))
79157960 goto next ;
79167961try_again :
79177962 done .uptodate = 0 ;
79187963 done .start = start ;
79197964 init_completion (& done .done );
79207965
7921- ret = dio_read_error (inode , & io_bio -> bio , bvec -> bv_page , start ,
7922- start + bvec -> bv_len - 1 ,
7923- io_bio -> mirror_num ,
7924- btrfs_retry_endio , & done );
7966+ ret = dio_read_error (inode , & io_bio -> bio , bvec -> bv_page ,
7967+ pgoff , start , start + sectorsize - 1 ,
7968+ io_bio -> mirror_num ,
7969+ btrfs_retry_endio , & done );
79257970 if (ret ) {
79267971 err = ret ;
79277972 goto next ;
@@ -7934,8 +7979,15 @@ static int __btrfs_subio_endio_read(struct inode *inode,
79347979 goto try_again ;
79357980 }
79367981next :
7937- offset += bvec -> bv_len ;
7938- start += bvec -> bv_len ;
7982+ offset += sectorsize ;
7983+ start += sectorsize ;
7984+
7985+ ASSERT (nr_sectors );
7986+
7987+ if (-- nr_sectors ) {
7988+ pgoff += sectorsize ;
7989+ goto next_block ;
7990+ }
79397991 }
79407992
79417993 return err ;
0 commit comments