goto out;
/* If this is a write we don't need to check anymore */
- if (iov_iter_rw(iter) == WRITE)
+ if (iov_iter_rw(iter) != READ || !iter_is_iovec(iter))
return 0;
/*
* Check to make sure we don't have duplicate iov_base's in this
*ppos = kiocb.ki_pos;
file_accessed(in);
} else if (ret < 0) {
- if (WARN_ON(to.idx != idx || to.iov_offset)) {
- /*
- * a bogus ->read_iter() has copied something and still
- * returned an error instead of a short read.
- */
- to.idx = idx;
- to.iov_offset = 0;
- iov_iter_advance(&to, 0); /* to free what was emitted */
- }
+ to.idx = idx;
+ to.iov_offset = 0;
+ iov_iter_advance(&to, 0); /* to free what was emitted */
/*
* callers of ->splice_read() expect -EAGAIN on
* "can't put anything in there", rather than -EFAULT.
data = *to;
ret = __blockdev_direct_IO(iocb, inode, target->bt_bdev, &data,
xfs_get_blocks_direct, NULL, NULL, 0);
- if (ret > 0) {
+ if (ret >= 0) {
iocb->ki_pos += ret;
iov_iter_advance(to, ret);
}
const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags);
-static inline size_t iov_iter_count(struct iov_iter *i)
+static inline size_t iov_iter_count(const struct iov_iter *i)
{
return i->count;
}
-static inline bool iter_is_iovec(struct iov_iter *i)
+static inline bool iter_is_iovec(const struct iov_iter *i)
{
return !(i->type & (ITER_BVEC | ITER_KVEC | ITER_PIPE));
}
file_accessed(file);
retval = mapping->a_ops->direct_IO(iocb, &data);
- if (retval > 0) {
+ if (retval >= 0) {
iocb->ki_pos += retval;
iov_iter_advance(iter, retval);
}