@@ -1252,12 +1252,12 @@ unsigned long iov_iter_gap_alignment(const struct iov_iter *i)
}
iterate_all_kinds(i, size, v,
- (res |= (!res ? 0 : (unsigned long)v.iov_base) |
- (size != v.iov_len ? size : 0), 0),
- (res |= (!res ? 0 : (unsigned long)v.bv_offset) |
- (size != v.bv_len ? size : 0)),
- (res |= (!res ? 0 : (unsigned long)v.iov_base) |
- (size != v.iov_len ? size : 0))
+ (res |= (size == i->count ? 0 : (unsigned long)v.iov_base) |
+ (size == v.iov_len ? 0 : (unsigned long)v.iov_base + v.iov_len), 0),
+ res |= (size == i->count ? 0 : v.bv_offset) |
+ (size == v.bv_len ? 0 : v.bv_offset + v.bv_len),
+ res |= (size == i->count ? 0 : (unsigned long)v.iov_base) |
+ (size == v.iov_len ? 0 : (unsigned long)v.iov_base + v.iov_len)
);
return res;
}
The block layer uses the queue's virt_boundary to enforce alignment between vectors, but iov_iter_gap_alignment() returned the starting address or'ed with all but the last the length. Fix it to return alignment for each vector's starting address except the first, and each vector's ending address except the last. Signed-off-by: Keith Busch <kbusch@kernel.org> --- lib/iov_iter.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)