diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/core/net_namespace.c | 24 | ||||
| -rw-r--r-- | net/core/rtnetlink.c | 4 | ||||
| -rw-r--r-- | net/ipv4/ipmr.c | 2 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 2 | ||||
| -rw-r--r-- | net/ipv6/ip6mr.c | 2 | ||||
| -rw-r--r-- | net/ipv6/ndisc.c | 9 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 13 | ||||
| -rw-r--r-- | net/iucv/af_iucv.c | 4 | ||||
| -rw-r--r-- | net/mac80211/agg-rx.c | 8 | ||||
| -rw-r--r-- | net/mac80211/rx.c | 7 | ||||
| -rw-r--r-- | net/mac80211/sta_info.h | 2 | ||||
| -rw-r--r-- | net/openvswitch/vport.c | 4 | ||||
| -rw-r--r-- | net/sunrpc/clnt.c | 4 | ||||
| -rw-r--r-- | net/sunrpc/debugfs.c | 52 | ||||
| -rw-r--r-- | net/sunrpc/sunrpc_syms.c | 7 | ||||
| -rw-r--r-- | net/sunrpc/xprt.c | 7 | ||||
| -rw-r--r-- | net/tipc/core.c | 2 |
17 files changed, 87 insertions, 66 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index cb5290b8c428..5221f975a4cc 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
| @@ -349,7 +349,7 @@ static LIST_HEAD(cleanup_list); /* Must hold cleanup_list_lock to touch */ | |||
| 349 | static void cleanup_net(struct work_struct *work) | 349 | static void cleanup_net(struct work_struct *work) |
| 350 | { | 350 | { |
| 351 | const struct pernet_operations *ops; | 351 | const struct pernet_operations *ops; |
| 352 | struct net *net, *tmp; | 352 | struct net *net, *tmp, *peer; |
| 353 | struct list_head net_kill_list; | 353 | struct list_head net_kill_list; |
| 354 | LIST_HEAD(net_exit_list); | 354 | LIST_HEAD(net_exit_list); |
| 355 | 355 | ||
| @@ -365,14 +365,6 @@ static void cleanup_net(struct work_struct *work) | |||
| 365 | list_for_each_entry(net, &net_kill_list, cleanup_list) { | 365 | list_for_each_entry(net, &net_kill_list, cleanup_list) { |
| 366 | list_del_rcu(&net->list); | 366 | list_del_rcu(&net->list); |
| 367 | list_add_tail(&net->exit_list, &net_exit_list); | 367 | list_add_tail(&net->exit_list, &net_exit_list); |
| 368 | for_each_net(tmp) { | ||
| 369 | int id = __peernet2id(tmp, net, false); | ||
| 370 | |||
| 371 | if (id >= 0) | ||
| 372 | idr_remove(&tmp->netns_ids, id); | ||
| 373 | } | ||
| 374 | idr_destroy(&net->netns_ids); | ||
| 375 | |||
| 376 | } | 368 | } |
| 377 | rtnl_unlock(); | 369 | rtnl_unlock(); |
| 378 | 370 | ||
| @@ -398,12 +390,26 @@ static void cleanup_net(struct work_struct *work) | |||
| 398 | */ | 390 | */ |
| 399 | rcu_barrier(); | 391 | rcu_barrier(); |
| 400 | 392 | ||
| 393 | rtnl_lock(); | ||
| 401 | /* Finally it is safe to free my network namespace structure */ | 394 | /* Finally it is safe to free my network namespace structure */ |
| 402 | list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { | 395 | list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { |
| 396 | /* Unreference net from all peers (no need to loop over | ||
| 397 | * net_exit_list because idr_destroy() will be called for each | ||
| 398 | * element of this list. | ||
| 399 | */ | ||
| 400 | for_each_net(peer) { | ||
| 401 | int id = __peernet2id(peer, net, false); | ||
| 402 | |||
| 403 | if (id >= 0) | ||
| 404 | idr_remove(&peer->netns_ids, id); | ||
| 405 | } | ||
| 406 | idr_destroy(&net->netns_ids); | ||
| 407 | |||
| 403 | list_del_init(&net->exit_list); | 408 | list_del_init(&net->exit_list); |
| 404 | put_user_ns(net->user_ns); | 409 | put_user_ns(net->user_ns); |
| 405 | net_drop_ns(net); | 410 | net_drop_ns(net); |
| 406 | } | 411 | } |
| 412 | rtnl_unlock(); | ||
| 407 | } | 413 | } |
| 408 | static DECLARE_WORK(net_cleanup_work, cleanup_net); | 414 | static DECLARE_WORK(net_cleanup_work, cleanup_net); |
| 409 | 415 | ||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index ee0608bb3bc0..7ebed55b5f7d 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -1932,10 +1932,10 @@ static int rtnl_group_changelink(const struct sk_buff *skb, | |||
| 1932 | struct ifinfomsg *ifm, | 1932 | struct ifinfomsg *ifm, |
| 1933 | struct nlattr **tb) | 1933 | struct nlattr **tb) |
| 1934 | { | 1934 | { |
| 1935 | struct net_device *dev; | 1935 | struct net_device *dev, *aux; |
| 1936 | int err; | 1936 | int err; |
| 1937 | 1937 | ||
| 1938 | for_each_netdev(net, dev) { | 1938 | for_each_netdev_safe(net, dev, aux) { |
| 1939 | if (dev->group == group) { | 1939 | if (dev->group == group) { |
| 1940 | err = do_setlink(skb, dev, ifm, tb, NULL, 0); | 1940 | err = do_setlink(skb, dev, ifm, tb, NULL, 0); |
| 1941 | if (err < 0) | 1941 | if (err < 0) |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 9d78427652d2..92825443fad6 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
| @@ -268,7 +268,7 @@ static int __net_init ipmr_rules_init(struct net *net) | |||
| 268 | return 0; | 268 | return 0; |
| 269 | 269 | ||
| 270 | err2: | 270 | err2: |
| 271 | kfree(mrt); | 271 | ipmr_free_table(mrt); |
| 272 | err1: | 272 | err1: |
| 273 | fib_rules_unregister(ops); | 273 | fib_rules_unregister(ops); |
| 274 | return err; | 274 | return err; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 5a2dfed4783b..f1756ee02207 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -1518,7 +1518,7 @@ void tcp_v4_early_demux(struct sk_buff *skb) | |||
| 1518 | skb->sk = sk; | 1518 | skb->sk = sk; |
| 1519 | skb->destructor = sock_edemux; | 1519 | skb->destructor = sock_edemux; |
| 1520 | if (sk->sk_state != TCP_TIME_WAIT) { | 1520 | if (sk->sk_state != TCP_TIME_WAIT) { |
| 1521 | struct dst_entry *dst = sk->sk_rx_dst; | 1521 | struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst); |
| 1522 | 1522 | ||
| 1523 | if (dst) | 1523 | if (dst) |
| 1524 | dst = dst_check(dst, 0); | 1524 | dst = dst_check(dst, 0); |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 34b682617f50..52028f449a89 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
| @@ -252,7 +252,7 @@ static int __net_init ip6mr_rules_init(struct net *net) | |||
| 252 | return 0; | 252 | return 0; |
| 253 | 253 | ||
| 254 | err2: | 254 | err2: |
| 255 | kfree(mrt); | 255 | ip6mr_free_table(mrt); |
| 256 | err1: | 256 | err1: |
| 257 | fib_rules_unregister(ops); | 257 | fib_rules_unregister(ops); |
| 258 | return err; | 258 | return err; |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 471ed24aabae..14ecdaf06bf7 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -1218,7 +1218,14 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
| 1218 | if (rt) | 1218 | if (rt) |
| 1219 | rt6_set_expires(rt, jiffies + (HZ * lifetime)); | 1219 | rt6_set_expires(rt, jiffies + (HZ * lifetime)); |
| 1220 | if (ra_msg->icmph.icmp6_hop_limit) { | 1220 | if (ra_msg->icmph.icmp6_hop_limit) { |
| 1221 | in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit; | 1221 | /* Only set hop_limit on the interface if it is higher than |
| 1222 | * the current hop_limit. | ||
| 1223 | */ | ||
| 1224 | if (in6_dev->cnf.hop_limit < ra_msg->icmph.icmp6_hop_limit) { | ||
| 1225 | in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit; | ||
| 1226 | } else { | ||
| 1227 | ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than current\n"); | ||
| 1228 | } | ||
| 1222 | if (rt) | 1229 | if (rt) |
| 1223 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, | 1230 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, |
| 1224 | ra_msg->icmph.icmp6_hop_limit); | 1231 | ra_msg->icmph.icmp6_hop_limit); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5d46832c6f72..1f5e62229aaa 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -1411,6 +1411,15 @@ static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr, | |||
| 1411 | TCP_SKB_CB(skb)->sacked = 0; | 1411 | TCP_SKB_CB(skb)->sacked = 0; |
| 1412 | } | 1412 | } |
| 1413 | 1413 | ||
| 1414 | static void tcp_v6_restore_cb(struct sk_buff *skb) | ||
| 1415 | { | ||
| 1416 | /* We need to move header back to the beginning if xfrm6_policy_check() | ||
| 1417 | * and tcp_v6_fill_cb() are going to be called again. | ||
| 1418 | */ | ||
| 1419 | memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6, | ||
| 1420 | sizeof(struct inet6_skb_parm)); | ||
| 1421 | } | ||
| 1422 | |||
| 1414 | static int tcp_v6_rcv(struct sk_buff *skb) | 1423 | static int tcp_v6_rcv(struct sk_buff *skb) |
| 1415 | { | 1424 | { |
| 1416 | const struct tcphdr *th; | 1425 | const struct tcphdr *th; |
| @@ -1543,6 +1552,7 @@ do_time_wait: | |||
| 1543 | inet_twsk_deschedule(tw, &tcp_death_row); | 1552 | inet_twsk_deschedule(tw, &tcp_death_row); |
| 1544 | inet_twsk_put(tw); | 1553 | inet_twsk_put(tw); |
| 1545 | sk = sk2; | 1554 | sk = sk2; |
| 1555 | tcp_v6_restore_cb(skb); | ||
| 1546 | goto process; | 1556 | goto process; |
| 1547 | } | 1557 | } |
| 1548 | /* Fall through to ACK */ | 1558 | /* Fall through to ACK */ |
| @@ -1551,6 +1561,7 @@ do_time_wait: | |||
| 1551 | tcp_v6_timewait_ack(sk, skb); | 1561 | tcp_v6_timewait_ack(sk, skb); |
| 1552 | break; | 1562 | break; |
| 1553 | case TCP_TW_RST: | 1563 | case TCP_TW_RST: |
| 1564 | tcp_v6_restore_cb(skb); | ||
| 1554 | goto no_tcp_socket; | 1565 | goto no_tcp_socket; |
| 1555 | case TCP_TW_SUCCESS: | 1566 | case TCP_TW_SUCCESS: |
| 1556 | ; | 1567 | ; |
| @@ -1585,7 +1596,7 @@ static void tcp_v6_early_demux(struct sk_buff *skb) | |||
| 1585 | skb->sk = sk; | 1596 | skb->sk = sk; |
| 1586 | skb->destructor = sock_edemux; | 1597 | skb->destructor = sock_edemux; |
| 1587 | if (sk->sk_state != TCP_TIME_WAIT) { | 1598 | if (sk->sk_state != TCP_TIME_WAIT) { |
| 1588 | struct dst_entry *dst = sk->sk_rx_dst; | 1599 | struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst); |
| 1589 | 1600 | ||
| 1590 | if (dst) | 1601 | if (dst) |
| 1591 | dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); | 1602 | dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); |
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 2e9953b2db84..53d931172088 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
| @@ -1114,10 +1114,8 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1114 | noblock, &err); | 1114 | noblock, &err); |
| 1115 | else | 1115 | else |
| 1116 | skb = sock_alloc_send_skb(sk, len, noblock, &err); | 1116 | skb = sock_alloc_send_skb(sk, len, noblock, &err); |
| 1117 | if (!skb) { | 1117 | if (!skb) |
| 1118 | err = -ENOMEM; | ||
| 1119 | goto out; | 1118 | goto out; |
| 1120 | } | ||
| 1121 | if (iucv->transport == AF_IUCV_TRANS_HIPER) | 1119 | if (iucv->transport == AF_IUCV_TRANS_HIPER) |
| 1122 | skb_reserve(skb, sizeof(struct af_iucv_trans_hdr) + ETH_HLEN); | 1120 | skb_reserve(skb, sizeof(struct af_iucv_trans_hdr) + ETH_HLEN); |
| 1123 | if (memcpy_from_msg(skb_put(skb, len), msg, len)) { | 1121 | if (memcpy_from_msg(skb_put(skb, len), msg, len)) { |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index a48bad468880..7702978a4c99 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
| @@ -49,8 +49,6 @@ static void ieee80211_free_tid_rx(struct rcu_head *h) | |||
| 49 | container_of(h, struct tid_ampdu_rx, rcu_head); | 49 | container_of(h, struct tid_ampdu_rx, rcu_head); |
| 50 | int i; | 50 | int i; |
| 51 | 51 | ||
| 52 | del_timer_sync(&tid_rx->reorder_timer); | ||
| 53 | |||
| 54 | for (i = 0; i < tid_rx->buf_size; i++) | 52 | for (i = 0; i < tid_rx->buf_size; i++) |
| 55 | __skb_queue_purge(&tid_rx->reorder_buf[i]); | 53 | __skb_queue_purge(&tid_rx->reorder_buf[i]); |
| 56 | kfree(tid_rx->reorder_buf); | 54 | kfree(tid_rx->reorder_buf); |
| @@ -93,6 +91,12 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
| 93 | 91 | ||
| 94 | del_timer_sync(&tid_rx->session_timer); | 92 | del_timer_sync(&tid_rx->session_timer); |
| 95 | 93 | ||
| 94 | /* make sure ieee80211_sta_reorder_release() doesn't re-arm the timer */ | ||
| 95 | spin_lock_bh(&tid_rx->reorder_lock); | ||
| 96 | tid_rx->removed = true; | ||
| 97 | spin_unlock_bh(&tid_rx->reorder_lock); | ||
| 98 | del_timer_sync(&tid_rx->reorder_timer); | ||
| 99 | |||
| 96 | call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx); | 100 | call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx); |
| 97 | } | 101 | } |
| 98 | 102 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 944bdc04e913..1eb730bf8752 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -873,9 +873,10 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, | |||
| 873 | 873 | ||
| 874 | set_release_timer: | 874 | set_release_timer: |
| 875 | 875 | ||
| 876 | mod_timer(&tid_agg_rx->reorder_timer, | 876 | if (!tid_agg_rx->removed) |
| 877 | tid_agg_rx->reorder_time[j] + 1 + | 877 | mod_timer(&tid_agg_rx->reorder_timer, |
| 878 | HT_RX_REORDER_BUF_TIMEOUT); | 878 | tid_agg_rx->reorder_time[j] + 1 + |
| 879 | HT_RX_REORDER_BUF_TIMEOUT); | ||
| 879 | } else { | 880 | } else { |
| 880 | del_timer(&tid_agg_rx->reorder_timer); | 881 | del_timer(&tid_agg_rx->reorder_timer); |
| 881 | } | 882 | } |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 925e68fe64c7..fb0fc1302a58 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
| @@ -175,6 +175,7 @@ struct tid_ampdu_tx { | |||
| 175 | * @reorder_lock: serializes access to reorder buffer, see below. | 175 | * @reorder_lock: serializes access to reorder buffer, see below. |
| 176 | * @auto_seq: used for offloaded BA sessions to automatically pick head_seq_and | 176 | * @auto_seq: used for offloaded BA sessions to automatically pick head_seq_and |
| 177 | * and ssn. | 177 | * and ssn. |
| 178 | * @removed: this session is removed (but might have been found due to RCU) | ||
| 178 | * | 179 | * |
| 179 | * This structure's lifetime is managed by RCU, assignments to | 180 | * This structure's lifetime is managed by RCU, assignments to |
| 180 | * the array holding it must hold the aggregation mutex. | 181 | * the array holding it must hold the aggregation mutex. |
| @@ -199,6 +200,7 @@ struct tid_ampdu_rx { | |||
| 199 | u16 timeout; | 200 | u16 timeout; |
| 200 | u8 dialog_token; | 201 | u8 dialog_token; |
| 201 | bool auto_seq; | 202 | bool auto_seq; |
| 203 | bool removed; | ||
| 202 | }; | 204 | }; |
| 203 | 205 | ||
| 204 | /** | 206 | /** |
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index ec2954ffc690..067a3fff1d2c 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c | |||
| @@ -274,10 +274,8 @@ void ovs_vport_del(struct vport *vport) | |||
| 274 | ASSERT_OVSL(); | 274 | ASSERT_OVSL(); |
| 275 | 275 | ||
| 276 | hlist_del_rcu(&vport->hash_node); | 276 | hlist_del_rcu(&vport->hash_node); |
| 277 | |||
| 278 | vport->ops->destroy(vport); | ||
| 279 | |||
| 280 | module_put(vport->ops->owner); | 277 | module_put(vport->ops->owner); |
| 278 | vport->ops->destroy(vport); | ||
| 281 | } | 279 | } |
| 282 | 280 | ||
| 283 | /** | 281 | /** |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 612aa73bbc60..e6ce1517367f 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -303,9 +303,7 @@ static int rpc_client_register(struct rpc_clnt *clnt, | |||
| 303 | struct super_block *pipefs_sb; | 303 | struct super_block *pipefs_sb; |
| 304 | int err; | 304 | int err; |
| 305 | 305 | ||
| 306 | err = rpc_clnt_debugfs_register(clnt); | 306 | rpc_clnt_debugfs_register(clnt); |
| 307 | if (err) | ||
| 308 | return err; | ||
| 309 | 307 | ||
| 310 | pipefs_sb = rpc_get_sb_net(net); | 308 | pipefs_sb = rpc_get_sb_net(net); |
| 311 | if (pipefs_sb) { | 309 | if (pipefs_sb) { |
diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c index e811f390f9f6..82962f7e6e88 100644 --- a/net/sunrpc/debugfs.c +++ b/net/sunrpc/debugfs.c | |||
| @@ -129,48 +129,52 @@ static const struct file_operations tasks_fops = { | |||
| 129 | .release = tasks_release, | 129 | .release = tasks_release, |
| 130 | }; | 130 | }; |
| 131 | 131 | ||
| 132 | int | 132 | void |
| 133 | rpc_clnt_debugfs_register(struct rpc_clnt *clnt) | 133 | rpc_clnt_debugfs_register(struct rpc_clnt *clnt) |
| 134 | { | 134 | { |
| 135 | int len, err; | 135 | int len; |
| 136 | char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */ | 136 | char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */ |
| 137 | struct rpc_xprt *xprt; | ||
| 137 | 138 | ||
| 138 | /* Already registered? */ | 139 | /* Already registered? */ |
| 139 | if (clnt->cl_debugfs) | 140 | if (clnt->cl_debugfs || !rpc_clnt_dir) |
| 140 | return 0; | 141 | return; |
| 141 | 142 | ||
| 142 | len = snprintf(name, sizeof(name), "%x", clnt->cl_clid); | 143 | len = snprintf(name, sizeof(name), "%x", clnt->cl_clid); |
| 143 | if (len >= sizeof(name)) | 144 | if (len >= sizeof(name)) |
| 144 | return -EINVAL; | 145 | return; |
| 145 | 146 | ||
| 146 | /* make the per-client dir */ | 147 | /* make the per-client dir */ |
| 147 | clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir); | 148 | clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir); |
| 148 | if (!clnt->cl_debugfs) | 149 | if (!clnt->cl_debugfs) |
| 149 | return -ENOMEM; | 150 | return; |
| 150 | 151 | ||
| 151 | /* make tasks file */ | 152 | /* make tasks file */ |
| 152 | err = -ENOMEM; | ||
| 153 | if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs, | 153 | if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs, |
| 154 | clnt, &tasks_fops)) | 154 | clnt, &tasks_fops)) |
| 155 | goto out_err; | 155 | goto out_err; |
| 156 | 156 | ||
| 157 | err = -EINVAL; | ||
| 158 | rcu_read_lock(); | 157 | rcu_read_lock(); |
| 158 | xprt = rcu_dereference(clnt->cl_xprt); | ||
| 159 | /* no "debugfs" dentry? Don't bother with the symlink. */ | ||
| 160 | if (!xprt->debugfs) { | ||
| 161 | rcu_read_unlock(); | ||
| 162 | return; | ||
| 163 | } | ||
| 159 | len = snprintf(name, sizeof(name), "../../rpc_xprt/%s", | 164 | len = snprintf(name, sizeof(name), "../../rpc_xprt/%s", |
| 160 | rcu_dereference(clnt->cl_xprt)->debugfs->d_name.name); | 165 | xprt->debugfs->d_name.name); |
| 161 | rcu_read_unlock(); | 166 | rcu_read_unlock(); |
| 167 | |||
| 162 | if (len >= sizeof(name)) | 168 | if (len >= sizeof(name)) |
| 163 | goto out_err; | 169 | goto out_err; |
| 164 | 170 | ||
| 165 | err = -ENOMEM; | ||
| 166 | if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name)) | 171 | if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name)) |
| 167 | goto out_err; | 172 | goto out_err; |
| 168 | 173 | ||
| 169 | return 0; | 174 | return; |
| 170 | out_err: | 175 | out_err: |
| 171 | debugfs_remove_recursive(clnt->cl_debugfs); | 176 | debugfs_remove_recursive(clnt->cl_debugfs); |
| 172 | clnt->cl_debugfs = NULL; | 177 | clnt->cl_debugfs = NULL; |
| 173 | return err; | ||
| 174 | } | 178 | } |
| 175 | 179 | ||
| 176 | void | 180 | void |
| @@ -226,33 +230,33 @@ static const struct file_operations xprt_info_fops = { | |||
| 226 | .release = xprt_info_release, | 230 | .release = xprt_info_release, |
| 227 | }; | 231 | }; |
| 228 | 232 | ||
| 229 | int | 233 | void |
| 230 | rpc_xprt_debugfs_register(struct rpc_xprt *xprt) | 234 | rpc_xprt_debugfs_register(struct rpc_xprt *xprt) |
| 231 | { | 235 | { |
| 232 | int len, id; | 236 | int len, id; |
| 233 | static atomic_t cur_id; | 237 | static atomic_t cur_id; |
| 234 | char name[9]; /* 8 hex digits + NULL term */ | 238 | char name[9]; /* 8 hex digits + NULL term */ |
| 235 | 239 | ||
| 240 | if (!rpc_xprt_dir) | ||
| 241 | return; | ||
| 242 | |||
| 236 | id = (unsigned int)atomic_inc_return(&cur_id); | 243 | id = (unsigned int)atomic_inc_return(&cur_id); |
| 237 | 244 | ||
| 238 | len = snprintf(name, sizeof(name), "%x", id); | 245 | len = snprintf(name, sizeof(name), "%x", id); |
| 239 | if (len >= sizeof(name)) | 246 | if (len >= sizeof(name)) |
| 240 | return -EINVAL; | 247 | return; |
| 241 | 248 | ||
| 242 | /* make the per-client dir */ | 249 | /* make the per-client dir */ |
| 243 | xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir); | 250 | xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir); |
| 244 | if (!xprt->debugfs) | 251 | if (!xprt->debugfs) |
| 245 | return -ENOMEM; | 252 | return; |
| 246 | 253 | ||
| 247 | /* make tasks file */ | 254 | /* make tasks file */ |
| 248 | if (!debugfs_create_file("info", S_IFREG | S_IRUSR, xprt->debugfs, | 255 | if (!debugfs_create_file("info", S_IFREG | S_IRUSR, xprt->debugfs, |
| 249 | xprt, &xprt_info_fops)) { | 256 | xprt, &xprt_info_fops)) { |
| 250 | debugfs_remove_recursive(xprt->debugfs); | 257 | debugfs_remove_recursive(xprt->debugfs); |
| 251 | xprt->debugfs = NULL; | 258 | xprt->debugfs = NULL; |
| 252 | return -ENOMEM; | ||
| 253 | } | 259 | } |
| 254 | |||
| 255 | return 0; | ||
| 256 | } | 260 | } |
| 257 | 261 | ||
| 258 | void | 262 | void |
| @@ -266,14 +270,17 @@ void __exit | |||
| 266 | sunrpc_debugfs_exit(void) | 270 | sunrpc_debugfs_exit(void) |
| 267 | { | 271 | { |
| 268 | debugfs_remove_recursive(topdir); | 272 | debugfs_remove_recursive(topdir); |
| 273 | topdir = NULL; | ||
| 274 | rpc_clnt_dir = NULL; | ||
| 275 | rpc_xprt_dir = NULL; | ||
| 269 | } | 276 | } |
| 270 | 277 | ||
| 271 | int __init | 278 | void __init |
| 272 | sunrpc_debugfs_init(void) | 279 | sunrpc_debugfs_init(void) |
| 273 | { | 280 | { |
| 274 | topdir = debugfs_create_dir("sunrpc", NULL); | 281 | topdir = debugfs_create_dir("sunrpc", NULL); |
| 275 | if (!topdir) | 282 | if (!topdir) |
| 276 | goto out; | 283 | return; |
| 277 | 284 | ||
| 278 | rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir); | 285 | rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir); |
| 279 | if (!rpc_clnt_dir) | 286 | if (!rpc_clnt_dir) |
| @@ -283,10 +290,9 @@ sunrpc_debugfs_init(void) | |||
| 283 | if (!rpc_xprt_dir) | 290 | if (!rpc_xprt_dir) |
| 284 | goto out_remove; | 291 | goto out_remove; |
| 285 | 292 | ||
| 286 | return 0; | 293 | return; |
| 287 | out_remove: | 294 | out_remove: |
| 288 | debugfs_remove_recursive(topdir); | 295 | debugfs_remove_recursive(topdir); |
| 289 | topdir = NULL; | 296 | topdir = NULL; |
| 290 | out: | 297 | rpc_clnt_dir = NULL; |
| 291 | return -ENOMEM; | ||
| 292 | } | 298 | } |
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index e37fbed87956..ee5d3d253102 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c | |||
| @@ -98,10 +98,7 @@ init_sunrpc(void) | |||
| 98 | if (err) | 98 | if (err) |
| 99 | goto out4; | 99 | goto out4; |
| 100 | 100 | ||
| 101 | err = sunrpc_debugfs_init(); | 101 | sunrpc_debugfs_init(); |
| 102 | if (err) | ||
| 103 | goto out5; | ||
| 104 | |||
| 105 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) | 102 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
| 106 | rpc_register_sysctl(); | 103 | rpc_register_sysctl(); |
| 107 | #endif | 104 | #endif |
| @@ -109,8 +106,6 @@ init_sunrpc(void) | |||
| 109 | init_socket_xprt(); /* clnt sock transport */ | 106 | init_socket_xprt(); /* clnt sock transport */ |
| 110 | return 0; | 107 | return 0; |
| 111 | 108 | ||
| 112 | out5: | ||
| 113 | unregister_rpc_pipefs(); | ||
| 114 | out4: | 109 | out4: |
| 115 | unregister_pernet_subsys(&sunrpc_net_ops); | 110 | unregister_pernet_subsys(&sunrpc_net_ops); |
| 116 | out3: | 111 | out3: |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index e3015aede0d9..9949722d99ce 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
| @@ -1331,7 +1331,6 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net) | |||
| 1331 | */ | 1331 | */ |
| 1332 | struct rpc_xprt *xprt_create_transport(struct xprt_create *args) | 1332 | struct rpc_xprt *xprt_create_transport(struct xprt_create *args) |
| 1333 | { | 1333 | { |
| 1334 | int err; | ||
| 1335 | struct rpc_xprt *xprt; | 1334 | struct rpc_xprt *xprt; |
| 1336 | struct xprt_class *t; | 1335 | struct xprt_class *t; |
| 1337 | 1336 | ||
| @@ -1372,11 +1371,7 @@ found: | |||
| 1372 | return ERR_PTR(-ENOMEM); | 1371 | return ERR_PTR(-ENOMEM); |
| 1373 | } | 1372 | } |
| 1374 | 1373 | ||
| 1375 | err = rpc_xprt_debugfs_register(xprt); | 1374 | rpc_xprt_debugfs_register(xprt); |
| 1376 | if (err) { | ||
| 1377 | xprt_destroy(xprt); | ||
| 1378 | return ERR_PTR(err); | ||
| 1379 | } | ||
| 1380 | 1375 | ||
| 1381 | dprintk("RPC: created transport %p with %u slots\n", xprt, | 1376 | dprintk("RPC: created transport %p with %u slots\n", xprt, |
| 1382 | xprt->max_reqs); | 1377 | xprt->max_reqs); |
diff --git a/net/tipc/core.c b/net/tipc/core.c index 935205e6bcfe..be1c9fa60b09 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
| @@ -152,11 +152,11 @@ out_netlink: | |||
| 152 | static void __exit tipc_exit(void) | 152 | static void __exit tipc_exit(void) |
| 153 | { | 153 | { |
| 154 | tipc_bearer_cleanup(); | 154 | tipc_bearer_cleanup(); |
| 155 | unregister_pernet_subsys(&tipc_net_ops); | ||
| 155 | tipc_netlink_stop(); | 156 | tipc_netlink_stop(); |
| 156 | tipc_netlink_compat_stop(); | 157 | tipc_netlink_compat_stop(); |
| 157 | tipc_socket_stop(); | 158 | tipc_socket_stop(); |
| 158 | tipc_unregister_sysctl(); | 159 | tipc_unregister_sysctl(); |
| 159 | unregister_pernet_subsys(&tipc_net_ops); | ||
| 160 | 160 | ||
| 161 | pr_info("Deactivated\n"); | 161 | pr_info("Deactivated\n"); |
| 162 | } | 162 | } |
