- optimize the initialization of the SB max variables.

- Missing lock when sending data and moving it to the
  outqueue.
- If a mbuf alloc fails during moving to outqueue the
  reassembly of the old mbuf chain was incorrect.
- some_taken becomes a counter in sctputil.c instead of a set to 1.
- Fix a panic to be only under invarients and have a proper recovery.
- msg_flags needed to be set.to the value collected not or'd.

MFC after:	1 week
This commit is contained in:
Randall Stewart 2007-12-06 00:22:55 +00:00
parent 32089e4962
commit 9c04b2966d
2 changed files with 20 additions and 9 deletions

View File

@ -6459,6 +6459,10 @@ out_gu:
/* clear out the chunk before setting up */ /* clear out the chunk before setting up */
memset(chk, 0, sizeof(*chk)); memset(chk, 0, sizeof(*chk));
chk->rec.data.rcv_flags = rcv_flags; chk->rec.data.rcv_flags = rcv_flags;
if ((send_lock_up == 0) && (sp->msg_is_complete == 0)) {
SCTP_TCB_SEND_LOCK(stcb);
send_lock_up = 1;
}
if (SCTP_BUF_IS_EXTENDED(sp->data)) { if (SCTP_BUF_IS_EXTENDED(sp->data)) {
chk->copy_by_ref = 1; chk->copy_by_ref = 1;
} else { } else {
@ -6521,6 +6525,12 @@ out_gu:
} else { } else {
atomic_subtract_int(&sp->length, to_move); atomic_subtract_int(&sp->length, to_move);
} }
if (chk->last_mbuf == NULL) {
chk->last_mbuf = chk->data;
while (SCTP_BUF_NEXT(chk->last_mbuf) != NULL) {
chk->last_mbuf = SCTP_BUF_NEXT(chk->last_mbuf);
}
}
if (M_LEADINGSPACE(chk->data) < (int)sizeof(struct sctp_data_chunk)) { if (M_LEADINGSPACE(chk->data) < (int)sizeof(struct sctp_data_chunk)) {
/* Not enough room for a chunk header, get some */ /* Not enough room for a chunk header, get some */
struct mbuf *m; struct mbuf *m;
@ -6546,7 +6556,7 @@ out_gu:
/* reassemble the data */ /* reassemble the data */
m_tmp = sp->data; m_tmp = sp->data;
sp->data = chk->data; sp->data = chk->data;
SCTP_BUF_NEXT(sp->data) = m_tmp; SCTP_BUF_NEXT(chk->last_mbuf) = m_tmp;
} }
sp->some_taken = some_taken; sp->some_taken = some_taken;
atomic_add_int(&sp->length, to_move); atomic_add_int(&sp->length, to_move);
@ -6583,12 +6593,6 @@ out_gu:
* get last_mbuf and counts of mb useage This is ugly but hopefully * get last_mbuf and counts of mb useage This is ugly but hopefully
* its only one mbuf. * its only one mbuf.
*/ */
if (chk->last_mbuf == NULL) {
chk->last_mbuf = chk->data;
while (SCTP_BUF_NEXT(chk->last_mbuf) != NULL) {
chk->last_mbuf = SCTP_BUF_NEXT(chk->last_mbuf);
}
}
chk->flags = 0; chk->flags = 0;
chk->asoc = &stcb->asoc; chk->asoc = &stcb->asoc;
chk->pad_inplace = 0; chk->pad_inplace = 0;

View File

@ -5260,7 +5260,7 @@ found_one:
* If we reach here, control has a some data for us to read off. * If we reach here, control has a some data for us to read off.
* Note that stcb COULD be NULL. * Note that stcb COULD be NULL.
*/ */
control->some_taken = 1; control->some_taken++;
if (hold_sblock) { if (hold_sblock) {
SOCKBUF_UNLOCK(&so->so_rcv); SOCKBUF_UNLOCK(&so->so_rcv);
hold_sblock = 0; hold_sblock = 0;
@ -5731,7 +5731,14 @@ wait_some_more:
* big trouble.. we have the lock and its * big trouble.. we have the lock and its
* corrupt? * corrupt?
*/ */
#ifdef INVARIANTS
panic("Impossible data==NULL length !=0"); panic("Impossible data==NULL length !=0");
#endif
out_flags |= MSG_EOR;
out_flags |= MSG_TRUNC;
control->length = 0;
SCTP_INP_READ_UNLOCK(inp);
goto done_with_control;
} }
SCTP_INP_READ_UNLOCK(inp); SCTP_INP_READ_UNLOCK(inp);
/* We will fall around to get more data */ /* We will fall around to get more data */
@ -5807,7 +5814,7 @@ release_unlocked:
sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req);
} }
if (msg_flags) if (msg_flags)
*msg_flags |= out_flags; *msg_flags = out_flags;
out: out:
if (((out_flags & MSG_EOR) == 0) && if (((out_flags & MSG_EOR) == 0) &&
((in_flags & MSG_PEEK) == 0) && ((in_flags & MSG_PEEK) == 0) &&