[Devel] [PATCH rh7 14/30] iot_iter: Add iov_iter_alignment()

Kirill Tkhai ktkhai at virtuozzo.com
Wed May 20 19:04:35 MSK 2020


Part of ms commit 62a8067a7f35 "bio_vec-backed iov_iter"

"const" modifiers are discarded because of FUSE.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 include/linux/fs.h |    2 ++
 mm/iov-iter.c      |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 59 insertions(+)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index bf42e056bcad..63481fb49967 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3651,6 +3651,8 @@ static inline iop_dentry_open_t get_dentry_open_iop(struct inode *inode)
 	return wrapper ? wrapper->dentry_open : NULL;
 }
 
+extern unsigned long iov_iter_alignment(struct iov_iter *i);
+
 extern bool path_noexec(const struct path *path);
 
 #endif /* _LINUX_FS_H */
diff --git a/mm/iov-iter.c b/mm/iov-iter.c
index f08f59fafde5..59e26d833ac4 100644
--- a/mm/iov-iter.c
+++ b/mm/iov-iter.c
@@ -854,3 +854,60 @@ struct iov_iter_ops ii_bad_ops = {
 	.ii_get_page = ii_bad_get_page,
 };
 EXPORT_SYMBOL(ii_bad_ops);
+
+static unsigned long alignment_bvec(struct iov_iter *i)
+{
+	struct bio_vec *bvec = iov_iter_bvec(i);
+	unsigned long res;
+	size_t size = i->count;
+	size_t n;
+
+	if (!size)
+		return 0;
+
+	res = bvec->bv_offset + i->iov_offset;
+	n = bvec->bv_len - i->iov_offset;
+	if (n >= size)
+		return res | size;
+	size -= n;
+	res |= n;
+	while (size > (++bvec)->bv_len) {
+		res |= bvec->bv_offset | bvec->bv_len;
+		size -= bvec->bv_len;
+	}
+	res |= bvec->bv_offset | size;
+	return res;
+}
+
+static unsigned long alignment_iovec(const struct iov_iter *i)
+{
+	const struct iovec *iov = iov_iter_iovec(i);
+	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;
+}
+
+unsigned long iov_iter_alignment(struct iov_iter *i)
+{
+	if (iov_iter_has_bvec(i))
+		return alignment_bvec(i);
+	else
+		return alignment_iovec(i);
+}
+EXPORT_SYMBOL(iov_iter_alignment);




More information about the Devel mailing list