|
@@ -2035,7 +2035,6 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
|
|
|
if (iocb->ki_flags & IOCB_DIRECT) {
|
|
|
struct address_space *mapping = file->f_mapping;
|
|
|
struct inode *inode = mapping->host;
|
|
|
- struct iov_iter data = *iter;
|
|
|
loff_t size;
|
|
|
|
|
|
size = i_size_read(inode);
|
|
@@ -2046,11 +2045,12 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
|
|
|
|
|
|
file_accessed(file);
|
|
|
|
|
|
- retval = mapping->a_ops->direct_IO(iocb, &data);
|
|
|
+ retval = mapping->a_ops->direct_IO(iocb, iter);
|
|
|
if (retval >= 0) {
|
|
|
iocb->ki_pos += retval;
|
|
|
- iov_iter_advance(iter, retval);
|
|
|
+ count -= retval;
|
|
|
}
|
|
|
+ iov_iter_revert(iter, iov_iter_count(iter) - count);
|
|
|
|
|
|
/*
|
|
|
* Btrfs can have a short DIO read if we encounter
|
|
@@ -2061,7 +2061,7 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
|
|
|
* the rest of the read. Buffered reads will not work for
|
|
|
* DAX files, so don't bother trying.
|
|
|
*/
|
|
|
- if (retval < 0 || !iov_iter_count(iter) || iocb->ki_pos >= size ||
|
|
|
+ if (retval < 0 || !count || iocb->ki_pos >= size ||
|
|
|
IS_DAX(inode))
|
|
|
goto out;
|
|
|
}
|
|
@@ -2706,7 +2706,6 @@ generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from)
|
|
|
ssize_t written;
|
|
|
size_t write_len;
|
|
|
pgoff_t end;
|
|
|
- struct iov_iter data;
|
|
|
|
|
|
write_len = iov_iter_count(from);
|
|
|
end = (pos + write_len - 1) >> PAGE_SHIFT;
|
|
@@ -2735,8 +2734,7 @@ generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- data = *from;
|
|
|
- written = mapping->a_ops->direct_IO(iocb, &data);
|
|
|
+ written = mapping->a_ops->direct_IO(iocb, from);
|
|
|
|
|
|
/*
|
|
|
* Finally, try again to invalidate clean pages which might have been
|
|
@@ -2753,13 +2751,14 @@ generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from)
|
|
|
|
|
|
if (written > 0) {
|
|
|
pos += written;
|
|
|
- iov_iter_advance(from, written);
|
|
|
+ write_len -= written;
|
|
|
if (pos > i_size_read(inode) && !S_ISBLK(inode->i_mode)) {
|
|
|
i_size_write(inode, pos);
|
|
|
mark_inode_dirty(inode);
|
|
|
}
|
|
|
iocb->ki_pos = pos;
|
|
|
}
|
|
|
+ iov_iter_revert(from, write_len - iov_iter_count(from));
|
|
|
out:
|
|
|
return written;
|
|
|
}
|