[RHEL7,COMMIT] new primitive: iov_iter_alignment()

Submitted by Konstantin Khorenko on May 25, 2020, 2:52 p.m.

Details

Message ID 202005251452.04PEqLrh004240@finist-ce7.sw.ru
State New
Series "fs, direct_IO: Switch to iov_iter and allow bio_vec for ext4"
Headers show

Commit Message

Konstantin Khorenko May 25, 2020, 2:52 p.m.
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 91adc5be5de3f706d481412812668336424536bc
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Mon May 25 17:52:21 2020 +0300

    new primitive: iov_iter_alignment()
    
    ms commit 886a39115005
    
    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>
    Signed-off-by: Kirill Tkhai <ktkhai@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
---
 fs/direct-io.c | 27 +++++----------------------
 1 file changed, 5 insertions(+), 22 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/direct-io.c b/fs/direct-io.c
index 412e688e15c1e..1183db2f59039 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -1197,19 +1197,18 @@  do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
 	dio_submit_t submit_io,	int flags)
 {
 	int seg;
-	size_t size;
-	unsigned long addr;
 	unsigned i_blkbits = ACCESS_ONCE(inode->i_blkbits);
 	unsigned blkbits = i_blkbits;
 	unsigned blocksize_mask = (1 << blkbits) - 1;
 	ssize_t retval = -EINVAL;
-	loff_t end = offset;
+	loff_t end = offset + iov_iter_count(iter);
 	struct dio *dio;
 	struct dio_submit sdio = { 0, };
 	unsigned long user_addr;
 	size_t bytes;
 	struct buffer_head map_bh = { 0, };
 	struct blk_plug plug;
+	unsigned long align = offset | iov_iter_alignment(iter);
 
 	const struct iovec *iov = iov_iter_iovec(iter);
 	unsigned long nr_segs = iter->nr_segs;
@@ -1222,32 +1221,16 @@  do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
 	 * the early prefetch in the caller enough time.
 	 */
 
-	if (offset & blocksize_mask) {
+	if (align & blocksize_mask) {
 		if (bdev)
 			blkbits = blksize_bits(bdev_logical_block_size(bdev));
 		blocksize_mask = (1 << blkbits) - 1;
-		if (offset & blocksize_mask)
+		if (align & blocksize_mask)
 			goto out;
 	}
 
-	/* Check the memory alignment.  Blocks cannot straddle pages */
-	for (seg = 0; seg < nr_segs; seg++) {
-		addr = (unsigned long)iov[seg].iov_base;
-		size = iov[seg].iov_len;
-		end += size;
-		if (unlikely((addr & blocksize_mask) ||
-			     (size & blocksize_mask))) {
-			if (bdev)
-				blkbits = blksize_bits(
-					 bdev_logical_block_size(bdev));
-			blocksize_mask = (1 << blkbits) - 1;
-			if ((addr & blocksize_mask) || (size & blocksize_mask))
-				goto out;
-		}
-	}
-
 	/* watch out for a 0 len io from a tricksy fs */
-	if (rw == READ && end == offset)
+	if (rw == READ && !iov_iter_count(iter))
 		return 0;
 
 	dio = kmem_cache_alloc(dio_cache, GFP_KERNEL);