aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/sys_socket.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2016-05-24 21:09:05 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2016-05-24 21:09:05 +0000
commit778ce4f297a5adb6fea606b95acfaa4b4b318651 (patch)
treee8c4f47accb21440768f43e2a8cf680e6a3f2710 /sys/kern/sys_socket.c
parentcb05064e7099cc87afd96e1f78bc70cc2ad5ccf6 (diff)
downloadsrc-778ce4f297a5adb6fea606b95acfaa4b4b318651.tar.gz
src-778ce4f297a5adb6fea606b95acfaa4b4b318651.zip
Return the correct status when a partially completed request is cancelled.
After the previous changes to fix requests on blocking sockets to complete across multiple operations, an edge case exists where a request can be cancelled after it has partially completed. POSIX doesn't appear to dictate exactly how to handle this case, but in general I feel that aio_cancel() should arrange to cancel any request it can, but that any partially completed requests should return a partial completion rather than ECANCELED. To that end, fix the socket AIO cancellation routine to return a short read/write if a partially completed request is cancelled rather than ECANCELED. Sponsored by: Chelsio Communications
Notes
Notes: svn path=/head/; revision=300626
Diffstat (limited to 'sys/kern/sys_socket.c')
-rw-r--r--sys/kern/sys_socket.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index ffd59df76774..fb7eb96b5674 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -721,6 +721,7 @@ soo_aio_cancel(struct kaiocb *job)
{
struct socket *so;
struct sockbuf *sb;
+ long done;
int opcode;
so = job->fd_file->f_data;
@@ -739,7 +740,11 @@ soo_aio_cancel(struct kaiocb *job)
sb->sb_flags &= ~SB_AIO;
SOCKBUF_UNLOCK(sb);
- aio_cancel(job);
+ done = job->uaiocb._aiocb_private.status;
+ if (done != 0)
+ aio_complete(job, done, 0);
+ else
+ aio_cancel(job);
}
static int