Commit 9221d2e3 authored by Al Viro's avatar Al Viro

iov_iter_alignment(): don't bother with iterate_all_kinds()

It's easier to go over the array manually.  We need to watch out
for truncated iov_iter, though - iovec array might cover more
than i->count.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 8409a0d2
......@@ -1328,27 +1328,70 @@ void iov_iter_discard(struct iov_iter *i, unsigned int direction, size_t count)
}
EXPORT_SYMBOL(iov_iter_discard);
unsigned long iov_iter_alignment(const struct iov_iter *i)
static unsigned long iov_iter_alignment_iovec(const struct iov_iter *i)
{
unsigned long res = 0;
size_t size = i->count;
size_t skip = i->iov_offset;
unsigned k;
for (k = 0; k < i->nr_segs; k++, skip = 0) {
size_t len = i->iov[k].iov_len - skip;
if (len) {
res |= (unsigned long)i->iov[k].iov_base + skip;
if (len > size)
len = size;
res |= len;
size -= len;
if (!size)
break;
}
}
return res;
}
if (unlikely(iov_iter_is_pipe(i))) {
static unsigned long iov_iter_alignment_bvec(const struct iov_iter *i)
{
unsigned res = 0;
size_t size = i->count;
unsigned skip = i->iov_offset;
unsigned k;
for (k = 0; k < i->nr_segs; k++, skip = 0) {
size_t len = i->bvec[k].bv_len - skip;
res |= (unsigned long)i->bvec[k].bv_offset + skip;
if (len > size)
len = size;
res |= len;
size -= len;
if (!size)
break;
}
return res;
}
unsigned long iov_iter_alignment(const struct iov_iter *i)
{
/* iovec and kvec have identical layouts */
if (likely(iter_is_iovec(i) || iov_iter_is_kvec(i)))
return iov_iter_alignment_iovec(i);
if (iov_iter_is_bvec(i))
return iov_iter_alignment_bvec(i);
if (iov_iter_is_pipe(i)) {
unsigned int p_mask = i->pipe->ring_size - 1;
size_t size = i->count;
if (size && i->iov_offset && allocated(&i->pipe->bufs[i->head & p_mask]))
return size | i->iov_offset;
return size;
}
if (unlikely(iov_iter_is_xarray(i)))
if (iov_iter_is_xarray(i))
return (i->xarray_start + i->iov_offset) | i->count;
iterate_all_kinds(i, size, v,
(res |= (unsigned long)v.iov_base | v.iov_len, 0),
res |= v.bv_offset | v.bv_len,
res |= (unsigned long)v.iov_base | v.iov_len,
res |= v.bv_offset | v.bv_len
)
return res;
return 0;
}
EXPORT_SYMBOL(iov_iter_alignment);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment