diff options
author | Allan Stephens <Allan.Stephens@windriver.com> | 2011-04-21 20:58:26 +0200 |
---|---|---|
committer | Paul Gortmaker <paul.gortmaker@windriver.com> | 2011-05-10 22:03:59 +0200 |
commit | 3a777ff8b14456e15991c9fcc225943453dc3a75 (patch) | |
tree | 50f2b2ca5c9a2a4a1df107da4db00611ae938f32 /net/tipc/bearer.c | |
parent | tipc: Introduce routine to enqueue a chain of messages on link tx queue (diff) | |
download | linux-3a777ff8b14456e15991c9fcc225943453dc3a75.tar.xz linux-3a777ff8b14456e15991c9fcc225943453dc3a75.zip |
tipc: Enhance handling of discovery object creation failures
Modifies bearer creation and deletion code to improve handling of
scenarios when a neighbor discovery object cannot be created. The
creation routine now aborts the creation of a bearer if its discovery
object cannot be created, and deletes the newly created bearer, rather
than failing quietly and leaving an unusable bearer hanging around.
Since the exit via the goto label really isn't a definitive failure
in all cases, relabel it appropriately.
Signed-off-by: Allan Stephens <Allan.Stephens@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Diffstat (limited to 'net/tipc/bearer.c')
-rw-r--r-- | net/tipc/bearer.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index f7c29af4ab81..5fcd1c1214fd 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -46,6 +46,8 @@ static u32 media_count; struct tipc_bearer tipc_bearers[MAX_BEARERS]; +static void bearer_disable(struct tipc_bearer *b_ptr); + /** * media_name_valid - validate media name * @@ -518,7 +520,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority) if (!m_ptr) { warn("Bearer <%s> rejected, media <%s> not registered\n", name, b_name.media_name); - goto failed; + goto exit; } if (priority == TIPC_MEDIA_LINK_PRI) @@ -534,14 +536,14 @@ restart: } if (!strcmp(name, tipc_bearers[i].name)) { warn("Bearer <%s> rejected, already enabled\n", name); - goto failed; + goto exit; } if ((tipc_bearers[i].priority == priority) && (++with_this_prio > 2)) { if (priority-- == 0) { warn("Bearer <%s> rejected, duplicate priority\n", name); - goto failed; + goto exit; } warn("Bearer <%s> priority adjustment required %u->%u\n", name, priority + 1, priority); @@ -551,7 +553,7 @@ restart: if (bearer_id >= MAX_BEARERS) { warn("Bearer <%s> rejected, bearer limit reached (%u)\n", name, MAX_BEARERS); - goto failed; + goto exit; } b_ptr = &tipc_bearers[bearer_id]; @@ -559,7 +561,7 @@ restart: res = m_ptr->enable_bearer(b_ptr); if (res) { warn("Bearer <%s> rejected, enable failure (%d)\n", name, -res); - goto failed; + goto exit; } b_ptr->identity = bearer_id; @@ -569,14 +571,18 @@ restart: b_ptr->priority = priority; INIT_LIST_HEAD(&b_ptr->cong_links); INIT_LIST_HEAD(&b_ptr->links); - b_ptr->link_req = tipc_disc_init_link_req(b_ptr, &m_ptr->bcast_addr, - disc_domain); spin_lock_init(&b_ptr->lock); - write_unlock_bh(&tipc_net_lock); + + res = tipc_disc_create(b_ptr, &m_ptr->bcast_addr, disc_domain); + if (res) { + bearer_disable(b_ptr); + warn("Bearer <%s> rejected, discovery object creation failed\n", + name); + goto exit; + } info("Enabled bearer <%s>, discovery domain %s, priority %u\n", name, tipc_addr_string_fill(addr_string, disc_domain), priority); - return 0; -failed: +exit: write_unlock_bh(&tipc_net_lock); return res; } @@ -627,14 +633,14 @@ static void bearer_disable(struct tipc_bearer *b_ptr) struct link *temp_l_ptr; info("Disabling bearer <%s>\n", b_ptr->name); - tipc_disc_stop_link_req(b_ptr->link_req); spin_lock_bh(&b_ptr->lock); - b_ptr->link_req = NULL; b_ptr->blocked = 1; b_ptr->media->disable_bearer(b_ptr); list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { tipc_link_delete(l_ptr); } + if (b_ptr->link_req) + tipc_disc_delete(b_ptr->link_req); spin_unlock_bh(&b_ptr->lock); memset(b_ptr, 0, sizeof(struct tipc_bearer)); } |