diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/link.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index ad356df12d1e..02b083e5c219 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -2406,6 +2406,8 @@ void tipc_link_recv_bundle(struct sk_buff *buf) | |||
2406 | */ | 2406 | */ |
2407 | static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | 2407 | static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) |
2408 | { | 2408 | { |
2409 | struct sk_buff *buf_chain = NULL; | ||
2410 | struct sk_buff *buf_chain_tail = (struct sk_buff *)&buf_chain; | ||
2409 | struct tipc_msg *inmsg = buf_msg(buf); | 2411 | struct tipc_msg *inmsg = buf_msg(buf); |
2410 | struct tipc_msg fragm_hdr; | 2412 | struct tipc_msg fragm_hdr; |
2411 | u32 insize = msg_size(inmsg); | 2413 | u32 insize = msg_size(inmsg); |
@@ -2414,7 +2416,7 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
2414 | u32 rest = insize; | 2416 | u32 rest = insize; |
2415 | u32 pack_sz = l_ptr->max_pkt; | 2417 | u32 pack_sz = l_ptr->max_pkt; |
2416 | u32 fragm_sz = pack_sz - INT_H_SIZE; | 2418 | u32 fragm_sz = pack_sz - INT_H_SIZE; |
2417 | u32 fragm_no = 1; | 2419 | u32 fragm_no = 0; |
2418 | u32 destaddr; | 2420 | u32 destaddr; |
2419 | 2421 | ||
2420 | if (msg_short(inmsg)) | 2422 | if (msg_short(inmsg)) |
@@ -2426,9 +2428,6 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
2426 | 2428 | ||
2427 | tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, | 2429 | tipc_msg_init(&fragm_hdr, MSG_FRAGMENTER, FIRST_FRAGMENT, |
2428 | INT_H_SIZE, destaddr); | 2430 | INT_H_SIZE, destaddr); |
2429 | msg_set_long_msgno(&fragm_hdr, l_ptr->long_msg_seq_no++); | ||
2430 | msg_set_fragm_no(&fragm_hdr, fragm_no); | ||
2431 | l_ptr->stats.sent_fragmented++; | ||
2432 | 2431 | ||
2433 | /* Chop up message: */ | 2432 | /* Chop up message: */ |
2434 | 2433 | ||
@@ -2441,27 +2440,37 @@ static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) | |||
2441 | } | 2440 | } |
2442 | fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); | 2441 | fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); |
2443 | if (fragm == NULL) { | 2442 | if (fragm == NULL) { |
2444 | warn("Link unable to fragment message\n"); | 2443 | buf_discard(buf); |
2445 | dsz = -ENOMEM; | 2444 | while (buf_chain) { |
2446 | goto exit; | 2445 | buf = buf_chain; |
2446 | buf_chain = buf_chain->next; | ||
2447 | buf_discard(buf); | ||
2448 | } | ||
2449 | return -ENOMEM; | ||
2447 | } | 2450 | } |
2448 | msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); | 2451 | msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); |
2452 | fragm_no++; | ||
2453 | msg_set_fragm_no(&fragm_hdr, fragm_no); | ||
2449 | skb_copy_to_linear_data(fragm, &fragm_hdr, INT_H_SIZE); | 2454 | skb_copy_to_linear_data(fragm, &fragm_hdr, INT_H_SIZE); |
2450 | skb_copy_to_linear_data_offset(fragm, INT_H_SIZE, crs, | 2455 | skb_copy_to_linear_data_offset(fragm, INT_H_SIZE, crs, |
2451 | fragm_sz); | 2456 | fragm_sz); |
2452 | /* Send queued messages first, if any: */ | 2457 | buf_chain_tail->next = fragm; |
2458 | buf_chain_tail = fragm; | ||
2453 | 2459 | ||
2454 | l_ptr->stats.sent_fragments++; | ||
2455 | tipc_link_send_buf(l_ptr, fragm); | ||
2456 | if (!tipc_link_is_up(l_ptr)) | ||
2457 | return dsz; | ||
2458 | msg_set_fragm_no(&fragm_hdr, ++fragm_no); | ||
2459 | rest -= fragm_sz; | 2460 | rest -= fragm_sz; |
2460 | crs += fragm_sz; | 2461 | crs += fragm_sz; |
2461 | msg_set_type(&fragm_hdr, FRAGMENT); | 2462 | msg_set_type(&fragm_hdr, FRAGMENT); |
2462 | } | 2463 | } |
2463 | exit: | ||
2464 | buf_discard(buf); | 2464 | buf_discard(buf); |
2465 | |||
2466 | /* Append chain of fragments to send queue & send them */ | ||
2467 | |||
2468 | l_ptr->long_msg_seq_no++; | ||
2469 | link_add_chain_to_outqueue(l_ptr, buf_chain, l_ptr->long_msg_seq_no); | ||
2470 | l_ptr->stats.sent_fragments += fragm_no; | ||
2471 | l_ptr->stats.sent_fragmented++; | ||
2472 | tipc_link_push_queue(l_ptr); | ||
2473 | |||
2465 | return dsz; | 2474 | return dsz; |
2466 | } | 2475 | } |
2467 | 2476 | ||