aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2007-07-26 03:05:07 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-31 05:28:02 -0400
commit94571065757a4f2619c48ab4e36cafdc635028ce (patch)
tree4a7a00e06acdf51bef9ef987c90975c9ccda4e32 /net/tipc/link.c
parent0ed72ec4afb9fbd584e03763707d3db0f62ee1be (diff)
[TIPC]: fix tipc_link_create error handling
if printbuf allocation or tipc_node_attach_link() fails, invalid references to the link are left in the associated node and bearer structures. Fix by allocating printbuf early and moving timer initialization and the addition of the new link to the b_ptr->links list after tipc_node_attach_link() succeeded. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 5adfdfd49d61..1d674e0848fa 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -423,6 +423,17 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
423 return NULL; 423 return NULL;
424 } 424 }
425 425
426 if (LINK_LOG_BUF_SIZE) {
427 char *pb = kmalloc(LINK_LOG_BUF_SIZE, GFP_ATOMIC);
428
429 if (!pb) {
430 kfree(l_ptr);
431 warn("Link creation failed, no memory for print buffer\n");
432 return NULL;
433 }
434 tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE);
435 }
436
426 l_ptr->addr = peer; 437 l_ptr->addr = peer;
427 if_name = strchr(b_ptr->publ.name, ':') + 1; 438 if_name = strchr(b_ptr->publ.name, ':') + 1;
428 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", 439 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:",
@@ -432,8 +443,6 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
432 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 443 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer));
433 /* note: peer i/f is appended to link name by reset/activate */ 444 /* note: peer i/f is appended to link name by reset/activate */
434 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 445 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr));
435 k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr);
436 list_add_tail(&l_ptr->link_list, &b_ptr->links);
437 l_ptr->checkpoint = 1; 446 l_ptr->checkpoint = 1;
438 l_ptr->b_ptr = b_ptr; 447 l_ptr->b_ptr = b_ptr;
439 link_set_supervision_props(l_ptr, b_ptr->media->tolerance); 448 link_set_supervision_props(l_ptr, b_ptr->media->tolerance);
@@ -459,21 +468,14 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer,
459 468
460 l_ptr->owner = tipc_node_attach_link(l_ptr); 469 l_ptr->owner = tipc_node_attach_link(l_ptr);
461 if (!l_ptr->owner) { 470 if (!l_ptr->owner) {
471 if (LINK_LOG_BUF_SIZE)
472 kfree(l_ptr->print_buf.buf);
462 kfree(l_ptr); 473 kfree(l_ptr);
463 return NULL; 474 return NULL;
464 } 475 }
465 476
466 if (LINK_LOG_BUF_SIZE) { 477 k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr);
467 char *pb = kmalloc(LINK_LOG_BUF_SIZE, GFP_ATOMIC); 478 list_add_tail(&l_ptr->link_list, &b_ptr->links);
468
469 if (!pb) {
470 kfree(l_ptr);
471 warn("Link creation failed, no memory for print buffer\n");
472 return NULL;
473 }
474 tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE);
475 }
476
477 tipc_k_signal((Handler)tipc_link_start, (unsigned long)l_ptr); 479 tipc_k_signal((Handler)tipc_link_start, (unsigned long)l_ptr);
478 480
479 dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n", 481 dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n",