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 e2a6ae1a44e..9ffbea9b79e 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, |
