[Devel] [PATCH rh7 v2 1/4] fs: Drop "pos" argument from {read, write}_iter() callbacks

Konstantin Khorenko khorenko at virtuozzo.com
Fri Dec 25 19:15:05 MSK 2020


This syncs file_operations::read_iter()/write_iter() declarations with
mainstream versions.

We brought _iter() interface before it appeared in mainstream and
callbacks declarations are not in sync.

Usually this does not hurt, but zfs is a bit upset that we have
address_space_operations::direct_IO() which uses iters, but
file_operations::read_iter()/write_iter() are not implemented
(they are implemented in vz kernel, but have different declaration,
thus not detected correctly).

So, let's make zfs happy.

To_merge: eddb0e72476d ("fs/aio: kernel direct aio")

https://bugs.openvz.org/browse/OVZ-7243

Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 fs/aio.c           |  4 ++--
 fs/ext4/file.c     | 29 +++++++++++++++--------------
 include/linux/fs.h |  8 ++++----
 mm/filemap.c       | 24 ++++++++++++------------
 4 files changed, 33 insertions(+), 32 deletions(-)

diff --git a/fs/aio.c b/fs/aio.c
index f1b27fc5defb..f0a9e1613529 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1343,7 +1343,7 @@ static ssize_t aio_read_iter(struct kiocb *iocb)
 	if (!file->f_op->read_iter)
 		return -EINVAL;
 
-	return file->f_op->read_iter(iocb, iocb->ki_iter, iocb->ki_pos);
+	return file->f_op->read_iter(iocb, iocb->ki_iter);
 }
 
 static ssize_t aio_write_iter(struct kiocb *iocb)
@@ -1365,7 +1365,7 @@ static ssize_t aio_write_iter(struct kiocb *iocb)
 		return -EINVAL;
 
 	file_start_write(file);
-	ret = file->f_op->write_iter(iocb, iocb->ki_iter, iocb->ki_pos);
+	ret = file->f_op->write_iter(iocb, iocb->ki_iter);
 	file_end_write(file);
 	return ret;
 }
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 67a385e9f716..2b3a73f90163 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -318,26 +318,26 @@ ext4_file_dax_write(
 #endif
 
 static ssize_t
-ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *iter, loff_t pos)
+ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
 {
 	struct inode *inode = file_inode(iocb->ki_filp);
 	ssize_t ret;
 	int overwrite = 0;
 
-	ret = ext4_write_checks(iocb, iter, &pos);
+	ret = ext4_write_checks(iocb, iter, &iocb->ki_pos);
 	if (ret <= 0)
 		return ret;
 
 #ifdef CONFIG_FS_DAX
 	if (IS_DAX(inode))
-		return ext4_file_dax_write(iocb, iter, pos);
+		return ext4_file_dax_write(iocb, iter, iocb->ki_pos);
 #endif
 
 	iocb->private = &overwrite; /* RHEL7 only - prevent DIO race */
 	if (unlikely(io_is_direct(iocb->ki_filp)))
-		ret = ext4_file_dio_write(iocb, iter, pos);
+		ret = ext4_file_dio_write(iocb, iter, iocb->ki_pos);
 	else
-		ret = generic_file_write_iter(iocb, iter, pos);
+		ret = generic_file_write_iter(iocb, iter);
 
 	return ret;
 }
@@ -350,7 +350,8 @@ ext4_file_write(struct kiocb *iocb, const struct iovec *iov,
 
 	iov_iter_init(&iter, iov, nr_segs, iov_length(iov, nr_segs), 0);
 
-	return ext4_file_write_iter(iocb, &iter, pos);
+	BUG_ON(iocb->ki_pos != pos);
+	return ext4_file_write_iter(iocb, &iter);
 }
 
 #ifdef CONFIG_FS_DAX
