diff options
| -rw-r--r-- | net/core/net_namespace.c | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 2c2eb1b629b1..10608dd1489f 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
| @@ -213,14 +213,13 @@ static void rtnl_net_notifyid(struct net *net, int cmd, int id); | |||
| 213 | */ | 213 | */ |
| 214 | int peernet2id_alloc(struct net *net, struct net *peer) | 214 | int peernet2id_alloc(struct net *net, struct net *peer) |
| 215 | { | 215 | { |
| 216 | unsigned long flags; | ||
| 217 | bool alloc; | 216 | bool alloc; |
| 218 | int id; | 217 | int id; |
| 219 | 218 | ||
| 220 | spin_lock_irqsave(&net->nsid_lock, flags); | 219 | spin_lock_bh(&net->nsid_lock); |
| 221 | alloc = atomic_read(&peer->count) == 0 ? false : true; | 220 | alloc = atomic_read(&peer->count) == 0 ? false : true; |
| 222 | id = __peernet2id_alloc(net, peer, &alloc); | 221 | id = __peernet2id_alloc(net, peer, &alloc); |
| 223 | spin_unlock_irqrestore(&net->nsid_lock, flags); | 222 | spin_unlock_bh(&net->nsid_lock); |
| 224 | if (alloc && id >= 0) | 223 | if (alloc && id >= 0) |
| 225 | rtnl_net_notifyid(net, RTM_NEWNSID, id); | 224 | rtnl_net_notifyid(net, RTM_NEWNSID, id); |
| 226 | return id; | 225 | return id; |
| @@ -230,12 +229,11 @@ EXPORT_SYMBOL(peernet2id_alloc); | |||
| 230 | /* This function returns, if assigned, the id of a peer netns. */ | 229 | /* This function returns, if assigned, the id of a peer netns. */ |
| 231 | int peernet2id(struct net *net, struct net *peer) | 230 | int peernet2id(struct net *net, struct net *peer) |
| 232 | { | 231 | { |
| 233 | unsigned long flags; | ||
| 234 | int id; | 232 | int id; |
| 235 | 233 | ||
| 236 | spin_lock_irqsave(&net->nsid_lock, flags); | 234 | spin_lock_bh(&net->nsid_lock); |
| 237 | id = __peernet2id(net, peer); | 235 | id = __peernet2id(net, peer); |
| 238 | spin_unlock_irqrestore(&net->nsid_lock, flags); | 236 | spin_unlock_bh(&net->nsid_lock); |
| 239 | return id; | 237 | return id; |
| 240 | } | 238 | } |
| 241 | 239 | ||
| @@ -249,18 +247,17 @@ bool peernet_has_id(struct net *net, struct net *peer) | |||
| 249 | 247 | ||
| 250 | struct net *get_net_ns_by_id(struct net *net, int id) | 248 | struct net *get_net_ns_by_id(struct net *net, int id) |
| 251 | { | 249 | { |
| 252 | unsigned long flags; | ||
| 253 | struct net *peer; | 250 | struct net *peer; |
| 254 | 251 | ||
| 255 | if (id < 0) | 252 | if (id < 0) |
| 256 | return NULL; | 253 | return NULL; |
| 257 | 254 | ||
| 258 | rcu_read_lock(); | 255 | rcu_read_lock(); |
| 259 | spin_lock_irqsave(&net->nsid_lock, flags); | 256 | spin_lock_bh(&net->nsid_lock); |
| 260 | peer = idr_find(&net->netns_ids, id); | 257 | peer = idr_find(&net->netns_ids, id); |
| 261 | if (peer) | 258 | if (peer) |
| 262 | get_net(peer); | 259 | get_net(peer); |
| 263 | spin_unlock_irqrestore(&net->nsid_lock, flags); | 260 | spin_unlock_bh(&net->nsid_lock); |
| 264 | rcu_read_unlock(); | 261 | rcu_read_unlock(); |
| 265 | 262 | ||
| 266 | return peer; | 263 | return peer; |
| @@ -404,17 +401,17 @@ static void cleanup_net(struct work_struct *work) | |||
| 404 | for_each_net(tmp) { | 401 | for_each_net(tmp) { |
| 405 | int id; | 402 | int id; |
| 406 | 403 | ||
| 407 | spin_lock_irq(&tmp->nsid_lock); | 404 | spin_lock_bh(&tmp->nsid_lock); |
| 408 | id = __peernet2id(tmp, net); | 405 | id = __peernet2id(tmp, net); |
| 409 | if (id >= 0) | 406 | if (id >= 0) |
| 410 | idr_remove(&tmp->netns_ids, id); | 407 | idr_remove(&tmp->netns_ids, id); |
| 411 | spin_unlock_irq(&tmp->nsid_lock); | 408 | spin_unlock_bh(&tmp->nsid_lock); |
| 412 | if (id >= 0) | 409 | if (id >= 0) |
| 413 | rtnl_net_notifyid(tmp, RTM_DELNSID, id); | 410 | rtnl_net_notifyid(tmp, RTM_DELNSID, id); |
| 414 | } | 411 | } |
| 415 | spin_lock_irq(&net->nsid_lock); | 412 | spin_lock_bh(&net->nsid_lock); |
| 416 | idr_destroy(&net->netns_ids); | 413 | idr_destroy(&net->netns_ids); |
| 417 | spin_unlock_irq(&net->nsid_lock); | 414 | spin_unlock_bh(&net->nsid_lock); |
| 418 | 415 | ||
| 419 | } | 416 | } |
| 420 | rtnl_unlock(); | 417 | rtnl_unlock(); |
| @@ -542,7 +539,6 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 542 | { | 539 | { |
| 543 | struct net *net = sock_net(skb->sk); | 540 | struct net *net = sock_net(skb->sk); |
| 544 | struct nlattr *tb[NETNSA_MAX + 1]; | 541 | struct nlattr *tb[NETNSA_MAX + 1]; |
| 545 | unsigned long flags; | ||
| 546 | struct net *peer; | 542 | struct net *peer; |
| 547 | int nsid, err; | 543 | int nsid, err; |
| 548 | 544 | ||
| @@ -563,15 +559,15 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 563 | if (IS_ERR(peer)) | 559 | if (IS_ERR(peer)) |
| 564 | return PTR_ERR(peer); | 560 | return PTR_ERR(peer); |
| 565 | 561 | ||
| 566 | spin_lock_irqsave(&net->nsid_lock, flags); | 562 | spin_lock_bh(&net->nsid_lock); |
| 567 | if (__peernet2id(net, peer) >= 0) { | 563 | if (__peernet2id(net, peer) >= 0) { |
| 568 | spin_unlock_irqrestore(&net->nsid_lock, flags); | 564 | spin_unlock_bh(&net->nsid_lock); |
| 569 | err = -EEXIST; | 565 | err = -EEXIST; |
| 570 | goto out; | 566 | goto out; |
| 571 | } | 567 | } |
| 572 | 568 | ||
| 573 | err = alloc_netid(net, peer, nsid); | 569 | err = alloc_netid(net, peer, nsid); |
| 574 | spin_unlock_irqrestore(&net->nsid_lock, flags); | 570 | spin_unlock_bh(&net->nsid_lock); |
| 575 | if (err >= 0) { | 571 | if (err >= 0) { |
| 576 | rtnl_net_notifyid(net, RTM_NEWNSID, err); | 572 | rtnl_net_notifyid(net, RTM_NEWNSID, err); |
| 577 | err = 0; | 573 | err = 0; |
| @@ -693,11 +689,10 @@ static int rtnl_net_dumpid(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 693 | .idx = 0, | 689 | .idx = 0, |
| 694 | .s_idx = cb->args[0], | 690 | .s_idx = cb->args[0], |
| 695 | }; | 691 | }; |
| 696 | unsigned long flags; | ||
| 697 | 692 | ||
| 698 | spin_lock_irqsave(&net->nsid_lock, flags); | 693 | spin_lock_bh(&net->nsid_lock); |
| 699 | idr_for_each(&net->netns_ids, rtnl_net_dumpid_one, &net_cb); | 694 | idr_for_each(&net->netns_ids, rtnl_net_dumpid_one, &net_cb); |
| 700 | spin_unlock_irqrestore(&net->nsid_lock, flags); | 695 | spin_unlock_bh(&net->nsid_lock); |
| 701 | 696 | ||
| 702 | cb->args[0] = net_cb.idx; | 697 | cb->args[0] = net_cb.idx; |
| 703 | return skb->len; | 698 | return skb->len; |
