aboutsummaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2018-05-26 20:10:07 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2018-05-29 23:19:29 -0400
commit67ba049f94ebe49ed557e590dd243b6db45c9aff (patch)
treedaae1d99acb30a148b9fe7546d7894cd397f1029 /fs/aio.c
parent95af8496ac48263badf5b8dde5e06ef35aaace2b (diff)
aio: fold do_io_submit() into callers
get rid of insane "copy array of 32bit pointers into an array of native ones" glue. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/aio.c')
-rw-r--r--fs/aio.c99
1 files changed, 45 insertions, 54 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 90b46560f0ce..da859574c953 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1818,8 +1818,20 @@ out_put_req:
1818 return ret; 1818 return ret;
1819} 1819}
1820 1820
1821static long do_io_submit(aio_context_t ctx_id, long nr, 1821/* sys_io_submit:
1822 struct iocb __user *__user *iocbpp, bool compat) 1822 * Queue the nr iocbs pointed to by iocbpp for processing. Returns
1823 * the number of iocbs queued. May return -EINVAL if the aio_context
1824 * specified by ctx_id is invalid, if nr is < 0, if the iocb at
1825 * *iocbpp[0] is not properly initialized, if the operation specified
1826 * is invalid for the file descriptor in the iocb. May fail with
1827 * -EFAULT if any of the data structures point to invalid data. May
1828 * fail with -EBADF if the file descriptor specified in the first
1829 * iocb is invalid. May fail with -EAGAIN if insufficient resources
1830 * are available to queue any iocbs. Will return 0 if nr is 0. Will
1831 * fail with -ENOSYS if not implemented.
1832 */
1833SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr,
1834 struct iocb __user * __user *, iocbpp)
1823{ 1835{
1824 struct kioctx *ctx; 1836 struct kioctx *ctx;
1825 long ret = 0; 1837 long ret = 0;
@@ -1832,9 +1844,6 @@ static long do_io_submit(aio_context_t ctx_id, long nr,
1832 if (unlikely(nr > LONG_MAX/sizeof(*iocbpp))) 1844 if (unlikely(nr > LONG_MAX/sizeof(*iocbpp)))
1833 nr = LONG_MAX/sizeof(*iocbpp); 1845 nr = LONG_MAX/sizeof(*iocbpp);
1834 1846
1835 if (unlikely(!access_ok(VERIFY_READ, iocbpp, (nr*sizeof(*iocbpp)))))
1836 return -EFAULT;
1837
1838 ctx = lookup_ioctx(ctx_id); 1847 ctx = lookup_ioctx(ctx_id);
1839 if (unlikely(!ctx)) { 1848 if (unlikely(!ctx)) {
1840 pr_debug("EINVAL: invalid context id\n"); 1849 pr_debug("EINVAL: invalid context id\n");
@@ -1842,20 +1851,15 @@ static long do_io_submit(aio_context_t ctx_id, long nr,
1842 } 1851 }
1843 1852
1844 blk_start_plug(&plug); 1853 blk_start_plug(&plug);
1845 1854 for (i = 0; i < nr; i++) {
1846 /*
1847 * AKPM: should this return a partial result if some of the IOs were
1848 * successfully submitted?
1849 */
1850 for (i=0; i<nr; i++) {
1851 struct iocb __user *user_iocb; 1855 struct iocb __user *user_iocb;
1852 1856
1853 if (unlikely(__get_user(user_iocb, iocbpp + i))) { 1857 if (unlikely(get_user(user_iocb, iocbpp + i))) {
1854 ret = -EFAULT; 1858 ret = -EFAULT;
1855 break; 1859 break;
1856 } 1860 }
1857 1861
1858 ret = io_submit_one(ctx, user_iocb, compat); 1862 ret = io_submit_one(ctx, user_iocb, false);
1859 if (ret) 1863 if (ret)
1860 break; 1864 break;
1861 } 1865 }
@@ -1865,47 +1869,16 @@ static long do_io_submit(aio_context_t ctx_id, long nr,
1865 return i ? i : ret; 1869 return i ? i : ret;
1866} 1870}
1867 1871
1868/* sys_io_submit:
1869 * Queue the nr iocbs pointed to by iocbpp for processing. Returns
1870 * the number of iocbs queued. May return -EINVAL if the aio_context
1871 * specified by ctx_id is invalid, if nr is < 0, if the iocb at
1872 * *iocbpp[0] is not properly initialized, if the operation specified
1873 * is invalid for the file descriptor in the iocb. May fail with
1874 * -EFAULT if any of the data structures point to invalid data. May
1875 * fail with -EBADF if the file descriptor specified in the first
1876 * iocb is invalid. May fail with -EAGAIN if insufficient resources
1877 * are available to queue any iocbs. Will return 0 if nr is 0. Will
1878 * fail with -ENOSYS if not implemented.
1879 */
1880SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr,
1881 struct iocb __user * __user *, iocbpp)
1882{
1883 return do_io_submit(ctx_id, nr, iocbpp, 0);
1884}
1885
1886#ifdef CONFIG_COMPAT 1872#ifdef CONFIG_COMPAT
1887static inline long
1888copy_iocb(long nr, u32 __user *ptr32, struct iocb __user * __user *ptr64)
1889{
1890 compat_uptr_t uptr;
1891 int i;
1892
1893 for (i = 0; i < nr; ++i) {
1894 if (get_user(uptr, ptr32 + i))
1895 return -EFAULT;
1896 if (put_user(compat_ptr(uptr), ptr64 + i))
1897 return -EFAULT;
1898 }
1899 return 0;
1900}
1901
1902#define MAX_AIO_SUBMITS (PAGE_SIZE/sizeof(struct iocb *)) 1873#define MAX_AIO_SUBMITS (PAGE_SIZE/sizeof(struct iocb *))
1903 1874
1904COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id, 1875COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id,
1905 int, nr, u32 __user *, iocb) 1876 int, nr, compat_uptr_t __user *, iocbpp)
1906{ 1877{
1907 struct iocb __user * __user *iocb64; 1878 struct kioctx *ctx;
1908 long ret; 1879 long ret = 0;
1880 int i = 0;
1881 struct blk_plug plug;
1909 1882
1910 if (unlikely(nr < 0)) 1883 if (unlikely(nr < 0))
1911 return -EINVAL; 1884 return -EINVAL;
@@ -1913,11 +1886,29 @@ COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id,
1913 if (nr > MAX_AIO_SUBMITS) 1886 if (nr > MAX_AIO_SUBMITS)
1914 nr = MAX_AIO_SUBMITS; 1887 nr = MAX_AIO_SUBMITS;
1915 1888
1916 iocb64 = compat_alloc_user_space(nr * sizeof(*iocb64)); 1889 ctx = lookup_ioctx(ctx_id);
1917 ret = copy_iocb(nr, iocb, iocb64); 1890 if (unlikely(!ctx)) {
1918 if (!ret) 1891 pr_debug("EINVAL: invalid context id\n");
1919 ret = do_io_submit(ctx_id, nr, iocb64, 1); 1892 return -EINVAL;
1920 return ret; 1893 }
1894
1895 blk_start_plug(&plug);
1896 for (i = 0; i < nr; i++) {
1897 compat_uptr_t user_iocb;
1898
1899 if (unlikely(get_user(user_iocb, iocbpp + i))) {
1900 ret = -EFAULT;
1901 break;
1902 }
1903
1904 ret = io_submit_one(ctx, compat_ptr(user_iocb), true);
1905 if (ret)
1906 break;
1907 }
1908 blk_finish_plug(&plug);
1909
1910 percpu_ref_put(&ctx->users);
1911 return i ? i : ret;
1921} 1912}
1922#endif 1913#endif
1923 1914