@@ -537,7 +537,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
537537
538538 if (put_dreq (dreq ))
539539 nfs_direct_complete (dreq );
540- return 0 ;
540+ return requested_bytes ;
541541}
542542
543543/**
@@ -566,7 +566,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter)
566566 struct inode * inode = mapping -> host ;
567567 struct nfs_direct_req * dreq ;
568568 struct nfs_lock_context * l_ctx ;
569- ssize_t result = - EINVAL ;
569+ ssize_t result = - EINVAL , requested ;
570570 size_t count = iov_iter_count (iter );
571571 nfs_add_stats (mapping -> host , NFSIOS_DIRECTREADBYTES , count );
572572
@@ -600,14 +600,19 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter)
600600 nfs_start_io_direct (inode );
601601
602602 NFS_I (inode )-> read_io += count ;
603- result = nfs_direct_read_schedule_iovec (dreq , iter , iocb -> ki_pos );
603+ requested = nfs_direct_read_schedule_iovec (dreq , iter , iocb -> ki_pos );
604604
605605 nfs_end_io_direct (inode );
606606
607- if (! result ) {
607+ if (requested > 0 ) {
608608 result = nfs_direct_wait (dreq );
609- if (result > 0 )
609+ if (result > 0 ) {
610+ requested -= result ;
610611 iocb -> ki_pos += result ;
612+ }
613+ iov_iter_revert (iter , requested );
614+ } else {
615+ result = requested ;
611616 }
612617
613618out_release :
@@ -954,7 +959,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
954959
955960 if (put_dreq (dreq ))
956961 nfs_direct_write_complete (dreq );
957- return 0 ;
962+ return requested_bytes ;
958963}
959964
960965/**
@@ -979,7 +984,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
979984 */
980985ssize_t nfs_file_direct_write (struct kiocb * iocb , struct iov_iter * iter )
981986{
982- ssize_t result = - EINVAL ;
987+ ssize_t result = - EINVAL , requested ;
983988 size_t count ;
984989 struct file * file = iocb -> ki_filp ;
985990 struct address_space * mapping = file -> f_mapping ;
@@ -1022,7 +1027,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
10221027
10231028 nfs_start_io_direct (inode );
10241029
1025- result = nfs_direct_write_schedule_iovec (dreq , iter , pos );
1030+ requested = nfs_direct_write_schedule_iovec (dreq , iter , pos );
10261031
10271032 if (mapping -> nrpages ) {
10281033 invalidate_inode_pages2_range (mapping ,
@@ -1031,13 +1036,17 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
10311036
10321037 nfs_end_io_direct (inode );
10331038
1034- if (! result ) {
1039+ if (requested > 0 ) {
10351040 result = nfs_direct_wait (dreq );
10361041 if (result > 0 ) {
1042+ requested -= result ;
10371043 iocb -> ki_pos = pos + result ;
10381044 /* XXX: should check the generic_write_sync retval */
10391045 generic_write_sync (iocb , result );
10401046 }
1047+ iov_iter_revert (iter , requested );
1048+ } else {
1049+ result = requested ;
10411050 }
10421051out_release :
10431052 nfs_direct_req_release (dreq );
0 commit comments