aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugh Dickins <hugh@veritas.com>2008-07-24 00:27:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-24 13:47:16 -0400
commitbcd78e49613c41b5bed96fa288e983876f286a59 (patch)
tree0ad2591ca2e0d46923d8ec489ef7378f1a3c0d8e
parent11fa977ecde652ab324dd79c179deb52e82a8df1 (diff)
tmpfs: support aio
We have a request for tmpfs to support the AIO interface: easily done, no more than replacing the old shmem_file_read by shmem_file_aio_read, cribbed from generic_file_aio_read. (In 2.6.25 its write side was already changed to use generic_file_aio_write.) Incorporate cleanups from Andrew Morton and Harvey Harrison. Tests out fine with LTP's ltp-aiodio.sh, given hacks (not included) to support O_DIRECT. tmpfs cannot honestly support O_DIRECT: its cache-avoiding-IO nature is at odds with direct IO-avoiding-cache. Signed-off-by: Hugh Dickins <hugh@veritas.com> Tested-by: Lawrence Greenfield <leg@google.com> Cc: Christoph Rohland <hans-christoph.rohland@sap.com> Cc: Badari Pulavarty <pbadari@us.ibm.com> Cc: Zach Brown <zach.brown@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/shmem.c55
1 files changed, 34 insertions, 21 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index e2a6ae1a44e9..9ffbea9b79e1 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1690,26 +1690,38 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_
1690 file_accessed(filp); 1690 file_accessed(filp);
1691} 1691}
1692 1692
1693static ssize_t shmem_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) 1693static ssize_t shmem_file_aio_read(struct kiocb *iocb,
1694{ 1694 const struct iovec *iov, unsigned long nr_segs, loff_t pos)
1695 read_descriptor_t desc; 1695{
1696 1696 struct file *filp = iocb->ki_filp;
1697 if ((ssize_t) count < 0) 1697 ssize_t retval;
1698 return -EINVAL; 1698 unsigned long seg;
1699 if (!access_ok(VERIFY_WRITE, buf, count)) 1699 size_t count;
1700 return -EFAULT; 1700 loff_t *ppos = &iocb->ki_pos;
1701 if (!count) 1701
1702 return 0; 1702 retval = generic_segment_checks(iov, &nr_segs, &count, VERIFY_WRITE);
1703 1703 if (retval)
1704 desc.written = 0; 1704 return retval;
1705 desc.count = count; 1705
1706 desc.arg.buf = buf; 1706 for (seg = 0; seg < nr_segs; seg++) {
1707 desc.error = 0; 1707 read_descriptor_t desc;
1708 1708
1709 do_shmem_file_read(filp, ppos, &desc, file_read_actor); 1709 desc.written = 0;
1710 if (desc.written) 1710 desc.arg.buf = iov[seg].iov_base;
1711 return desc.written; 1711 desc.count = iov[seg].iov_len;
1712 return desc.error; 1712 if (desc.count == 0)
1713 continue;
1714 desc.error = 0;
1715 do_shmem_file_read(filp, ppos, &desc, file_read_actor);
1716 retval += desc.written;
1717 if (desc.error) {
1718 retval = retval ?: desc.error;
1719 break;
1720 }
1721 if (desc.count > 0)
1722 break;
1723 }
1724 return retval;
1713} 1725}
1714 1726
1715static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) 1727static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -2369,8 +2381,9 @@ static const struct file_operations shmem_file_operations = {
2369 .mmap = shmem_mmap, 2381 .mmap = shmem_mmap,
2370#ifdef CONFIG_TMPFS 2382#ifdef CONFIG_TMPFS
2371 .llseek = generic_file_llseek, 2383 .llseek = generic_file_llseek,
2372 .read = shmem_file_read, 2384 .read = do_sync_read,
2373 .write = do_sync_write, 2385 .write = do_sync_write,
2386 .aio_read = shmem_file_aio_read,
2374 .aio_write = generic_file_aio_write, 2387 .aio_write = generic_file_aio_write,
2375 .fsync = simple_sync_file, 2388 .fsync = simple_sync_file,
2376 .splice_read = generic_file_splice_read, 2389 .splice_read = generic_file_splice_read,