diff options
Diffstat (limited to 'io_uring/net.c')
| -rw-r--r-- | io_uring/net.c | 29 | 
1 files changed, 18 insertions, 11 deletions
diff --git a/io_uring/net.c b/io_uring/net.c index b7f190ca528e..89e839013837 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -47,6 +47,7 @@ struct io_connect {  	struct sockaddr __user		*addr;  	int				addr_len;  	bool				in_progress; +	bool				seen_econnaborted;  };  struct io_sr_msg { @@ -183,8 +184,8 @@ static int io_setup_async_msg(struct io_kiocb *req,  		async_msg->msg.msg_name = &async_msg->addr;  	/* if were using fast_iov, set it to the new one */  	if (iter_is_iovec(&kmsg->msg.msg_iter) && !kmsg->free_iov) { -		size_t fast_idx = kmsg->msg.msg_iter.iov - kmsg->fast_iov; -		async_msg->msg.msg_iter.iov = &async_msg->fast_iov[fast_idx]; +		size_t fast_idx = iter_iov(&kmsg->msg.msg_iter) - kmsg->fast_iov; +		async_msg->msg.msg_iter.__iov = &async_msg->fast_iov[fast_idx];  	}  	return -EAGAIN; @@ -1424,7 +1425,7 @@ int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)  	conn->addr = u64_to_user_ptr(READ_ONCE(sqe->addr));  	conn->addr_len =  READ_ONCE(sqe->addr2); -	conn->in_progress = false; +	conn->in_progress = conn->seen_econnaborted = false;  	return 0;  } @@ -1461,18 +1462,24 @@ int io_connect(struct io_kiocb *req, unsigned int issue_flags)  	ret = __sys_connect_file(req->file, &io->address,  					connect->addr_len, file_flags); -	if ((ret == -EAGAIN || ret == -EINPROGRESS) && force_nonblock) { +	if ((ret == -EAGAIN || ret == -EINPROGRESS || ret == -ECONNABORTED) +	    && force_nonblock) {  		if (ret == -EINPROGRESS) {  			connect->in_progress = true; -		} else { -			if (req_has_async_data(req)) -				return -EAGAIN; -			if (io_alloc_async_data(req)) { -				ret = -ENOMEM; +			return -EAGAIN; +		} +		if (ret == -ECONNABORTED) { +			if (connect->seen_econnaborted)  				goto out; -			} -			memcpy(req->async_data, &__io, sizeof(__io)); +			connect->seen_econnaborted = true; +		} +		if (req_has_async_data(req)) +			return -EAGAIN; +		if (io_alloc_async_data(req)) { +			ret = -ENOMEM; +			goto out;  		} +		memcpy(req->async_data, &__io, sizeof(__io));  		return -EAGAIN;  	}  	if (ret == -ERESTARTSYS)  |