diff options
Diffstat (limited to 'net/sctp/outqueue.c')
| -rw-r--r-- | net/sctp/outqueue.c | 23 | 
1 files changed, 15 insertions, 8 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 4db012aa25f7..c4ec99b20150 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -364,10 +364,12 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc,  	list_for_each_entry_safe(chk, temp, queue, transmitted_list) {  		struct sctp_stream_out *streamout; -		if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || -		    chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive) +		if (!chk->msg->abandoned && +		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || +		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))  			continue; +		chk->msg->abandoned = 1;  		list_del_init(&chk->transmitted_list);  		sctp_insert_list(&asoc->outqueue.abandoned,  				 &chk->transmitted_list); @@ -377,7 +379,8 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc,  		asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;  		streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; -		if (!chk->tsn_gap_acked) { +		if (queue != &asoc->outqueue.retransmit && +		    !chk->tsn_gap_acked) {  			if (chk->transport)  				chk->transport->flight_size -=  						sctp_data_size(chk); @@ -403,10 +406,13 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,  	q->sched->unsched_all(&asoc->stream);  	list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) { -		if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || -		    chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive) +		if (!chk->msg->abandoned && +		    (!(chk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG) || +		     !SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || +		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))  			continue; +		chk->msg->abandoned = 1;  		sctp_sched_dequeue_common(q, chk);  		asoc->sent_cnt_removable--;  		asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; @@ -912,9 +918,9 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)  			break;  		case SCTP_CID_ABORT: -			if (sctp_test_T_bit(chunk)) { +			if (sctp_test_T_bit(chunk))  				packet->vtag = asoc->c.my_vtag; -			} +			/* fallthru */  		/* The following chunks are "response" chunks, i.e.  		 * they are generated in response to something we  		 * received.  If we are sending these, then we can @@ -1434,7 +1440,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,  			/* If this chunk has not been acked, stop  			 * considering it as 'outstanding'.  			 */ -			if (!tchunk->tsn_gap_acked) { +			if (transmitted_queue != &q->retransmit && +			    !tchunk->tsn_gap_acked) {  				if (tchunk->transport)  					tchunk->transport->flight_size -=  							sctp_data_size(tchunk);  | 
