diff options
author | Hugh Dickins <hugh@veritas.com> | 2008-07-24 00:27:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 13:47:16 -0400 |
commit | bcd78e49613c41b5bed96fa288e983876f286a59 (patch) | |
tree | 0ad2591ca2e0d46923d8ec489ef7378f1a3c0d8e /mm/shmem.c | |
parent | 11fa977ecde652ab324dd79c179deb52e82a8df1 (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>
Diffstat (limited to 'mm/shmem.c')
-rw-r--r-- | mm/shmem.c | 55 |
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 | ||
1693 | static ssize_t shmem_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) | 1693 | static 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 | ||
1715 | static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) | 1727 | static 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, |