diff options
Diffstat (limited to 'fs/io_uring.c')
| -rw-r--r-- | fs/io_uring.c | 31 | 
1 files changed, 29 insertions, 2 deletions
| diff --git a/fs/io_uring.c b/fs/io_uring.c index 6aaa30580a2b..89aa8412b5f5 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;  	} @@ -2193,6 +2215,7 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg,  			fput(ctx->user_files[i]);  		kfree(ctx->user_files); +		ctx->user_files = NULL;  		ctx->nr_user_files = 0;  		return ret;  	} @@ -2222,6 +2245,10 @@ static int io_sq_offload_start(struct io_ring_ctx *ctx,  		goto err;  	if (ctx->flags & IORING_SETUP_SQPOLL) { +		ret = -EPERM; +		if (!capable(CAP_SYS_ADMIN)) +			goto err; +  		if (p->flags & IORING_SETUP_SQ_AFF) {  			int cpu; |