diff options
author | jhb <jhb@FreeBSD.org> | 2016-05-24 21:09:05 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2016-05-24 21:09:05 +0000 |
commit | f913b0e3d54d3521ae7eb9f7b68ec2c4d357eb55 (patch) | |
tree | e8c4f47accb21440768f43e2a8cf680e6a3f2710 /sys/kern | |
parent | 3e61cae63a0cae47555a546715abf14de1d21520 (diff) | |
download | FreeBSD-src-f913b0e3d54d3521ae7eb9f7b68ec2c4d357eb55.zip FreeBSD-src-f913b0e3d54d3521ae7eb9f7b68ec2c4d357eb55.tar.gz |
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
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/sys_socket.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index ffd59df..fb7eb96 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 |