* ensure that [off, off + len) is contiguous on the mbuf chain "m". * packet chain before "off" is kept untouched. * if offp == NULL, the target will start at on resulting chain. * if offp != NULL, the target will start at on resulting chain. * * on error return (NULL return value), original "m" will be freed. * * XXX: M_TRAILINGSPACE/M_LEADINGSPACE only permitte
| 94 | * XXX: M_TRAILINGSPACE/M_LEADINGSPACE only permitted on writable ext_buf. |
| 95 | */ |
| 96 | struct mbuf * |
| 97 | m_pulldown(struct mbuf *m, int off, int len, int *offp) |
| 98 | { |
| 99 | struct mbuf *n, *o; |
| 100 | int hlen, tlen, olen; |
| 101 | int writable; |
| 102 | |
| 103 | /* check invalid arguments. */ |
| 104 | KASSERT(m != NULL, ("%s: fix caller: m is NULL off %d len %d offp %p\n", |
| 105 | __func__, off, len, offp)); |
| 106 | if (len > MCLBYTES) { |
| 107 | m_freem(m); |
| 108 | return NULL; /* impossible */ |
| 109 | } |
| 110 | |
| 111 | #ifdef PULLDOWN_DEBUG |
| 112 | { |
| 113 | struct mbuf *t; |
| 114 | printf("before:"); |
| 115 | for (t = m; t; t = t->m_next) |
| 116 | printf(" %d", t->m_len); |
| 117 | printf("\n"); |
| 118 | } |
| 119 | #endif |
| 120 | n = m; |
| 121 | while (n != NULL && off > 0) { |
| 122 | if (n->m_len > off) |
| 123 | break; |
| 124 | off -= n->m_len; |
| 125 | n = n->m_next; |
| 126 | } |
| 127 | /* be sure to point non-empty mbuf */ |
| 128 | while (n != NULL && n->m_len == 0) |
| 129 | n = n->m_next; |
| 130 | if (!n) { |
| 131 | m_freem(m); |
| 132 | return NULL; /* mbuf chain too short */ |
| 133 | } |
| 134 | |
| 135 | /* |
| 136 | * The following comment is dated but still partially applies: |
| 137 | * |
| 138 | * XXX: This code is flawed because it considers a "writable" mbuf |
| 139 | * data region to require all of the following: |
| 140 | * (i) mbuf _has_ to have M_EXT set; if it is just a regular |
| 141 | * mbuf, it is still not considered "writable." |
| 142 | * (ii) since mbuf has M_EXT, the ext_type _has_ to be |
| 143 | * EXT_CLUSTER. Anything else makes it non-writable. |
| 144 | * (iii) M_WRITABLE() must evaluate true. |
| 145 | * Ideally, the requirement should only be (iii). |
| 146 | * |
| 147 | * If we're writable, we're sure we're writable, because the ref. count |
| 148 | * cannot increase from 1, as that would require possession of mbuf |
| 149 | * n by someone else (which is impossible). However, if we're _not_ |
| 150 | * writable, we may eventually become writable )if the ref. count drops |
| 151 | * to 1), but we'll fail to notice it unless we re-evaluate |
| 152 | * M_WRITABLE(). For now, we only evaluate once at the beginning and |
| 153 | * live with this. |
no test coverage detected