@@ -566,34 +566,37 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
566
566
{
567
567
struct block_device * bdev = iocb -> ki_filp -> private_data ;
568
568
loff_t size = bdev_nr_bytes (bdev );
569
- size_t count = iov_iter_count (to );
570
569
loff_t pos = iocb -> ki_pos ;
571
570
size_t shorted = 0 ;
572
571
ssize_t ret = 0 ;
572
+ size_t count ;
573
573
574
- if (unlikely (pos + count > size )) {
574
+ if (unlikely (pos + iov_iter_count ( to ) > size )) {
575
575
if (pos >= size )
576
576
return 0 ;
577
577
size -= pos ;
578
- if (count > size ) {
579
- shorted = count - size ;
580
- iov_iter_truncate (to , size );
581
- }
578
+ shorted = iov_iter_count (to ) - size ;
579
+ iov_iter_truncate (to , size );
582
580
}
583
581
582
+ count = iov_iter_count (to );
583
+ if (!count )
584
+ goto reexpand ; /* skip atime */
585
+
584
586
if (iocb -> ki_flags & IOCB_DIRECT ) {
585
587
struct address_space * mapping = iocb -> ki_filp -> f_mapping ;
586
588
587
589
if (iocb -> ki_flags & IOCB_NOWAIT ) {
588
- if (filemap_range_needs_writeback (mapping , iocb -> ki_pos ,
589
- iocb -> ki_pos + count - 1 ))
590
- return - EAGAIN ;
590
+ if (filemap_range_needs_writeback (mapping , pos ,
591
+ pos + count - 1 )) {
592
+ ret = - EAGAIN ;
593
+ goto reexpand ;
594
+ }
591
595
} else {
592
- ret = filemap_write_and_wait_range (mapping ,
593
- iocb -> ki_pos ,
594
- iocb -> ki_pos + count - 1 );
596
+ ret = filemap_write_and_wait_range (mapping , pos ,
597
+ pos + count - 1 );
595
598
if (ret < 0 )
596
- return ret ;
599
+ goto reexpand ;
597
600
}
598
601
599
602
file_accessed (iocb -> ki_filp );
@@ -603,12 +606,14 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
603
606
iocb -> ki_pos += ret ;
604
607
count -= ret ;
605
608
}
609
+ iov_iter_revert (to , count - iov_iter_count (to ));
606
610
if (ret < 0 || !count )
607
- return ret ;
611
+ goto reexpand ;
608
612
}
609
613
610
614
ret = filemap_read (iocb , to , ret );
611
615
616
+ reexpand :
612
617
if (unlikely (shorted ))
613
618
iov_iter_reexpand (to , iov_iter_count (to ) + shorted );
614
619
return ret ;
0 commit comments