| @@ -537,7 +537,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq, · 536 unmodified lines |
| 537 | | 537 | |
| 538 | if (put_dreq(dreq)) | 538 | if (put_dreq(dreq)) |
| 539 | nfs_direct_complete(dreq); | 539 | nfs_direct_complete(dreq); |
| 540 | return 0; | 540 | return requested_bytes; |
| 541 | } | 541 | } |
| 542 | | 542 | |
| 543 | /** | 543 | /** |
| @@ -566,7 +566,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter) · 22 unmodified lines |
| 566 | struct inode *inode = mapping->host; | 566 | struct inode *inode = mapping->host; |
| 567 | struct nfs_direct_req *dreq; | 567 | struct nfs_direct_req *dreq; |
| 568 | struct nfs_lock_context *l_ctx; | 568 | struct nfs_lock_context *l_ctx; |
| 569 | ssize_t result = -EINVAL; | 569 | ssize_t result = -EINVAL, requested; |
| 570 | size_t count = iov_iter_count(iter); | 570 | size_t count = iov_iter_count(iter); |
| 571 | nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count); | 571 | nfs_add_stats(mapping->host, NFSIOS_DIRECTREADBYTES, count); |
| 572 | | 572 | |
| @@ -600,14 +600,19 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, struct iov_iter *iter) · 27 unmodified lines |
| 600 | nfs_start_io_direct(inode); | 600 | nfs_start_io_direct(inode); |
| 601 | | 601 | |
| 602 | NFS_I(inode)->read_io += count; | 602 | 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); |
| 604 | | 604 | |
| 605 | nfs_end_io_direct(inode); | 605 | nfs_end_io_direct(inode); |
| 606 | | 606 | |
| 607 | if (!result) { | 607 | if (requested > 0) { |
| 608 | result = nfs_direct_wait(dreq); | 608 | result = nfs_direct_wait(dreq); |
| 609 | if (result > 0) | 609 | if (result > 0) { |
| | 610 | requested -= result; |
| 610 | iocb->ki_pos += result; | 611 | iocb->ki_pos += result; |
| | 612 | } |
| | 613 | iov_iter_revert(iter, requested); |
| | 614 | } else { |
| | 615 | result = requested; |
| 611 | } | 616 | } |
| 612 | | 617 | |
| 613 | out_release: | 618 | out_release: |
| @@ -954,7 +959,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, · 340 unmodified lines |
| 954 | | 959 | |
| 955 | if (put_dreq(dreq)) | 960 | if (put_dreq(dreq)) |
| 956 | nfs_direct_write_complete(dreq); | 961 | nfs_direct_write_complete(dreq); |
| 957 | return 0; | 962 | return requested_bytes; |
| 958 | } | 963 | } |
| 959 | | 964 | |
| 960 | /** | 965 | /** |
| @@ -979,7 +984,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, · 18 unmodified lines |
| 979 | */ | 984 | */ |
| 980 | ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter) | 985 | ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter) |
| 981 | { | 986 | { |
| 982 | ssize_t result = -EINVAL; | 987 | ssize_t result = -EINVAL, requested; |
| 983 | size_t count; | 988 | size_t count; |
| 984 | struct file *file = iocb->ki_filp; | 989 | struct file *file = iocb->ki_filp; |
| 985 | struct address_space *mapping = file->f_mapping; | 990 | struct address_space *mapping = file->f_mapping; |
| @@ -1022,7 +1027,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter) · 36 unmodified lines |
| 1022 | | 1027 | |
| 1023 | nfs_start_io_direct(inode); | 1028 | nfs_start_io_direct(inode); |
| 1024 | | 1029 | |
| 1025 | result = nfs_direct_write_schedule_iovec(dreq, iter, pos); | 1030 | requested = nfs_direct_write_schedule_iovec(dreq, iter, pos); |
| 1026 | | 1031 | |
| 1027 | if (mapping->nrpages) { | 1032 | if (mapping->nrpages) { |
| 1028 | invalidate_inode_pages2_range(mapping, | 1033 | invalidate_inode_pages2_range(mapping, |
| @@ -1031,13 +1036,17 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter) · 2 unmodified lines |
| 1031 | | 1036 | |
| 1032 | nfs_end_io_direct(inode); | 1037 | nfs_end_io_direct(inode); |
| 1033 | | 1038 | |
| 1034 | if (!result) { | 1039 | if (requested > 0) { |
| 1035 | result = nfs_direct_wait(dreq); | 1040 | result = nfs_direct_wait(dreq); |
| 1036 | if (result > 0) { | 1041 | if (result > 0) { |
| | 1042 | requested -= result; |
| 1037 | iocb->ki_pos = pos + result; | 1043 | iocb->ki_pos = pos + result; |
| 1038 | /* XXX: should check the generic_write_sync retval */ | 1044 | /* XXX: should check the generic_write_sync retval */ |
| 1039 | generic_write_sync(iocb, result); | 1045 | generic_write_sync(iocb, result); |
| 1040 | } | 1046 | } |
| | 1047 | iov_iter_revert(iter, requested); |
| | 1048 | } else { |
| | 1049 | result = requested; |
| 1041 | } | 1050 | } |
| 1042 | out_release: | 1051 | out_release: |
| 1043 | nfs_direct_req_release(dreq); | 1052 | nfs_direct_req_release(dreq); |