| @@ -537,7 +537,7 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq, · 536 unmodified lines |
| 537 | 537 | |
| 538 | 538 | if (put_dreq(dreq)) |
| 539 | 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 | 566 | struct inode *inode = mapping->host; |
| 567 | 567 | struct nfs_direct_req *dreq; |
| 568 | 568 | struct nfs_lock_context *l_ctx; |
| 569 | | − ssize_t result = -EINVAL; |
| 569 | + ssize_t result = -EINVAL, requested; |
| 570 | 570 | size_t count = iov_iter_count(iter); |
| 571 | 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 | 600 | nfs_start_io_direct(inode); |
| 601 | 601 | |
| 602 | 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 | 605 | nfs_end_io_direct(inode); |
| 606 | 606 | |
| 607 | | − if (!result) { |
| 607 | + if (requested > 0) { |
| 608 | 608 | result = nfs_direct_wait(dreq); |
| 609 | | − if (result > 0) |
| 609 | + if (result > 0) { |
| 610 | + requested -= result; |
| 610 | 611 | iocb->ki_pos += result; |
| 612 | + } |
| 613 | + iov_iter_revert(iter, requested); |
| 614 | + } else { |
| 615 | + result = requested; |
| 611 | 616 | } |
| 612 | 617 | |
| 613 | 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 | 960 | if (put_dreq(dreq)) |
| 956 | 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 | 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 | 988 | size_t count; |
| 984 | 989 | struct file *file = iocb->ki_filp; |
| 985 | 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 | 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 | 1032 | if (mapping->nrpages) { |
| 1028 | 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 | 1037 | nfs_end_io_direct(inode); |
| 1033 | 1038 | |
| 1034 | | − if (!result) { |
| 1039 | + if (requested > 0) { |
| 1035 | 1040 | result = nfs_direct_wait(dreq); |
| 1036 | 1041 | if (result > 0) { |
| 1042 | + requested -= result; |
| 1037 | 1043 | iocb->ki_pos = pos + result; |
| 1038 | 1044 | /* XXX: should check the generic_write_sync retval */ |
| 1039 | 1045 | generic_write_sync(iocb, result); |
| 1040 | 1046 | } |
| 1047 | + iov_iter_revert(iter, requested); |
| 1048 | + } else { |
| 1049 | + result = requested; |
| 1041 | 1050 | } |
| 1042 | 1051 | out_release: |
| 1043 | 1052 | nfs_direct_req_release(dreq); |