[PATCH 1/2] mm: Add functions for aio read and write using xip

Vishal Verma vishal.l.verma at linux.intel.com
Fri Aug 23 19:21:17 EDT 2013


xip filesystems may want to avoid using generic_file_aio_{read, write}
because they use the pagecache for non-direct IO.
Provide xip_file_aio_{read, write} which uses the filesystem's
direct_IO and read/write entry points.

Signed-off-by: Vishal Verma <vishal.l.verma at linux.intel.com>
Signed-off-by: Ross Zwisler <ross.zwisler at linux.intel.com>
Reviewed-by: Matthew Wilcox <matthew.r.wilcox at intel.com>
---
 include/linux/fs.h |    4 ++++
 mm/filemap_xip.c   |   44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 2c28271..81dc290 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2416,6 +2416,10 @@ extern int xip_file_mmap(struct file * file, struct vm_area_struct * vma);
 extern ssize_t xip_file_write(struct file *filp, const char __user *buf,
 			      size_t len, loff_t *ppos);
 extern int xip_truncate_page(struct address_space *mapping, loff_t from);
+extern ssize_t xip_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
+				unsigned long nr_segs, loff_t pos);
+extern ssize_t xip_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
+				unsigned long nr_segs, loff_t pos);
 #else
 static inline int xip_truncate_page(struct address_space *mapping, loff_t from)
 {
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index a912da6..e15949f 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -484,3 +484,47 @@ xip_truncate_page(struct address_space *mapping, loff_t from)
 	return 0;
 }
 EXPORT_SYMBOL_GPL(xip_truncate_page);
+
+static ssize_t do_xip_file_aio(int rw, struct kiocb *iocb,
+		const struct iovec *iov, unsigned long nr_segs, loff_t pos)
+{
+	struct file *filp = iocb->ki_filp;
+	struct address_space *mapping = filp->f_mapping;
+	loff_t offset = pos;
+	int ret = 0;
+	unsigned long seg;
+
+	if (filp->f_flags & O_DIRECT)
+		ret = mapping->a_ops->direct_IO(rw, iocb, iov,
+					pos, nr_segs);
+	else {
+		/* FIXME: Add checking for grow/out of bounds IO */
+		for (seg = 0; seg < nr_segs; seg++) {
+			const struct iovec *iv = &iov[seg];
+			if (rw == READ)
+				ret = filp->f_op->read(filp, iv->iov_base,
+						iv->iov_len, &offset);
+			else if (rw == WRITE)
+				ret = filp->f_op->write(filp, iv->iov_base,
+						iv->iov_len, &offset);
+			if (ret <= 0)
+				goto err;
+		}
+	}
+err:
+	return ret;
+}
+
+ssize_t xip_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
+				unsigned long nr_segs, loff_t pos)
+{
+	return do_xip_file_aio(READ, iocb, iov, nr_segs, pos);
+}
+EXPORT_SYMBOL_GPL(xip_file_aio_read);
+
+ssize_t xip_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
+				unsigned long nr_segs, loff_t pos)
+{
+	return do_xip_file_aio(WRITE, iocb, iov, nr_segs, pos);
+}
+EXPORT_SYMBOL_GPL(xip_file_aio_write);
-- 
1.7.0.4




More information about the Linux-pmfs mailing list