[rh7,12/30] fs: blockdev_direct_IO: switch to iov_iter

Submitted by Kirill Tkhai on May 20, 2020, 4:04 p.m.

Details

Message ID 158999065886.2234365.11676069162657039258.stgit@localhost.localdomain
State New
Series "fs, direct_IO: Switch to iov_iter and allow bio_vec for ext4"
Headers show

Commit Message

Kirill Tkhai May 20, 2020, 4:04 p.m.
Also __blockdev_direct_IO() and blockdev_direct_IO()

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 fs/block_dev.c      |    6 ++----
 fs/btrfs/inode.c    |    2 +-
 fs/direct-io.c      |   15 +++++++++------
 fs/ext2/inode.c     |    2 +-
 fs/ext3/inode.c     |    4 +---
 fs/ext4/indirect.c  |    9 ++++-----
 fs/ext4/inode.c     |    4 ++--
 fs/f2fs/data.c      |    4 +---
 fs/fat/inode.c      |    4 +---
 fs/gfs2/aops.c      |    6 ++----
 fs/hfs/inode.c      |    4 +---
 fs/hfsplus/inode.c  |    4 +---
 fs/jfs/inode.c      |    4 +---
 fs/nilfs2/inode.c   |    4 +---
 fs/ocfs2/aops.c     |    4 +---
 fs/reiserfs/inode.c |    4 +---
 fs/udf/inode.c      |    4 +---
 fs/xfs/xfs_file.c   |   13 ++++++++++---
 include/linux/fs.h  |   12 ++++++------
 19 files changed, 47 insertions(+), 62 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/block_dev.c b/fs/block_dev.c
index d9d5215b63b7..0271d05377ce 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -199,11 +199,9 @@  blkdev_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t offse
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = bdev_file_inode(file);
-	const struct iovec *iov = iov_iter_iovec(iter);
-	unsigned long nr_segs = iter->nr_segs;
 
