aboutsummaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
authorDeepa Dinamani <deepa.kernel@gmail.com>2017-08-05 00:12:32 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2017-09-19 17:55:59 -0400
commitfa2e62a54003419b06f1de7836dca51b368d0872 (patch)
tree6028b39e1a4ac42bcbbdbdfea9c7a4b2ae2b5904 /fs/aio.c
parent36819ad093e16a4b06c53f98d4a5afc55530bbcb (diff)
io_getevents: Use timespec64 to represent timeouts
struct timespec is not y2038 safe. Use y2038 safe struct timespec64 to represent timeouts. The system call interface itself will be changed as part of different series. Timeouts will not really need more than 32 bits. But, replacing these with timespec64 helps verification of a y2038 safe kernel by getting rid of timespec internally. Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com> Cc: linux-aio@kvack.org Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/aio.c')
-rw-r--r--fs/aio.c55
1 files changed, 30 insertions, 25 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 5a2487217072..91624905024f 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1297,20 +1297,10 @@ static bool aio_read_events(struct kioctx *ctx, long min_nr, long nr,
1297 1297
1298static long read_events(struct kioctx *ctx, long min_nr, long nr, 1298static long read_events(struct kioctx *ctx, long min_nr, long nr,
1299 struct io_event __user *event, 1299 struct io_event __user *event,
1300 struct timespec __user *timeout) 1300 ktime_t until)
1301{ 1301{
1302 ktime_t until = KTIME_MAX;
1303 long ret = 0; 1302 long ret = 0;
1304 1303
1305 if (timeout) {
1306 struct timespec ts;
1307
1308 if (unlikely(copy_from_user(&ts, timeout, sizeof(ts))))
1309 return -EFAULT;
1310
1311 until = timespec_to_ktime(ts);
1312 }
1313
1314 /* 1304 /*
1315 * Note that aio_read_events() is being called as the conditional - i.e. 1305 * Note that aio_read_events() is being called as the conditional - i.e.
1316 * we're calling it after prepare_to_wait() has set task state to 1306 * we're calling it after prepare_to_wait() has set task state to
@@ -1826,6 +1816,25 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
1826 return ret; 1816 return ret;
1827} 1817}
1828 1818
1819static long do_io_getevents(aio_context_t ctx_id,
1820 long min_nr,
1821 long nr,
1822 struct io_event __user *events,
1823 struct timespec64 *ts)
1824{
1825 ktime_t until = ts ? timespec64_to_ktime(*ts) : KTIME_MAX;
1826 struct kioctx *ioctx = lookup_ioctx(ctx_id);
1827 long ret = -EINVAL;
1828
1829 if (likely(ioctx)) {
1830 if (likely(min_nr <= nr && min_nr >= 0))
1831 ret = read_events(ioctx, min_nr, nr, events, until);
1832 percpu_ref_put(&ioctx->users);
1833 }
1834
1835 return ret;
1836}
1837
1829/* io_getevents: 1838/* io_getevents:
1830 * Attempts to read at least min_nr events and up to nr events from 1839 * Attempts to read at least min_nr events and up to nr events from
1831 * the completion queue for the aio_context specified by ctx_id. If 1840 * the completion queue for the aio_context specified by ctx_id. If
@@ -1844,15 +1853,14 @@ SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
1844 struct io_event __user *, events, 1853 struct io_event __user *, events,
1845 struct timespec __user *, timeout) 1854 struct timespec __user *, timeout)
1846{ 1855{
1847 struct kioctx *ioctx = lookup_ioctx(ctx_id); 1856 struct timespec64 ts;
1848 long ret = -EINVAL;
1849 1857
1850 if (likely(ioctx)) { 1858 if (timeout) {
1851 if (likely(min_nr <= nr && min_nr >= 0)) 1859 if (unlikely(get_timespec64(&ts, timeout)))
1852 ret = read_events(ioctx, min_nr, nr, events, timeout); 1860 return -EFAULT;
1853 percpu_ref_put(&ioctx->users);
1854 } 1861 }
1855 return ret; 1862
1863 return do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
1856} 1864}
1857 1865
1858#ifdef CONFIG_COMPAT 1866#ifdef CONFIG_COMPAT
@@ -1862,17 +1870,14 @@ COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id,
1862 struct io_event __user *, events, 1870 struct io_event __user *, events,
1863 struct compat_timespec __user *, timeout) 1871 struct compat_timespec __user *, timeout)
1864{ 1872{
1865 struct timespec t; 1873 struct timespec64 t;
1866 struct timespec __user *ut = NULL;
1867 1874
1868 if (timeout) { 1875 if (timeout) {
1869 if (compat_get_timespec(&t, timeout)) 1876 if (compat_get_timespec64(&t, timeout))
1870 return -EFAULT; 1877 return -EFAULT;
1871 1878
1872 ut = compat_alloc_user_space(sizeof(*ut));
1873 if (copy_to_user(ut, &t, sizeof(t)))
1874 return -EFAULT;
1875 } 1879 }
1876 return sys_io_getevents(ctx_id, min_nr, nr, events, ut); 1880
1881 return do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
1877} 1882}
1878#endif 1883#endif