aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-29 14:43:07 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-29 14:43:07 -0700
commitffb8e45cf33e14d9a565491aec7abe039bebcfce (patch)
tree4181a995d8fb1de48ed6af9c4211ac6a27b54b0a /fs
parent7376e39ad96583545faefa2e7798bcb6a2a212a7 (diff)
parent7bca889ee9297c3e208dee7c41aed7a56a880400 (diff)
downloadlinux-stericsson-ffb8e45cf33e14d9a565491aec7abe039bebcfce.tar.gz
Merge tag 'for-linus-20190329' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe: "Small set of fixes that should go into this series. This contains: - compat signal mask fix for io_uring (Arnd) - EAGAIN corner case for direct vs buffered writes for io_uring (Roman) - NVMe pull request from Christoph with various little fixes - sbitmap ws_active fix, which caused a perf regression for shared tags (me) - sbitmap bit ordering fix (Ming) - libata on-stack DMA fix (Raymond)" * tag 'for-linus-20190329' of git://git.kernel.dk/linux-block: nvmet: fix error flow during ns enable nvmet: fix building bvec from sg list nvme-multipath: relax ANA state check nvme-tcp: fix an endianess miss-annotation libata: fix using DMA buffers on stack io_uring: offload write to async worker in case of -EAGAIN sbitmap: order READ/WRITE freed instance and setting clear bit blk-mq: fix sbitmap ws_active for shared tags io_uring: fix big-endian compat signal mask handling blk-mq: update comment for blk_mq_hctx_has_pending() blk-mq: use blk_mq_put_driver_tag() to put tag
Diffstat (limited to 'fs')
-rw-r--r--fs/io_uring.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 6aaa30580a2b..bbdbd56cf2ac 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -1022,6 +1022,8 @@ static int io_write(struct io_kiocb *req, const struct sqe_submit *s,
ret = rw_verify_area(WRITE, file, &kiocb->ki_pos, iov_count);
if (!ret) {
+ ssize_t ret2;
+
/*
* Open-code file_start_write here to grab freeze protection,
* which will be released by another thread in
@@ -1036,7 +1038,19 @@ static int io_write(struct io_kiocb *req, const struct sqe_submit *s,
SB_FREEZE_WRITE);
}
kiocb->ki_flags |= IOCB_WRITE;
- io_rw_done(kiocb, call_write_iter(file, kiocb, &iter));
+
+ ret2 = call_write_iter(file, kiocb, &iter);
+ if (!force_nonblock || ret2 != -EAGAIN) {
+ io_rw_done(kiocb, ret2);
+ } else {
+ /*
+ * If ->needs_lock is true, we're already in async
+ * context.
+ */
+ if (!s->needs_lock)
+ io_async_list_note(WRITE, req, iov_count);
+ ret = -EAGAIN;
+ }
}
out_free:
kfree(iovec);
@@ -1968,7 +1982,15 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
return 0;
if (sig) {
- ret = set_user_sigmask(sig, &ksigmask, &sigsaved, sigsz);
+#ifdef CONFIG_COMPAT
+ if (in_compat_syscall())
+ ret = set_compat_user_sigmask((const compat_sigset_t __user *)sig,
+ &ksigmask, &sigsaved, sigsz);
+ else
+#endif
+ ret = set_user_sigmask(sig, &ksigmask,
+ &sigsaved, sigsz);
+
if (ret)
return ret;
}