summaryrefslogtreecommitdiffstats
path: root/fs/aio.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-10-11 13:45:22 +0200
committerTakashi Iwai <tiwai@suse.de>2010-10-11 13:45:22 +0200
commit4e83998f5af010a928495988c586ea2926624db9 (patch)
treee72d346172a30bbee165d7f585784724906da416 /fs/aio.c
parentdd1d3a49db4ae5c6afffadaff526b96c7993c7dd (diff)
parentd4cfa4d12f46e2520f4c1d1a92e891ce068b7464 (diff)
downloadlinux-stable-4e83998f5af010a928495988c586ea2926624db9.tar.gz
linux-stable-4e83998f5af010a928495988c586ea2926624db9.tar.bz2
linux-stable-4e83998f5af010a928495988c586ea2926624db9.zip
Merge branch 'fix/misc' into topic/misc
Diffstat (limited to 'fs/aio.c')
-rw-r--r--fs/aio.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/fs/aio.c b/fs/aio.c
index 3006b5bc33d6..250b0a73c8a8 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -712,8 +712,16 @@ static ssize_t aio_run_iocb(struct kiocb *iocb)
*/
ret = retry(iocb);
- if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED)
+ if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) {
+ /*
+ * There's no easy way to restart the syscall since other AIO's
+ * may be already running. Just fail this IO with EINTR.
+ */
+ if (unlikely(ret == -ERESTARTSYS || ret == -ERESTARTNOINTR ||
+ ret == -ERESTARTNOHAND || ret == -ERESTART_RESTARTBLOCK))
+ ret = -EINTR;
aio_complete(iocb, ret, 0);
+ }
out:
spin_lock_irq(&ctx->ctx_lock);
@@ -1659,6 +1667,9 @@ long do_io_submit(aio_context_t ctx_id, long nr,
if (unlikely(nr < 0))
return -EINVAL;
+ if (unlikely(nr > LONG_MAX/sizeof(*iocbpp)))
+ nr = LONG_MAX/sizeof(*iocbpp);
+
if (unlikely(!access_ok(VERIFY_READ, iocbpp, (nr*sizeof(*iocbpp)))))
return -EFAULT;