mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 21:24:08 +08:00
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: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
8409a0d261
commit
9221d2e37b
@ -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;
|
||||
|
||||
if (unlikely(iov_iter_is_pipe(i))) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user