summaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-03-05 19:50:45 +0100
committerAl Viro <viro@zeniv.linux.org.uk>2014-05-06 23:32:47 +0200
commit886a39115005ced8b15ab067c9c2a8d546b40a5e (patch)
treecb72af0480369f31a449aa7a8451d407315c2bf3 /mm
parentgive ->direct_IO() a copy of iov_iter (diff)
downloadlinux-886a39115005ced8b15ab067c9c2a8d546b40a5e.tar.xz
linux-886a39115005ced8b15ab067c9c2a8d546b40a5e.zip
new primitive: iov_iter_alignment()
returns the value aligned as badly as the worst remaining segment in iov_iter is. Use instead of open-coded equivalents. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'mm')
-rw-r--r--mm/iov_iter.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/mm/iov_iter.c b/mm/iov_iter.c
index 22ec1ef068a8..2f762cc21080 100644
--- a/mm/iov_iter.c
+++ b/mm/iov_iter.c
@@ -195,3 +195,28 @@ size_t iov_iter_single_seg_count(const struct iov_iter *i)
return min(i->count, iov->iov_len - i->iov_offset);
}
EXPORT_SYMBOL(iov_iter_single_seg_count);
+
+unsigned long iov_iter_alignment(const struct iov_iter *i)
+{
+ const struct iovec *iov = i->iov;
+ unsigned long res;
+ size_t size = i->count;
+ size_t n;
+
+ if (!size)
+ return 0;
+
+ res = (unsigned long)iov->iov_base + i->iov_offset;
+ n = iov->iov_len - i->iov_offset;
+ if (n >= size)
+ return res | size;
+ size -= n;
+ res |= n;
+ while (size > (++iov)->iov_len) {
+ res |= (unsigned long)iov->iov_base | iov->iov_len;
+ size -= iov->iov_len;
+ }
+ res |= (unsigned long)iov->iov_base | size;
+ return res;
+}
+EXPORT_SYMBOL(iov_iter_alignment);