[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