Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tipc: refactor function tipc_enable_bearer()

As a preparation for the next commits we try to reduce the footprint of
the function tipc_enable_bearer(), while hopefully making is simpler to
follow.

Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jon Maloy and committed by
David S. Miller
cb30a633 59461949

+70 -66
+70 -66
net/tipc/bearer.c
··· 230 230 * tipc_enable_bearer - enable bearer with the given name 231 231 */ 232 232 static int tipc_enable_bearer(struct net *net, const char *name, 233 - u32 disc_domain, u32 priority, 233 + u32 disc_domain, u32 prio, 234 234 struct nlattr *attr[]) 235 235 { 236 - struct tipc_net *tn = net_generic(net, tipc_net_id); 236 + struct tipc_net *tn = tipc_net(net); 237 + struct tipc_bearer_names b_names; 238 + u32 self = tipc_own_addr(net); 239 + int with_this_prio = 1; 237 240 struct tipc_bearer *b; 238 241 struct tipc_media *m; 239 - struct tipc_bearer_names b_names; 240 242 struct sk_buff *skb; 241 243 char addr_string[16]; 242 - u32 bearer_id; 243 - u32 with_this_prio; 244 - u32 i; 244 + int bearer_id = 0; 245 245 int res = -EINVAL; 246 + char *errstr = ""; 246 247 247 - if (!tn->own_addr) { 248 - pr_warn("Bearer <%s> rejected, not supported in standalone mode\n", 249 - name); 250 - return -ENOPROTOOPT; 248 + if (!self) { 249 + errstr = "not supported in standalone mode"; 250 + res = -ENOPROTOOPT; 251 + goto rejected; 251 252 } 253 + 252 254 if (!bearer_name_validate(name, &b_names)) { 253 - pr_warn("Bearer <%s> rejected, illegal name\n", name); 254 - return -EINVAL; 255 + errstr = "illegal name"; 256 + goto rejected; 255 257 } 256 - if (tipc_addr_domain_valid(disc_domain) && 257 - (disc_domain != tn->own_addr)) { 258 - if (tipc_in_scope(disc_domain, tn->own_addr)) { 259 - disc_domain = tn->own_addr & TIPC_ZONE_CLUSTER_MASK; 260 - res = 0; /* accept any node in own cluster */ 261 - } else if (in_own_cluster_exact(net, disc_domain)) 262 - res = 0; /* accept specified node in own cluster */ 258 + 259 + if (tipc_addr_domain_valid(disc_domain) && disc_domain != self) { 260 + if (tipc_in_scope(disc_domain, self)) { 261 + /* Accept any node in own cluster */ 262 + disc_domain = self & TIPC_ZONE_CLUSTER_MASK; 263 + res = 0; 264 + } else if (in_own_cluster_exact(net, disc_domain)) { 265 + /* Accept specified node in own cluster */ 266 + res = 0; 267 + } 263 268 } 264 269 if (res) { 265 - pr_warn("Bearer <%s> rejected, illegal discovery domain\n", 266 - name); 267 - return -EINVAL; 270 + errstr = "illegal discovery domain"; 271 + goto rejected; 268 272 } 269 - if ((priority > TIPC_MAX_LINK_PRI) && 270 - (priority != TIPC_MEDIA_LINK_PRI)) { 271 - pr_warn("Bearer <%s> rejected, illegal priority\n", name); 272 - return -EINVAL; 273 + 274 + if (prio > TIPC_MAX_LINK_PRI && prio != TIPC_MEDIA_LINK_PRI) { 275 + errstr = "illegal priority"; 276 + goto rejected; 273 277 } 274 278 275 279 m = tipc_media_find(b_names.media_name); 276 280 if (!m) { 277 - pr_warn("Bearer <%s> rejected, media <%s> not registered\n", 278 - name, b_names.media_name); 279 - return -EINVAL; 281 + errstr = "media not registered"; 282 + goto rejected; 280 283 } 281 284 282 - if (priority == TIPC_MEDIA_LINK_PRI) 283 - priority = m->priority; 285 + if (prio == TIPC_MEDIA_LINK_PRI) 286 + prio = m->priority; 284 287 285 - restart: 286 - bearer_id = MAX_BEARERS; 287 - with_this_prio = 1; 288 - for (i = MAX_BEARERS; i-- != 0; ) { 289 - b = rtnl_dereference(tn->bearer_list[i]); 290 - if (!b) { 291 - bearer_id = i; 292 - continue; 293 - } 288 + /* Check new bearer vs existing ones and find free bearer id if any */ 289 + while (bearer_id < MAX_BEARERS) { 290 + b = rtnl_dereference(tn->bearer_list[bearer_id]); 291 + if (!b) 292 + break; 294 293 if (!strcmp(name, b->name)) { 295 - pr_warn("Bearer <%s> rejected, already enabled\n", 296 - name); 297 - return -EINVAL; 294 + errstr = "already enabled"; 295 + goto rejected; 298 296 } 299 - if ((b->priority == priority) && 300 - (++with_this_prio > 2)) { 301 - if (priority-- == 0) { 302 - pr_warn("Bearer <%s> rejected, duplicate priority\n", 303 - name); 304 - return -EINVAL; 305 - } 306 - pr_warn("Bearer <%s> priority adjustment required %u->%u\n", 307 - name, priority + 1, priority); 308 - goto restart; 297 + bearer_id++; 298 + if (b->priority != prio) 299 + continue; 300 + if (++with_this_prio <= 2) 301 + continue; 302 + pr_warn("Bearer <%s>: already 2 bearers with priority %u\n", 303 + name, prio); 304 + if (prio == TIPC_MIN_LINK_PRI) { 305 + errstr = "cannot adjust to lower"; 306 + goto rejected; 309 307 } 308 + pr_warn("Bearer <%s>: trying with adjusted priority\n", name); 309 + prio--; 310 + bearer_id = 0; 311 + with_this_prio = 1; 310 312 } 313 + 311 314 if (bearer_id >= MAX_BEARERS) { 312 - pr_warn("Bearer <%s> rejected, bearer limit reached (%u)\n", 313 - name, MAX_BEARERS); 314 - return -EINVAL; 315 + errstr = "max 3 bearers permitted"; 316 + goto rejected; 315 317 } 316 318 317 319 b = kzalloc(sizeof(*b), GFP_ATOMIC); ··· 324 322 b->media = m; 325 323 res = m->enable_media(net, b, attr); 326 324 if (res) { 327 - pr_warn("Bearer <%s> rejected, enable failure (%d)\n", 328 - name, -res); 329 325 kfree(b); 330 - return -EINVAL; 326 + errstr = "failed to enable media"; 327 + goto rejected; 331 328 } 332 329 333 330 b->identity = bearer_id; ··· 334 333 b->window = m->window; 335 334 b->domain = disc_domain; 336 335 b->net_plane = bearer_id + 'A'; 337 - b->priority = priority; 336 + b->priority = prio; 338 337 test_and_set_bit_lock(0, &b->up); 339 338 340 339 res = tipc_disc_create(net, b, &b->bcast_addr, &skb); 341 340 if (res) { 342 341 bearer_disable(net, b); 343 - pr_warn("Bearer <%s> rejected, discovery object creation failed\n", 344 - name); 345 - return -EINVAL; 342 + kfree(b); 343 + errstr = "failed to create discoverer"; 344 + goto rejected; 346 345 } 347 346 348 347 rcu_assign_pointer(tn->bearer_list[bearer_id], b); ··· 354 353 return -ENOMEM; 355 354 } 356 355 357 - pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n", 358 - name, 359 - tipc_addr_string_fill(addr_string, disc_domain), priority); 356 + tipc_addr_string_fill(addr_string, disc_domain); 357 + pr_info("Enabled bearer <%s>, discovery scope %s, priority %u\n", 358 + name, addr_string, prio); 359 + return res; 360 + rejected: 361 + pr_warn("Bearer <%s> rejected, %s\n", name, errstr); 360 362 return res; 361 363 } 362 364