summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/kern/uipc_sockbuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/kern/uipc_sockbuf.c')
-rw-r--r--freebsd/sys/kern/uipc_sockbuf.c79
1 files changed, 62 insertions, 17 deletions
diff --git a/freebsd/sys/kern/uipc_sockbuf.c b/freebsd/sys/kern/uipc_sockbuf.c
index ec493c04..cf99c615 100644
--- a/freebsd/sys/kern/uipc_sockbuf.c
+++ b/freebsd/sys/kern/uipc_sockbuf.c
@@ -961,23 +961,14 @@ sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa,
return (retval);
}
-int
+void
sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
struct mbuf *control)
{
- struct mbuf *m, *n, *mlast;
- int space;
-
- SOCKBUF_LOCK_ASSERT(sb);
+ struct mbuf *m, *mlast;
- if (control == NULL)
- panic("sbappendcontrol_locked");
- space = m_length(control, &n) + m_length(m0, NULL);
-
- if (space > sbspace(sb))
- return (0);
m_clrprotoflags(m0);
- n->m_next = m0; /* concatenate data to control */
+ m_last(control)->m_next = m0;
SBLASTRECORDCHK(sb);
@@ -991,18 +982,15 @@ sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
SBLASTMBUFCHK(sb);
SBLASTRECORDCHK(sb);
- return (1);
}
-int
+void
sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control)
{
- int retval;
SOCKBUF_LOCK(sb);
- retval = sbappendcontrol_locked(sb, m0, control);
+ sbappendcontrol_locked(sb, m0, control);
SOCKBUF_UNLOCK(sb);
- return (retval);
}
/*
@@ -1289,6 +1277,63 @@ sbsndptr(struct sockbuf *sb, u_int off, u_int len, u_int *moff)
return (ret);
}
+struct mbuf *
+#ifndef __rtems__
+sbsndptr_noadv(struct sockbuf *sb, uint32_t off, uint32_t *moff)
+#else /* __rtems__ */
+sbsndptr_noadv(struct sockbuf *sb, u_int off, u_int *moff)
+#endif /* __rtems__ */
+{
+ struct mbuf *m;
+
+ KASSERT(sb->sb_mb != NULL, ("%s: sb_mb is NULL", __func__));
+ if (sb->sb_sndptr == NULL || sb->sb_sndptroff > off) {
+ *moff = off;
+ if (sb->sb_sndptr == NULL) {
+ sb->sb_sndptr = sb->sb_mb;
+ sb->sb_sndptroff = 0;
+ }
+ return (sb->sb_mb);
+ } else {
+ m = sb->sb_sndptr;
+ off -= sb->sb_sndptroff;
+ }
+ *moff = off;
+ return (m);
+}
+
+void
+#ifndef __rtems__
+sbsndptr_adv(struct sockbuf *sb, struct mbuf *mb, uint32_t len)
+#else /* __rtems__ */
+sbsndptr_adv(struct sockbuf *sb, struct mbuf *mb, u_int len)
+#endif /* __rtems__ */
+{
+ /*
+ * A small copy was done, advance forward the sb_sbsndptr to cover
+ * it.
+ */
+ struct mbuf *m;
+
+ if (mb != sb->sb_sndptr) {
+ /* Did not copyout at the same mbuf */
+ return;
+ }
+ m = mb;
+ while (m && (len > 0)) {
+ if (len >= m->m_len) {
+ len -= m->m_len;
+ if (m->m_next) {
+ sb->sb_sndptroff += m->m_len;
+ sb->sb_sndptr = m->m_next;
+ }
+ m = m->m_next;
+ } else {
+ len = 0;
+ }
+ }
+}
+
/*
* Return the first mbuf and the mbuf data offset for the provided
* send offset without changing the "sb_sndptroff" field.