Skip to content

Commit 3d14ec1

Browse files
committed
iov_iter: Four fixes for ITER_XARRAY
Fix four things[1] in the patch that adds ITER_XARRAY[2]: (1) Remove the address_space struct predeclaration. This is a holdover from when it was ITER_MAPPING. (2) Fix _copy_mc_to_iter() so that the xarray segment updates count and iov_offset in the iterator before returning. (3) Fix iov_iter_alignment() to not loop in the xarray case. Because the middle pages are all whole pages, only the end pages need be considered - and this can be reduced to just looking at the start position in the xarray and the iteration size. (4) Fix iov_iter_advance() to limit the size of the advance to no more than the remaining iteration size. Reported-by: Al Viro <[email protected]> Signed-off-by: David Howells <[email protected]> Reviewed-by: Al Viro <[email protected]> Tested-by: Jeff Layton <[email protected]> Tested-by: Dave Wysochanski <[email protected]> Link: https://lore.kernel.org/r/[email protected] [1] Link: https://lore.kernel.org/r/161918448151.3145707.11541538916600921083.stgit@warthog.procyon.org.uk [2]
1 parent 26aaeff commit 3d14ec1

File tree

2 files changed

+5
-1
lines changed

2 files changed

+5
-1
lines changed

include/linux/uio.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include <uapi/linux/uio.h>
1111

1212
struct page;
13-
struct address_space;
1413
struct pipe_inode_info;
1514

1615
struct kvec {

lib/iov_iter.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,8 @@ size_t _copy_mc_to_iter(const void *addr, size_t bytes, struct iov_iter *i)
791791
curr_addr = (unsigned long) from;
792792
bytes = curr_addr - s_addr - rem;
793793
rcu_read_unlock();
794+
i->iov_offset += bytes;
795+
i->count -= bytes;
794796
return bytes;
795797
}
796798
})
@@ -1147,6 +1149,7 @@ void iov_iter_advance(struct iov_iter *i, size_t size)
11471149
return;
11481150
}
11491151
if (unlikely(iov_iter_is_xarray(i))) {
1152+
size = min(size, i->count);
11501153
i->iov_offset += size;
11511154
i->count -= size;
11521155
return;
@@ -1346,6 +1349,8 @@ unsigned long iov_iter_alignment(const struct iov_iter *i)
13461349
return size | i->iov_offset;
13471350
return size;
13481351
}
1352+
if (unlikely(iov_iter_is_xarray(i)))
1353+
return (i->xarray_start + i->iov_offset) | i->count;
13491354
iterate_all_kinds(i, size, v,
13501355
(res |= (unsigned long)v.iov_base | v.iov_len, 0),
13511356
res |= v.bv_offset | v.bv_len,

0 commit comments

Comments
 (0)