Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F110153843
D48924.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D48924.id.diff
View Options
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -90,6 +90,7 @@
#include <sys/un.h>
#include <sys/unpcb.h>
#include <sys/vnode.h>
+#include <machine/stack.h>
#include <net/vnet.h>
@@ -1059,18 +1060,19 @@
static int
uipc_sosend_stream_or_seqpacket(struct socket *so, struct sockaddr *addr,
- struct uio *uio, struct mbuf *m, struct mbuf *c, int flags,
+ struct uio *uio0, struct mbuf *m, struct mbuf *c, int flags,
struct thread *td)
{
struct unpcb *unp2;
struct socket *so2;
struct sockbuf *sb;
+ struct uio *uio;
struct mchain mc, cmc;
- ssize_t resid, sent;
- bool nonblock, eor;
+ size_t resid, sent;
+ bool nonblock, eor, aio;
int error;
- MPASS((uio != NULL && m == NULL) || (m != NULL && uio == NULL));
+ MPASS((uio0 != NULL && m == NULL) || (m != NULL && uio0 == NULL));
MPASS(m == NULL || c == NULL);
if (__predict_false(flags & MSG_OOB))
@@ -1083,17 +1085,37 @@
mc = MCHAIN_INITIALIZER(&mc);
cmc = MCHAIN_INITIALIZER(&cmc);
sent = 0;
+ aio = false;
if (m == NULL) {
if (c != NULL && (error = unp_internalize(c, &cmc, td)))
goto out;
+ /*
+ * This function may read more data from the uio than it would
+ * then place on socket. That would leave uio inconsistent
+ * upon return. Normally uio is allocated on the stack of the
+ * syscall thread and we don't care about leaving it consistent.
+ * However, aio(9) will allocate a uio as part of job and will
+ * use it to track progress. We detect aio(9) checking the
+ * SB_AIO_RUNNING flag. It is safe to check it without lock
+ * cause it is set and cleared in the same taskqueue thread.
+ */
+ if (__predict_false(so->so_snd.sb_flags & SB_AIO_RUNNING)) {
+ MPASS(nonblock);
+ uio = cloneuio(uio0);
+ aio = true;
+ } else {
+ MPASS(kstack_contains(curthread, (vm_offset_t)uio0,
+ sizeof(struct uio)));
+ uio = uio0;
+ resid = uio->uio_resid;
+ }
/*
* Optimization for a case when our send fits into the receive
* buffer - do the copyin before taking any locks, sized to our
* send buffer. Later copyins will also take into account
* space in the peer's receive buffer.
*/
- resid = uio->uio_resid;
error = mc_uiotomc(&mc, uio, so->so_snd.sb_hiwat, 0, M_WAITOK,
eor ? M_EOR : 0);
if (__predict_false(error))
@@ -1240,15 +1262,17 @@
out3:
SOCK_IO_SEND_UNLOCK(so);
out2:
+ if (aio) {
+ freeuio(uio);
+ uioadvance(uio0, sent);
+ } else if (uio != NULL)
+ uio->uio_resid = resid - sent;
if (!mc_empty(&cmc))
unp_scan(mc_first(&cmc), unp_freerights);
out:
mc_freem(&mc);
mc_freem(&cmc);
- if (uio != NULL)
- uio->uio_resid = resid - sent;
-
return (error);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Feb 15, 9:06 AM (8 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16602172
Default Alt Text
D48924.id.diff (2 KB)
Attached To
Mode
D48924: unix/stream: try to fix uio problem with aio(4) on the side of the unix(4)
Attached
Detach File
Event Timeline
Log In to Comment