* Compress M_NOTREADY mbufs after they have been readied by sbready(). * * sbcompress() skips M_NOTREADY mbufs since the data is not available to * be copied at the time of sbcompress(). This function combines small * mbufs similar to sbcompress() once mbufs are ready. 'm0' is the first * mbuf sbready() marked ready, and 'end' is the first mbuf still not * ready. */
| 104 | * ready. |
| 105 | */ |
| 106 | static void |
| 107 | sbready_compress(struct sockbuf *sb, struct mbuf *m0, struct mbuf *end) |
| 108 | { |
| 109 | struct mbuf *m, *n; |
| 110 | int ext_size; |
| 111 | |
| 112 | SOCKBUF_LOCK_ASSERT(sb); |
| 113 | |
| 114 | if ((sb->sb_flags & SB_NOCOALESCE) != 0) |
| 115 | return; |
| 116 | |
| 117 | for (m = m0; m != end; m = m->m_next) { |
| 118 | MPASS((m->m_flags & M_NOTREADY) == 0); |
| 119 | /* |
| 120 | * NB: In sbcompress(), 'n' is the last mbuf in the |
| 121 | * socket buffer and 'm' is the new mbuf being copied |
| 122 | * into the trailing space of 'n'. Here, the roles |
| 123 | * are reversed and 'n' is the next mbuf after 'm' |
| 124 | * that is being copied into the trailing space of |
| 125 | * 'm'. |
| 126 | */ |
| 127 | n = m->m_next; |
| 128 | #ifdef KERN_TLS |
| 129 | /* Try to coalesce adjacent ktls mbuf hdr/trailers. */ |
| 130 | if ((n != NULL) && (n != end) && (m->m_flags & M_EOR) == 0 && |
| 131 | (m->m_flags & M_EXTPG) && |
| 132 | (n->m_flags & M_EXTPG) && |
| 133 | !mbuf_has_tls_session(m) && |
| 134 | !mbuf_has_tls_session(n)) { |
| 135 | int hdr_len, trail_len; |
| 136 | |
| 137 | hdr_len = n->m_epg_hdrlen; |
| 138 | trail_len = m->m_epg_trllen; |
| 139 | if (trail_len != 0 && hdr_len != 0 && |
| 140 | trail_len + hdr_len <= MBUF_PEXT_TRAIL_LEN) { |
| 141 | /* copy n's header to m's trailer */ |
| 142 | memcpy(&m->m_epg_trail[trail_len], |
| 143 | n->m_epg_hdr, hdr_len); |
| 144 | m->m_epg_trllen += hdr_len; |
| 145 | m->m_len += hdr_len; |
| 146 | n->m_epg_hdrlen = 0; |
| 147 | n->m_len -= hdr_len; |
| 148 | } |
| 149 | } |
| 150 | #endif |
| 151 | |
| 152 | /* Compress small unmapped mbufs into plain mbufs. */ |
| 153 | if ((m->m_flags & M_EXTPG) && m->m_len <= MLEN && |
| 154 | !mbuf_has_tls_session(m)) { |
| 155 | ext_size = m->m_ext.ext_size; |
| 156 | if (mb_unmapped_compress(m) == 0) { |
| 157 | sb->sb_mbcnt -= ext_size; |
| 158 | sb->sb_ccnt -= 1; |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | while ((n != NULL) && (n != end) && (m->m_flags & M_EOR) == 0 && |
| 163 | M_WRITABLE(m) && |
no test coverage detected