diff options
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, |