@@ -1677,6 +1677,7 @@ ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from)
16771677 struct inode * bd_inode = bdev_file_inode (file );
16781678 loff_t size = i_size_read (bd_inode );
16791679 struct blk_plug plug ;
1680+ size_t shorted = 0 ;
16801681 ssize_t ret ;
16811682
16821683 if (bdev_read_only (I_BDEV (bd_inode )))
@@ -1694,12 +1695,17 @@ ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from)
16941695 if ((iocb -> ki_flags & (IOCB_NOWAIT | IOCB_DIRECT )) == IOCB_NOWAIT )
16951696 return - EOPNOTSUPP ;
16961697
1697- iov_iter_truncate (from , size - iocb -> ki_pos );
1698+ size -= iocb -> ki_pos ;
1699+ if (iov_iter_count (from ) > size ) {
1700+ shorted = iov_iter_count (from ) - size ;
1701+ iov_iter_truncate (from , size );
1702+ }
16981703
16991704 blk_start_plug (& plug );
17001705 ret = __generic_file_write_iter (iocb , from );
17011706 if (ret > 0 )
17021707 ret = generic_write_sync (iocb , ret );
1708+ iov_iter_reexpand (from , iov_iter_count (from ) + shorted );
17031709 blk_finish_plug (& plug );
17041710 return ret ;
17051711}
@@ -1711,13 +1717,21 @@ ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
17111717 struct inode * bd_inode = bdev_file_inode (file );
17121718 loff_t size = i_size_read (bd_inode );
17131719 loff_t pos = iocb -> ki_pos ;
1720+ size_t shorted = 0 ;
1721+ ssize_t ret ;
17141722
17151723 if (pos >= size )
17161724 return 0 ;
17171725
17181726 size -= pos ;
1719- iov_iter_truncate (to , size );
1720- return generic_file_read_iter (iocb , to );
1727+ if (iov_iter_count (to ) > size ) {
1728+ shorted = iov_iter_count (to ) - size ;
1729+ iov_iter_truncate (to , size );
1730+ }
1731+
1732+ ret = generic_file_read_iter (iocb , to );
1733+ iov_iter_reexpand (to , iov_iter_count (to ) + shorted );
1734+ return ret ;
17211735}
17221736EXPORT_SYMBOL_GPL (blkdev_read_iter );
17231737
0 commit comments