Page MenuHomeFreeBSD

D44148.id135829.diff
No OneTemporary

D44148.id135829.diff

diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1108,6 +1108,72 @@
m->m_next = NULL;
return (n);
}
+
+/*
+ * Partition mchain in two pieces, keeping len0 bytes in head and transferring
+ * remainder to tail. In case of failure, both chains to be left untouched.
+ * M_EOR is observed correctly.
+ * Resulting mbufs might be read-only.
+ */
+int
+mc_split(struct mchain *head, struct mchain *tail, u_int len0, int wait)
+{
+ struct mbuf *m, *n;
+ u_int len, mlen, remain;
+
+ MPASS(!(STAILQ_FIRST(&head->mc_q)->m_flags & M_PKTHDR));
+ MBUF_CHECKSLEEP(wait);
+
+ mlen = 0;
+ len = len0;
+ STAILQ_FOREACH(m, &head->mc_q, m_stailq) {
+ mlen += MSIZE;
+ if (m->m_flags & M_EXT)
+ mlen += m->m_ext.ext_size;
+ if (len > m->m_len)
+ len -= m->m_len;
+ else
+ break;
+ }
+ if (__predict_false(m == NULL)) {
+ *tail = MCHAIN_INITIALIZER(tail);
+ return (0);
+ }
+ remain = m->m_len - len;
+ if (remain > 0) {
+ if (__predict_false((n = m_get(wait, m->m_type)) == NULL))
+ return (ENOMEM);
+ m_align(n, remain);
+ if (m->m_flags & M_EXT) {
+ n->m_data = m->m_data + len;
+ mb_dupcl(n, m);
+ } else
+ bcopy(mtod(m, char *) + len, mtod(n, char *), remain);
+ }
+
+ /* XXXGL: need STAILQ_SPLIT */
+ STAILQ_FIRST(&tail->mc_q) = STAILQ_NEXT(m, m_stailq);
+ tail->mc_q.stqh_last = head->mc_q.stqh_last;
+ tail->mc_len = head->mc_len - len0;
+ tail->mc_mlen = head->mc_mlen - mlen;
+ if (remain > 0) {
+ MPASS(n->m_len == 0);
+ mc_prepend(tail, n);
+ n->m_len = remain;
+ m->m_len -= remain;
+ if (m->m_flags & M_EOR) {
+ m->m_flags &= ~M_EOR;
+ n->m_flags |= M_EOR;
+ }
+ }
+ head->mc_q.stqh_last = &STAILQ_NEXT(m, m_stailq);
+ STAILQ_NEXT(m, m_stailq) = NULL;
+ head->mc_len = len0;
+ head->mc_mlen = mlen;
+
+ return (0);
+}
+
/*
* Routine to copy from device local memory into mbufs.
* Note that `off' argument is offset into first mbuf of target chain from
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -1750,6 +1750,17 @@
mc_inc(mc, m);
}
+static inline void
+mc_concat(struct mchain *head, struct mchain *tail)
+{
+ STAILQ_CONCAT(&head->mc_q, &tail->mc_q);
+ head->mc_len += tail->mc_len;
+ head->mc_mlen += tail->mc_mlen;
+ tail->mc_len = tail->mc_mlen = 0;
+}
+
+int mc_split(struct mchain *, struct mchain *, u_int, int);
+
/*
* Note: STAILQ_REMOVE() is expensive. mc_remove_after() needs to be provided
* as long as there consumers that would benefit from it.

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 5, 2:15 AM (12 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29266683
Default Alt Text
D44148.id135829.diff (2 KB)

Event Timeline