-	return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset,
-				    nr_segs, blkdev_get_block, NULL, NULL,
+	return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iter, offset,
+				    blkdev_get_block, NULL, NULL,
 				    DIO_SKIP_DIO_COUNT);
 }
 
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index f2cdbdce472a..dcf741f02913 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8713,7 +8713,7 @@  static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
 
 	ret = __blockdev_direct_IO(rw, iocb, inode,
 			BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev,
-			iov, offset, nr_segs, btrfs_get_blocks_direct, NULL,
+			iter, offset, btrfs_get_blocks_direct, NULL,
 			btrfs_submit_direct, flags);
 	if (rw & WRITE) {
 		up_read(&BTRFS_I(inode)->dio_sem);
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 2dbbb775dbcb..412e688e15c1 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -1192,8 +1192,8 @@  static inline int drop_refcount(struct dio *dio)
  */
 static inline ssize_t
 do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
-	struct block_device *bdev, const struct iovec *iov, loff_t offset, 
-	unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
+	struct block_device *bdev, struct iov_iter *iter, loff_t offset,
+	get_block_t get_block, dio_iodone_t end_io,
 	dio_submit_t submit_io,	int flags)
 {
 	int seg;
@@ -1211,6 +1211,9 @@  do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
 	struct buffer_head map_bh = { 0, };
 	struct blk_plug plug;
 
+	const struct iovec *iov = iov_iter_iovec(iter);
+	unsigned long nr_segs = iter->nr_segs;
+
 	if (rw & WRITE)
 		rw = WRITE_ODIRECT;
 
@@ -1471,8 +1474,8 @@  do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
 
 ssize_t
 __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
-	struct block_device *bdev, const struct iovec *iov, loff_t offset,
-	unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
+	struct block_device *bdev, struct iov_iter *iter, loff_t offset,
+	get_block_t get_block, dio_iodone_t end_io,
 	dio_submit_t submit_io,	int flags)
 {
 	/*
@@ -1487,8 +1490,8 @@  __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
 	prefetch(bdev->bd_queue);
 	prefetch((char *)bdev->bd_queue + SMP_CACHE_BYTES);
 
-	return do_blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
-				     nr_segs, get_block, end_io,
+	return do_blockdev_direct_IO(rw, iocb, inode, bdev, iter, offset,
+				     get_block, end_io,
 				     submit_io, flags);
 }
 
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 868a438f73c6..de21dfcc09b7 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -866,7 +866,7 @@  ext2_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,
 		ret = dax_do_io(rw, iocb, inode, iov, offset, nr_segs,
 				ext2_get_block, NULL, DIO_LOCKING);
 	else
-		ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
+		ret = blockdev_direct_IO(rw, iocb, inode, iter, offset,
 					 ext2_get_block);
 	if (ret < 0 && (rw & WRITE))
 		ext2_write_failed(mapping, offset + iov_iter_count(iter));
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index bea45cc565b9..7318cce3d3a5 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1866,8 +1866,6 @@  static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb,
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file->f_mapping->host;
 	struct ext3_inode_info *ei = EXT3_I(inode);
-	const struct iovec *iov = iov_iter_iovec(iter);
-	unsigned long nr_segs = iter->nr_segs;
 	handle_t *handle;
 	ssize_t ret;
 	int orphan = 0;
@@ -1898,7 +1896,7 @@  static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb,
 	}
 
 retry:
-	ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
+	ret = blockdev_direct_IO(rw, iocb, inode, iter, offset,
 				 ext3_get_block);
 	/*
 	 * In case of error extending write may have instantiated a few
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index aa16a40b8258..4bb26fda35eb 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -716,14 +716,13 @@  ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
 			goto locked;
 		}
 		ret = __blockdev_direct_IO(rw, iocb, inode,
-					inode->i_sb->s_bdev, iov_iter_iovec(iter),
-					offset, iter->nr_segs,
-					ext4_get_block, NULL, NULL, 0);
+					inode->i_sb->s_bdev, iter,
+					offset, ext4_get_block, NULL, NULL, 0);
 		inode_dio_end(inode);
 	} else {
 locked:
-		ret = blockdev_direct_IO(rw, iocb, inode, iov_iter_iovec(iter),
-					offset, iter->nr_segs, ext4_get_block);
+		ret = blockdev_direct_IO(rw, iocb, inode, iter,
+					offset, ext4_get_block);
 
 		if (unlikely((rw & WRITE) && ret < 0)) {
 			loff_t isize = i_size_read(inode);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index d8798831afe5..c2bc8c7ccfca 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3430,8 +3430,8 @@  static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
 		dio_flags = DIO_LOCKING;
 	}
 	ret = __blockdev_direct_IO(rw, iocb, inode,
-				   inode->i_sb->s_bdev, iov_iter_iovec(iter), offset,
-				   iter->nr_segs, get_block_func,
+				   inode->i_sb->s_bdev, iter, offset,
+				   get_block_func,
 				   ext4_end_io_dio, NULL, dio_flags);
 
 	/*
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 69c4a35f8029..db5964b9f409 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -686,14 +686,12 @@  static ssize_t f2fs_direct_IO(int rw, struct kiocb *iocb,
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file->f_mapping->host;
-	const struct iovec *iov = iov_iter_iovec(iter);
-	unsigned long nr_segs = iter->nr_segs;
 
 	if (rw == WRITE)
 		return 0;
 
 	/* Needs synchronization with the cleaner */
-	return blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
+	return blockdev_direct_IO(rw, iocb, inode, iter, offset,
 						  get_data_block_ro);
 }
 
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index f7fe0253d5b3..0eeba52695a3 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -191,8 +191,6 @@  static ssize_t fat_direct_IO(int rw, struct kiocb *iocb,
 	struct file *file = iocb->ki_filp;
 	struct address_space *mapping = file->f_mapping;
 	struct inode *inode = mapping->host;
-	const struct iovec *iov = iov_iter_iovec(iter);
-	unsigned long nr_segs = iter->nr_segs;
 	ssize_t ret;
 
 	if (rw == WRITE) {
@@ -214,7 +212,7 @@  static ssize_t fat_direct_IO(int rw, struct kiocb *iocb,
 	 * FAT need to use the DIO_LOCKING for avoiding the race
 	 * condition of fat_get_block() and ->truncate().
 	 */
-	ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
+	ret = blockdev_direct_IO(rw, iocb, inode, iter, offset,
 				 fat_get_block);
 	if (ret < 0 && (rw & WRITE))
 		fat_write_failed(mapping, offset + iov_iter_count(iter));
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 3899484855c9..c70d1bde1f7b 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -1075,8 +1075,6 @@  static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
 	struct inode *inode = file->f_mapping->host;
 	struct address_space *mapping = inode->i_mapping;
 	struct gfs2_inode *ip = GFS2_I(inode);
-	const struct iovec *iov = iov_iter_iovec(iter);
-	unsigned long nr_segs = iter->nr_segs;
 	struct gfs2_holder gh;
 	int rv;
 
@@ -1126,8 +1124,8 @@  static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
 			truncate_inode_pages_range(mapping, lstart, end);
 	}
 
-	rv = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
-				  offset, nr_segs, gfs2_get_block_direct,
+	rv = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iter,
+				  offset, gfs2_get_block_direct,
 				  NULL, NULL, 0);
 out:
 	gfs2_glock_dq(&gh);
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index fb9df57ae800..5eaa6542b670 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -130,11 +130,9 @@  static ssize_t hfs_direct_IO(int rw, struct kiocb *iocb,
 	struct file *file = iocb->ki_filp;
 	struct address_space *mapping = file->f_mapping;
 	struct inode *inode = file_inode(file)->i_mapping->host;
-	const struct iovec *iov = iov_iter_iovec(iter);
-	unsigned long nr_segs = iter->nr_segs;
 	ssize_t ret;
 
-	ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
+	ret = blockdev_direct_IO(rw, iocb, inode, iter, offset,
 				 hfs_get_block);
 
 	/*
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 2546c965b432..7b04768c133c 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -127,11 +127,9 @@  static ssize_t hfsplus_direct_IO(int rw, struct kiocb *iocb,
 	struct file *file = iocb->ki_filp;
 	struct address_space *mapping = file->f_mapping;
 	struct inode *inode = file_inode(file)->i_mapping->host;
-	const struct iovec *iov = iov_iter_iovec(iter);
-	unsigned long nr_segs = iter->nr_segs;
 	ssize_t ret;
 
-	ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
+	ret = blockdev_direct_IO(rw, iocb, inode, iter, offset,
 				 hfsplus_get_block);
 
 	/*
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 4b58be70933e..e9a724247fab 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -336,11 +336,9 @@  static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb,
 	struct file *file = iocb->ki_filp;
 	struct address_space *mapping = file->f_mapping;
 	struct inode *inode = file->f_mapping->host;
-	const struct iovec *iov = iov_iter_iovec(iter);
-	unsigned long nr_segs = iter->nr_segs;
 	ssize_t ret;
 
-	ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
+	ret = blockdev_direct_IO(rw, iocb, inode, iter, offset,
 				 jfs_get_block);
 
 	/*
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 5a59a4dc1e67..c26dfc6c7a87 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -304,15 +304,13 @@  nilfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter,
 	struct file *file = iocb->ki_filp;
 	struct address_space *mapping = file->f_mapping;
 	struct inode *inode = file->f_mapping->host;
-	const struct iovec *iov = iov_iter_iovec(iter);
-	unsigned long nr_segs = iter->nr_segs;
 	ssize_t size;
 
 	if (rw == WRITE)
 		return 0;
 
 	/* Needs synchronization with the cleaner */
-	size = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
+	size = blockdev_direct_IO(rw, iocb, inode, iter, offset,
 				  nilfs_get_block);
 
 	/*
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 5f95455c1920..fc9140b65d78 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -627,8 +627,6 @@  static ssize_t ocfs2_direct_IO(int rw,
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file_inode(file)->i_mapping->host;
-	const struct iovec *iov = iov_iter_iovec(iter);
-	unsigned long nr_segs = iter->nr_segs;
 
 	/*
 	 * Fallback to buffered I/O if we see an inode without
@@ -642,7 +640,7 @@  static ssize_t ocfs2_direct_IO(int rw,
 		return 0;
 
 	return __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev,
-				    iov, offset, nr_segs,
+				    iter, offset,
 				    ocfs2_direct_IO_get_blocks,
 				    ocfs2_dio_end_io, NULL, 0);
 }
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index b56120dbf55a..4723e682e32d 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -3077,11 +3077,9 @@  static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb,
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file->f_mapping->host;
-	const struct iovec *iov = iov_iter_iovec(iter);
-	unsigned long nr_segs = iter->nr_segs;
 	ssize_t ret;
 
-	ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
+	ret = blockdev_direct_IO(rw, iocb, inode, iter, offset,
 				  reiserfs_get_blocks_direct_io);
 
 	/*
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 26d9d9f55f44..53756f7ac0e3 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -223,11 +223,9 @@  static ssize_t udf_direct_IO(int rw, struct kiocb *iocb,
 	struct file *file = iocb->ki_filp;
 	struct address_space *mapping = file->f_mapping;
 	struct inode *inode = mapping->host;
-	const struct iovec *iov = iov_iter_iovec(iter);
-	unsigned long nr_segs = iter->nr_segs;
 	ssize_t ret;
 
-	ret = blockdev_direct_IO(rw, iocb, inode, iov, offset, nr_segs,
+	ret = blockdev_direct_IO(rw, iocb, inode, iter, offset,
 				  udf_get_block);
 	if (unlikely(ret < 0 && (rw & WRITE)))
 		udf_write_failed(mapping, offset + iov_iter_count(iter));
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 5fb17574f0ce..67a632f2c00f 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -254,6 +254,7 @@  xfs_file_dio_aio_read(
 	struct xfs_buftarg	*target;
 	ssize_t			ret = 0;
 	loff_t			end;
+	struct iov_iter iter;
 
 	size = iov_length(iovp, nr_segs);
 	end = iocb->ki_pos + size - 1;
@@ -293,8 +294,11 @@  xfs_file_dio_aio_read(
 		WARN_ON_ONCE(ret);
 		ret = 0;
 	}
+
+	iov_iter_init(&iter, iovp, nr_segs, size, 0);
+
 	ret = __blockdev_direct_IO(READ, iocb, inode, target->bt_bdev,
-			iovp, pos, nr_segs, xfs_get_blocks_direct, NULL, NULL, 0);
+			&iter, pos, xfs_get_blocks_direct, NULL, NULL, 0);
 	if (ret > 0) {
 		iocb->ki_pos = pos + ret;
 	}
@@ -659,6 +663,7 @@  xfs_file_dio_aio_write(
 	loff_t			end;
 	struct xfs_buftarg	*target = XFS_IS_REALTIME_INODE(ip) ?
 					mp->m_rtdev_targp : mp->m_ddev_targp;
+	struct iov_iter iter;
 
 	/* DIO must be aligned to device logical sector size */
 	if ((pos | count) & target->bt_logical_sectormask)
@@ -721,8 +726,10 @@  xfs_file_dio_aio_write(
 	if (count != ocount)
 		nr_segs = iov_shorten((struct iovec *)iovp, nr_segs, count);
 
-	ret = __blockdev_direct_IO(WRITE, iocb, inode, target->bt_bdev, iovp,
-			pos, nr_segs, xfs_get_blocks_direct, xfs_end_io_direct_write,
+	iov_iter_init(&iter, iovp, nr_segs, count, 0);
+
+	ret = __blockdev_direct_IO(WRITE, iocb, inode, target->bt_bdev, &iter,
+			pos, xfs_get_blocks_direct, xfs_end_io_direct_write,
 			NULL, DIO_ASYNC_EXTEND);
 
 	/* see generic_file_direct_write() for why this is necessary */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d32e9e282c10..bf42e056bcad 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3283,16 +3283,16 @@  enum {
 void dio_end_io(struct bio *bio, int error);
 
 ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
-	struct block_device *bdev, const struct iovec *iov, loff_t offset,
-	unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
+	struct block_device *bdev, struct iov_iter *iter, loff_t offset,
+	get_block_t get_block, dio_iodone_t end_io,
 	dio_submit_t submit_io,	int flags);
 
 static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb,
-		struct inode *inode, const struct iovec *iov, loff_t offset,
-		unsigned long nr_segs, get_block_t get_block)
+		struct inode *inode, struct iov_iter *iter, loff_t offset,
+		get_block_t get_block)
 {
-	return __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
-				    offset, nr_segs, get_block, NULL, NULL,
+	return __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iter,
+				    offset, get_block, NULL, NULL,
 				    DIO_LOCKING | DIO_SKIP_HOLES);
 }
 #endif