[Devel] [PATCH RHEL7 COMMIT] iot_iter: Add iov_iter_alignment()
Konstantin Khorenko
khorenko at virtuozzo.com
Mon May 25 17:52:20 MSK 2020
The commit is pushed to "branch-rh7-3.10.0-1127.8.2.vz7.161.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.8.2.vz7.161.1
------>
commit abcd1caadfd8ceb3a0b2b1d8a51d30e384e1c1cb
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date: Mon May 25 17:52:19 2020 +0300
iot_iter: Add iov_iter_alignment()
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>
=====================
Patchset description:
[00/30] fs,direct_IO: Switch to iov_iter and allow bio_vec for ext4
This patchset transforms direct_IO callbacks, blockdev_direct_IO
and its underlining functions to iov_iter, and introduces complete
support of iov_iter for ext4.
Supported iov_iter subtypes for ext4 is iovec and bio_vec. The first
is for traditional user-submitted aio, while bio_vec is the type,
which is important for us, since we use it in ploop.
bio_vec operates with pages instead of user addresses (like iovec
does), so it requires specific callbacks in do_blockdev_direct_IO()
and in the functions it calls.
The patchset reworks do_blockdev_direct_IO() in the same manner
as in mainstrean. The most of rest patches are prepared manually,
since we have significant differences to ms (RHEL7 patches, our
direct IO patches for FUSE; all they have changed many functions).
At the end, kaio engine (resulting in direct_IO) became possible
to be enabled for ext4.
https://jira.sw.ru/browse/PSBM-99793
---
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 5f10c8486a6f7..f787d68600234 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 f08f59fafde5d..59e26d833ac49 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