@@ -585,8 +586,7 @@ loff_t ext4_llseek(struct file *file, loff_t offset, int whence)
 static ssize_t
 ext4_file_dax_read_iter(
 	struct kiocb		*iocb,
-	struct iov_iter		*iter,
-	loff_t			pos)
+	struct iov_iter		*iter)
 {
 	size_t			size = iov_iter_count(iter);
 	ssize_t			ret = 0;
@@ -603,10 +603,10 @@ ext4_file_dax_read_iter(
 	if (!IS_DAX(inode)) {
 		inode_unlock(inode);
 		/* Fallback to buffered IO in case we cannot support DAX */
-		return generic_file_read_iter(iocb, iter, pos);
+		return generic_file_read_iter(iocb, iter);
 	}
 
-	ret = dax_iomap_rw(READ, iocb, iter, pos,
+	ret = dax_iomap_rw(READ, iocb, iter, iocb->ki_pos,
 					size, &ext4_iomap_ops);
 	inode_unlock(inode);
 
@@ -616,13 +616,13 @@ ext4_file_dax_read_iter(
 #endif
 
 ssize_t
-ext4_file_read_iter(struct kiocb *iocb, struct iov_iter *iter, loff_t pos)
+ext4_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 {
 #ifdef CONFIG_FS_DAX
 	if (IS_DAX(file_inode(iocb->ki_filp)))
-		return ext4_file_dax_read_iter(iocb, iter, pos);
+		return ext4_file_dax_read_iter(iocb, iter);
 #endif
-	return generic_file_read_iter(iocb, iter, pos);
+	return generic_file_read_iter(iocb, iter);
 }
 
 static ssize_t
@@ -636,7 +636,8 @@ ext4_file_read(
 	struct iov_iter iter;
 
 	iov_iter_init(&iter, iovp, nr_segs, size, 0);
-	return ext4_file_read_iter(iocb, &iter, pos);
+	BUG_ON(iocb->ki_pos != pos);
+	return ext4_file_read_iter(iocb, &iter);
 }
 
 const struct file_operations_extend  ext4_file_operations = {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8398ec202a42..2f498238202a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1969,9 +1969,9 @@ struct file_operations {
 	ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
 	ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
 	ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
-	ssize_t (*read_iter) (struct kiocb *, struct iov_iter *, loff_t);
+	ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
 	ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
-	ssize_t (*write_iter) (struct kiocb *, struct iov_iter *, loff_t);
+	ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
 	int (*readdir) (struct file *, void *, filldir_t);
 	unsigned int (*poll) (struct file *, struct poll_table_struct *);
 	long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
@@ -3239,12 +3239,12 @@ extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
 extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
 int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
 extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
-extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *, loff_t);
+extern ssize_t generic_file_read_iter(struct kiocb *, struct iov_iter *);
 extern ssize_t __generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long,
 		loff_t *);
 extern ssize_t __generic_file_write_iter(struct kiocb *, struct iov_iter *, loff_t *);
 extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
-extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *, loff_t);
+extern ssize_t generic_file_write_iter(struct kiocb *, struct iov_iter *);
 extern ssize_t generic_file_direct_write(struct kiocb *iocb, struct iov_iter *iter,
 		loff_t pos, loff_t *ppos, size_t count);
 extern ssize_t generic_file_direct_write_iter(struct kiocb *, struct iov_iter *,
diff --git a/mm/filemap.c b/mm/filemap.c
index 950d92b6059b..e0f7e5c73f80 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2006,16 +2006,14 @@ static int file_read_iter_actor(read_descriptor_t *desc, struct page *page,
  * generic_file_read_iter - generic filesystem read routine
  * @iocb:	kernel I/O control block
  * @iov_iter:	memory vector
- * @pos:	current file position
  */
 ssize_t
-generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter, loff_t pos)
+generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 {
 	struct file *filp = iocb->ki_filp;
 	read_descriptor_t desc;
 	ssize_t retval = 0;
 	size_t count = iov_iter_count(iter);
-	loff_t *ppos = &iocb->ki_pos;
 
 	if (io_is_direct(filp)) {
 		loff_t size;
@@ -2027,14 +2025,15 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter, loff_t pos)
 		if (!count)
 			goto out; /* skip atime */
 		size = i_size_read(inode);
-		retval = filemap_write_and_wait_range(mapping, pos,
-				pos + count - 1);
+		retval = filemap_write_and_wait_range(mapping, iocb->ki_pos,
+				iocb->ki_pos + count - 1);
 		if (!retval) {
 			struct iov_iter data = *iter;
-			retval = mapping->a_ops->direct_IO(READ, iocb, &data, pos);
+			retval = mapping->a_ops->direct_IO(READ, iocb, &data,
+							   iocb->ki_pos);
 		}
 		if (retval > 0) {
-			*ppos = pos + retval;
+			iocb->ki_pos += retval;
 			count -= retval;
 		}
 
@@ -2046,7 +2045,7 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter, loff_t pos)
 		 * and return.  Otherwise fallthrough to buffered io for
 		 * the rest of the read.
 		 */
-		if (retval < 0 || !count || *ppos >= size) {
+		if (retval < 0 || !count || iocb->ki_pos >= size) {
 			file_accessed(filp);
 			goto out;
 		}
@@ -2067,7 +2066,7 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter, loff_t pos)
 	desc.arg.data = iter;
 	desc.count = count;
 	desc.error = 0;
-	do_generic_file_read(filp, ppos, &desc, file_read_iter_actor);
+	do_generic_file_read(filp, &iocb->ki_pos, &desc, file_read_iter_actor);
 
 	retval += desc.written;
 	if (desc.error && !retval)
@@ -2096,7 +2095,8 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
 
 	iov_iter_init(&iter, iov, nr_segs, count, 0);
 
-	return generic_file_read_iter(iocb, &iter, pos);
+	BUG_ON(iocb->ki_pos != pos);
+	return generic_file_read_iter(iocb, &iter);
 }
 EXPORT_SYMBOL(generic_file_aio_read);
 
@@ -3097,12 +3097,12 @@ ssize_t __generic_file_write_iter(struct kiocb *iocb, struct iov_iter *iter,
 }
 EXPORT_SYMBOL(__generic_file_write_iter);
 
-ssize_t generic_file_write_iter(struct kiocb *iocb, struct iov_iter *iter,
-			        loff_t pos)
+ssize_t generic_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
 {
 	struct file *file = iocb->ki_filp;
 	struct inode *inode = file->f_mapping->host;
 	ssize_t ret;
+	loff_t pos = iocb->ki_pos;
 
 	mutex_lock(&inode->i_mutex);
 	ret = __generic_file_write_iter(iocb, iter, &iocb->ki_pos);
-- 
2.24.3



More information about the Devel mailing list