diff options
Diffstat (limited to 'net')
71 files changed, 561 insertions, 587 deletions
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 0117b9fb8480..de7a9f532edc 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
@@ -110,7 +110,7 @@ static struct p9_req_t *p9_lookup_tag(struct virtio_chan *c, u16 tag) | |||
110 | } | 110 | } |
111 | for (count = old_max; count < c->max_tag; count++) { | 111 | for (count = old_max; count < c->max_tag; count++) { |
112 | c->reqs[count].status = REQ_STATUS_IDLE; | 112 | c->reqs[count].status = REQ_STATUS_IDLE; |
113 | c->reqs[count].wq = kmalloc(sizeof(wait_queue_t), | 113 | c->reqs[count].wq = kmalloc(sizeof(wait_queue_head_t), |
114 | GFP_ATOMIC); | 114 | GFP_ATOMIC); |
115 | if (!c->reqs[count].wq) { | 115 | if (!c->reqs[count].wq) { |
116 | printk(KERN_ERR "Couldn't grow tag array\n"); | 116 | printk(KERN_ERR "Couldn't grow tag array\n"); |
@@ -183,8 +183,7 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data, | |||
183 | sg_set_buf(&sg[index++], data, s); | 183 | sg_set_buf(&sg[index++], data, s); |
184 | count -= s; | 184 | count -= s; |
185 | data += s; | 185 | data += s; |
186 | if (index > limit) | 186 | BUG_ON(index > limit); |
187 | BUG(); | ||
188 | } | 187 | } |
189 | 188 | ||
190 | return index-start; | 189 | return index-start; |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 8fc64e3150a2..48bfcc741f25 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -510,11 +510,7 @@ ax25_cb *ax25_create_cb(void) | |||
510 | skb_queue_head_init(&ax25->ack_queue); | 510 | skb_queue_head_init(&ax25->ack_queue); |
511 | skb_queue_head_init(&ax25->reseq_queue); | 511 | skb_queue_head_init(&ax25->reseq_queue); |
512 | 512 | ||
513 | init_timer(&ax25->timer); | 513 | ax25_setup_timers(ax25); |
514 | init_timer(&ax25->t1timer); | ||
515 | init_timer(&ax25->t2timer); | ||
516 | init_timer(&ax25->t3timer); | ||
517 | init_timer(&ax25->idletimer); | ||
518 | 514 | ||
519 | ax25_fillin_cb(ax25, NULL); | 515 | ax25_fillin_cb(ax25, NULL); |
520 | 516 | ||
@@ -1928,12 +1924,10 @@ static int ax25_info_show(struct seq_file *seq, void *v) | |||
1928 | ax25->paclen); | 1924 | ax25->paclen); |
1929 | 1925 | ||
1930 | if (ax25->sk != NULL) { | 1926 | if (ax25->sk != NULL) { |
1931 | bh_lock_sock(ax25->sk); | 1927 | seq_printf(seq, " %d %d %lu\n", |
1932 | seq_printf(seq," %d %d %ld\n", | ||
1933 | atomic_read(&ax25->sk->sk_wmem_alloc), | 1928 | atomic_read(&ax25->sk->sk_wmem_alloc), |
1934 | atomic_read(&ax25->sk->sk_rmem_alloc), | 1929 | atomic_read(&ax25->sk->sk_rmem_alloc), |
1935 | ax25->sk->sk_socket != NULL ? SOCK_INODE(ax25->sk->sk_socket)->i_ino : 0L); | 1930 | sock_i_ino(ax25->sk)); |
1936 | bh_unlock_sock(ax25->sk); | ||
1937 | } else { | 1931 | } else { |
1938 | seq_puts(seq, " * * *\n"); | 1932 | seq_puts(seq, " * * *\n"); |
1939 | } | 1933 | } |
diff --git a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c index 528c874d9828..a7a0e0c9698b 100644 --- a/net/ax25/ax25_dev.c +++ b/net/ax25/ax25_dev.c | |||
@@ -82,7 +82,7 @@ void ax25_dev_device_up(struct net_device *dev) | |||
82 | ax25_dev->values[AX25_VALUES_DS_TIMEOUT]= AX25_DEF_DS_TIMEOUT; | 82 | ax25_dev->values[AX25_VALUES_DS_TIMEOUT]= AX25_DEF_DS_TIMEOUT; |
83 | 83 | ||
84 | #if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER) | 84 | #if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER) |
85 | init_timer(&ax25_dev->dama.slave_timer); | 85 | ax25_ds_setup_timer(ax25_dev); |
86 | #endif | 86 | #endif |
87 | 87 | ||
88 | spin_lock_bh(&ax25_dev_lock); | 88 | spin_lock_bh(&ax25_dev_lock); |
diff --git a/net/ax25/ax25_ds_timer.c b/net/ax25/ax25_ds_timer.c index c4e3b025d21c..2ce79df00680 100644 --- a/net/ax25/ax25_ds_timer.c +++ b/net/ax25/ax25_ds_timer.c | |||
@@ -40,13 +40,10 @@ static void ax25_ds_timeout(unsigned long); | |||
40 | * 1/10th of a second. | 40 | * 1/10th of a second. |
41 | */ | 41 | */ |
42 | 42 | ||
43 | static void ax25_ds_add_timer(ax25_dev *ax25_dev) | 43 | void ax25_ds_setup_timer(ax25_dev *ax25_dev) |
44 | { | 44 | { |
45 | struct timer_list *t = &ax25_dev->dama.slave_timer; | 45 | setup_timer(&ax25_dev->dama.slave_timer, ax25_ds_timeout, |
46 | t->data = (unsigned long) ax25_dev; | 46 | (unsigned long)ax25_dev); |
47 | t->function = &ax25_ds_timeout; | ||
48 | t->expires = jiffies + HZ; | ||
49 | add_timer(t); | ||
50 | } | 47 | } |
51 | 48 | ||
52 | void ax25_ds_del_timer(ax25_dev *ax25_dev) | 49 | void ax25_ds_del_timer(ax25_dev *ax25_dev) |
@@ -60,10 +57,9 @@ void ax25_ds_set_timer(ax25_dev *ax25_dev) | |||
60 | if (ax25_dev == NULL) /* paranoia */ | 57 | if (ax25_dev == NULL) /* paranoia */ |
61 | return; | 58 | return; |
62 | 59 | ||
63 | del_timer(&ax25_dev->dama.slave_timer); | ||
64 | ax25_dev->dama.slave_timeout = | 60 | ax25_dev->dama.slave_timeout = |
65 | msecs_to_jiffies(ax25_dev->values[AX25_VALUES_DS_TIMEOUT]) / 10; | 61 | msecs_to_jiffies(ax25_dev->values[AX25_VALUES_DS_TIMEOUT]) / 10; |
66 | ax25_ds_add_timer(ax25_dev); | 62 | mod_timer(&ax25_dev->dama.slave_timer, jiffies + HZ); |
67 | } | 63 | } |
68 | 64 | ||
69 | /* | 65 | /* |
diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c index 92b517af7260..bf706f83a5c9 100644 --- a/net/ax25/ax25_out.c +++ b/net/ax25/ax25_out.c | |||
@@ -117,6 +117,12 @@ void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb) | |||
117 | unsigned char *p; | 117 | unsigned char *p; |
118 | int frontlen, len, fragno, ka9qfrag, first = 1; | 118 | int frontlen, len, fragno, ka9qfrag, first = 1; |
119 | 119 | ||
120 | if (paclen < 16) { | ||
121 | WARN_ON_ONCE(1); | ||
122 | kfree_skb(skb); | ||
123 | return; | ||
124 | } | ||
125 | |||
120 | if ((skb->len - 1) > paclen) { | 126 | if ((skb->len - 1) > paclen) { |
121 | if (*skb->data == AX25_P_TEXT) { | 127 | if (*skb->data == AX25_P_TEXT) { |
122 | skb_pull(skb, 1); /* skip PID */ | 128 | skb_pull(skb, 1); /* skip PID */ |
@@ -251,8 +257,6 @@ void ax25_kick(ax25_cb *ax25) | |||
251 | if (start == end) | 257 | if (start == end) |
252 | return; | 258 | return; |
253 | 259 | ||
254 | ax25->vs = start; | ||
255 | |||
256 | /* | 260 | /* |
257 | * Transmit data until either we're out of data to send or | 261 | * Transmit data until either we're out of data to send or |
258 | * the window is full. Send a poll on the final I frame if | 262 | * the window is full. Send a poll on the final I frame if |
@@ -261,8 +265,13 @@ void ax25_kick(ax25_cb *ax25) | |||
261 | 265 | ||
262 | /* | 266 | /* |
263 | * Dequeue the frame and copy it. | 267 | * Dequeue the frame and copy it. |
268 | * Check for race with ax25_clear_queues(). | ||
264 | */ | 269 | */ |
265 | skb = skb_dequeue(&ax25->write_queue); | 270 | skb = skb_dequeue(&ax25->write_queue); |
271 | if (!skb) | ||
272 | return; | ||
273 | |||
274 | ax25->vs = start; | ||
266 | 275 | ||
267 | do { | 276 | do { |
268 | if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { | 277 | if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { |
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index 38c7f3087ec3..8672cd84fdf9 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c | |||
@@ -45,7 +45,7 @@ void ax25_rt_device_down(struct net_device *dev) | |||
45 | { | 45 | { |
46 | ax25_route *s, *t, *ax25_rt; | 46 | ax25_route *s, *t, *ax25_rt; |
47 | 47 | ||
48 | write_lock(&ax25_route_lock); | 48 | write_lock_bh(&ax25_route_lock); |
49 | ax25_rt = ax25_route_list; | 49 | ax25_rt = ax25_route_list; |
50 | while (ax25_rt != NULL) { | 50 | while (ax25_rt != NULL) { |
51 | s = ax25_rt; | 51 | s = ax25_rt; |
@@ -68,7 +68,7 @@ void ax25_rt_device_down(struct net_device *dev) | |||
68 | } | 68 | } |
69 | } | 69 | } |
70 | } | 70 | } |
71 | write_unlock(&ax25_route_lock); | 71 | write_unlock_bh(&ax25_route_lock); |
72 | } | 72 | } |
73 | 73 | ||
74 | static int __must_check ax25_rt_add(struct ax25_routes_struct *route) | 74 | static int __must_check ax25_rt_add(struct ax25_routes_struct *route) |
@@ -82,7 +82,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) | |||
82 | if (route->digi_count > AX25_MAX_DIGIS) | 82 | if (route->digi_count > AX25_MAX_DIGIS) |
83 | return -EINVAL; | 83 | return -EINVAL; |
84 | 84 | ||
85 | write_lock(&ax25_route_lock); | 85 | write_lock_bh(&ax25_route_lock); |
86 | 86 | ||
87 | ax25_rt = ax25_route_list; | 87 | ax25_rt = ax25_route_list; |
88 | while (ax25_rt != NULL) { | 88 | while (ax25_rt != NULL) { |
@@ -92,7 +92,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) | |||
92 | ax25_rt->digipeat = NULL; | 92 | ax25_rt->digipeat = NULL; |
93 | if (route->digi_count != 0) { | 93 | if (route->digi_count != 0) { |
94 | if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { | 94 | if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { |
95 | write_unlock(&ax25_route_lock); | 95 | write_unlock_bh(&ax25_route_lock); |
96 | return -ENOMEM; | 96 | return -ENOMEM; |
97 | } | 97 | } |
98 | ax25_rt->digipeat->lastrepeat = -1; | 98 | ax25_rt->digipeat->lastrepeat = -1; |
@@ -102,14 +102,14 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) | |||
102 | ax25_rt->digipeat->calls[i] = route->digi_addr[i]; | 102 | ax25_rt->digipeat->calls[i] = route->digi_addr[i]; |
103 | } | 103 | } |
104 | } | 104 | } |
105 | write_unlock(&ax25_route_lock); | 105 | write_unlock_bh(&ax25_route_lock); |
106 | return 0; | 106 | return 0; |
107 | } | 107 | } |
108 | ax25_rt = ax25_rt->next; | 108 | ax25_rt = ax25_rt->next; |
109 | } | 109 | } |
110 | 110 | ||
111 | if ((ax25_rt = kmalloc(sizeof(ax25_route), GFP_ATOMIC)) == NULL) { | 111 | if ((ax25_rt = kmalloc(sizeof(ax25_route), GFP_ATOMIC)) == NULL) { |
112 | write_unlock(&ax25_route_lock); | 112 | write_unlock_bh(&ax25_route_lock); |
113 | return -ENOMEM; | 113 | return -ENOMEM; |
114 | } | 114 | } |
115 | 115 | ||
@@ -120,7 +120,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) | |||
120 | ax25_rt->ip_mode = ' '; | 120 | ax25_rt->ip_mode = ' '; |
121 | if (route->digi_count != 0) { | 121 | if (route->digi_count != 0) { |
122 | if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { | 122 | if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { |
123 | write_unlock(&ax25_route_lock); | 123 | write_unlock_bh(&ax25_route_lock); |
124 | kfree(ax25_rt); | 124 | kfree(ax25_rt); |
125 | return -ENOMEM; | 125 | return -ENOMEM; |
126 | } | 126 | } |
@@ -133,7 +133,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) | |||
133 | } | 133 | } |
134 | ax25_rt->next = ax25_route_list; | 134 | ax25_rt->next = ax25_route_list; |
135 | ax25_route_list = ax25_rt; | 135 | ax25_route_list = ax25_rt; |
136 | write_unlock(&ax25_route_lock); | 136 | write_unlock_bh(&ax25_route_lock); |
137 | 137 | ||
138 | return 0; | 138 | return 0; |
139 | } | 139 | } |
@@ -152,7 +152,7 @@ static int ax25_rt_del(struct ax25_routes_struct *route) | |||
152 | if ((ax25_dev = ax25_addr_ax25dev(&route->port_addr)) == NULL) | 152 | if ((ax25_dev = ax25_addr_ax25dev(&route->port_addr)) == NULL) |
153 | return -EINVAL; | 153 | return -EINVAL; |
154 | 154 | ||
155 | write_lock(&ax25_route_lock); | 155 | write_lock_bh(&ax25_route_lock); |
156 | 156 | ||
157 | ax25_rt = ax25_route_list; | 157 | ax25_rt = ax25_route_list; |
158 | while (ax25_rt != NULL) { | 158 | while (ax25_rt != NULL) { |
@@ -174,7 +174,7 @@ static int ax25_rt_del(struct ax25_routes_struct *route) | |||
174 | } | 174 | } |
175 | } | 175 | } |
176 | } | 176 | } |
177 | write_unlock(&ax25_route_lock); | 177 | write_unlock_bh(&ax25_route_lock); |
178 | 178 | ||
179 | return 0; | 179 | return 0; |
180 | } | 180 | } |
@@ -188,7 +188,7 @@ static int ax25_rt_opt(struct ax25_route_opt_struct *rt_option) | |||
188 | if ((ax25_dev = ax25_addr_ax25dev(&rt_option->port_addr)) == NULL) | 188 | if ((ax25_dev = ax25_addr_ax25dev(&rt_option->port_addr)) == NULL) |
189 | return -EINVAL; | 189 | return -EINVAL; |
190 | 190 | ||
191 | write_lock(&ax25_route_lock); | 191 | write_lock_bh(&ax25_route_lock); |
192 | 192 | ||
193 | ax25_rt = ax25_route_list; | 193 | ax25_rt = ax25_route_list; |
194 | while (ax25_rt != NULL) { | 194 | while (ax25_rt != NULL) { |
@@ -216,7 +216,7 @@ static int ax25_rt_opt(struct ax25_route_opt_struct *rt_option) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | out: | 218 | out: |
219 | write_unlock(&ax25_route_lock); | 219 | write_unlock_bh(&ax25_route_lock); |
220 | return err; | 220 | return err; |
221 | } | 221 | } |
222 | 222 | ||
@@ -492,7 +492,7 @@ void __exit ax25_rt_free(void) | |||
492 | { | 492 | { |
493 | ax25_route *s, *ax25_rt = ax25_route_list; | 493 | ax25_route *s, *ax25_rt = ax25_route_list; |
494 | 494 | ||
495 | write_lock(&ax25_route_lock); | 495 | write_lock_bh(&ax25_route_lock); |
496 | while (ax25_rt != NULL) { | 496 | while (ax25_rt != NULL) { |
497 | s = ax25_rt; | 497 | s = ax25_rt; |
498 | ax25_rt = ax25_rt->next; | 498 | ax25_rt = ax25_rt->next; |
@@ -500,5 +500,5 @@ void __exit ax25_rt_free(void) | |||
500 | kfree(s->digipeat); | 500 | kfree(s->digipeat); |
501 | kfree(s); | 501 | kfree(s); |
502 | } | 502 | } |
503 | write_unlock(&ax25_route_lock); | 503 | write_unlock_bh(&ax25_route_lock); |
504 | } | 504 | } |
diff --git a/net/ax25/ax25_timer.c b/net/ax25/ax25_timer.c index 72594867fab6..db29ea71e80a 100644 --- a/net/ax25/ax25_timer.c +++ b/net/ax25/ax25_timer.c | |||
@@ -40,63 +40,45 @@ static void ax25_t2timer_expiry(unsigned long); | |||
40 | static void ax25_t3timer_expiry(unsigned long); | 40 | static void ax25_t3timer_expiry(unsigned long); |
41 | static void ax25_idletimer_expiry(unsigned long); | 41 | static void ax25_idletimer_expiry(unsigned long); |
42 | 42 | ||
43 | void ax25_start_heartbeat(ax25_cb *ax25) | 43 | void ax25_setup_timers(ax25_cb *ax25) |
44 | { | 44 | { |
45 | del_timer(&ax25->timer); | 45 | setup_timer(&ax25->timer, ax25_heartbeat_expiry, (unsigned long)ax25); |
46 | 46 | setup_timer(&ax25->t1timer, ax25_t1timer_expiry, (unsigned long)ax25); | |
47 | ax25->timer.data = (unsigned long)ax25; | 47 | setup_timer(&ax25->t2timer, ax25_t2timer_expiry, (unsigned long)ax25); |
48 | ax25->timer.function = &ax25_heartbeat_expiry; | 48 | setup_timer(&ax25->t3timer, ax25_t3timer_expiry, (unsigned long)ax25); |
49 | ax25->timer.expires = jiffies + 5 * HZ; | 49 | setup_timer(&ax25->idletimer, ax25_idletimer_expiry, |
50 | (unsigned long)ax25); | ||
51 | } | ||
50 | 52 | ||
51 | add_timer(&ax25->timer); | 53 | void ax25_start_heartbeat(ax25_cb *ax25) |
54 | { | ||
55 | mod_timer(&ax25->timer, jiffies + 5 * HZ); | ||
52 | } | 56 | } |
53 | 57 | ||
54 | void ax25_start_t1timer(ax25_cb *ax25) | 58 | void ax25_start_t1timer(ax25_cb *ax25) |
55 | { | 59 | { |
56 | del_timer(&ax25->t1timer); | 60 | mod_timer(&ax25->t1timer, jiffies + ax25->t1); |
57 | |||
58 | ax25->t1timer.data = (unsigned long)ax25; | ||
59 | ax25->t1timer.function = &ax25_t1timer_expiry; | ||
60 | ax25->t1timer.expires = jiffies + ax25->t1; | ||
61 | |||
62 | add_timer(&ax25->t1timer); | ||
63 | } | 61 | } |
64 | 62 | ||
65 | void ax25_start_t2timer(ax25_cb *ax25) | 63 | void ax25_start_t2timer(ax25_cb *ax25) |
66 | { | 64 | { |
67 | del_timer(&ax25->t2timer); | 65 | mod_timer(&ax25->t2timer, jiffies + ax25->t2); |
68 | |||
69 | ax25->t2timer.data = (unsigned long)ax25; | ||
70 | ax25->t2timer.function = &ax25_t2timer_expiry; | ||
71 | ax25->t2timer.expires = jiffies + ax25->t2; | ||
72 | |||
73 | add_timer(&ax25->t2timer); | ||
74 | } | 66 | } |
75 | 67 | ||
76 | void ax25_start_t3timer(ax25_cb *ax25) | 68 | void ax25_start_t3timer(ax25_cb *ax25) |
77 | { | 69 | { |
78 | del_timer(&ax25->t3timer); | 70 | if (ax25->t3 > 0) |
79 | 71 | mod_timer(&ax25->t3timer, jiffies + ax25->t3); | |
80 | if (ax25->t3 > 0) { | 72 | else |
81 | ax25->t3timer.data = (unsigned long)ax25; | 73 | del_timer(&ax25->t3timer); |
82 | ax25->t3timer.function = &ax25_t3timer_expiry; | ||
83 | ax25->t3timer.expires = jiffies + ax25->t3; | ||
84 | |||
85 | add_timer(&ax25->t3timer); | ||
86 | } | ||
87 | } | 74 | } |
88 | 75 | ||
89 | void ax25_start_idletimer(ax25_cb *ax25) | 76 | void ax25_start_idletimer(ax25_cb *ax25) |
90 | { | 77 | { |
91 | del_timer(&ax25->idletimer); | 78 | if (ax25->idle > 0) |
92 | 79 | mod_timer(&ax25->idletimer, jiffies + ax25->idle); | |
93 | if (ax25->idle > 0) { | 80 | else |
94 | ax25->idletimer.data = (unsigned long)ax25; | 81 | del_timer(&ax25->idletimer); |
95 | ax25->idletimer.function = &ax25_idletimer_expiry; | ||
96 | ax25->idletimer.expires = jiffies + ax25->idle; | ||
97 | |||
98 | add_timer(&ax25->idletimer); | ||
99 | } | ||
100 | } | 82 | } |
101 | 83 | ||
102 | void ax25_stop_heartbeat(ax25_cb *ax25) | 84 | void ax25_stop_heartbeat(ax25_cb *ax25) |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 5fc7be206f62..f8880261da0e 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -260,7 +260,6 @@ int hci_conn_del(struct hci_conn *conn) | |||
260 | tasklet_enable(&hdev->tx_task); | 260 | tasklet_enable(&hdev->tx_task); |
261 | skb_queue_purge(&conn->data_q); | 261 | skb_queue_purge(&conn->data_q); |
262 | hci_conn_del_sysfs(conn); | 262 | hci_conn_del_sysfs(conn); |
263 | hci_dev_put(hdev); | ||
264 | 263 | ||
265 | return 0; | 264 | return 0; |
266 | } | 265 | } |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 372b0d3b75a8..930b58e7149a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | /* Bluetooth HCI core. */ | 25 | /* Bluetooth HCI core. */ |
26 | 26 | ||
27 | #include <linux/jiffies.h> | ||
27 | #include <linux/module.h> | 28 | #include <linux/module.h> |
28 | #include <linux/kmod.h> | 29 | #include <linux/kmod.h> |
29 | 30 | ||
@@ -1321,7 +1322,7 @@ static inline void hci_sched_acl(struct hci_dev *hdev) | |||
1321 | if (!test_bit(HCI_RAW, &hdev->flags)) { | 1322 | if (!test_bit(HCI_RAW, &hdev->flags)) { |
1322 | /* ACL tx timeout must be longer than maximum | 1323 | /* ACL tx timeout must be longer than maximum |
1323 | * link supervision timeout (40.9 seconds) */ | 1324 | * link supervision timeout (40.9 seconds) */ |
1324 | if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45)) | 1325 | if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45)) |
1325 | hci_acl_tx_to(hdev); | 1326 | hci_acl_tx_to(hdev); |
1326 | } | 1327 | } |
1327 | 1328 | ||
@@ -1543,7 +1544,7 @@ static void hci_cmd_task(unsigned long arg) | |||
1543 | 1544 | ||
1544 | BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); | 1545 | BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); |
1545 | 1546 | ||
1546 | if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) { | 1547 | if (!atomic_read(&hdev->cmd_cnt) && time_after(jiffies, hdev->cmd_last_tx + HZ)) { |
1547 | BT_ERR("%s command tx timeout", hdev->name); | 1548 | BT_ERR("%s command tx timeout", hdev->name); |
1548 | atomic_set(&hdev->cmd_cnt, 1); | 1549 | atomic_set(&hdev->cmd_cnt, 1); |
1549 | } | 1550 | } |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index e13cf5ef144c..84360c117d4e 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -320,28 +320,34 @@ void hci_conn_add_sysfs(struct hci_conn *conn) | |||
320 | queue_work(btaddconn, &conn->work); | 320 | queue_work(btaddconn, &conn->work); |
321 | } | 321 | } |
322 | 322 | ||
323 | /* | ||
324 | * The rfcomm tty device will possibly retain even when conn | ||
325 | * is down, and sysfs doesn't support move zombie device, | ||
326 | * so we should move the device before conn device is destroyed. | ||
327 | */ | ||
323 | static int __match_tty(struct device *dev, void *data) | 328 | static int __match_tty(struct device *dev, void *data) |
324 | { | 329 | { |
325 | /* The rfcomm tty device will possibly retain even when conn | 330 | return !strncmp(dev->bus_id, "rfcomm", 6); |
326 | * is down, and sysfs doesn't support move zombie device, | ||
327 | * so we should move the device before conn device is destroyed. | ||
328 | * Due to the only child device of hci_conn dev is rfcomm | ||
329 | * tty_dev, here just return 1 | ||
330 | */ | ||
331 | return 1; | ||
332 | } | 331 | } |
333 | 332 | ||
334 | static void del_conn(struct work_struct *work) | 333 | static void del_conn(struct work_struct *work) |
335 | { | 334 | { |
336 | struct device *dev; | ||
337 | struct hci_conn *conn = container_of(work, struct hci_conn, work); | 335 | struct hci_conn *conn = container_of(work, struct hci_conn, work); |
336 | struct hci_dev *hdev = conn->hdev; | ||
337 | |||
338 | while (1) { | ||
339 | struct device *dev; | ||
338 | 340 | ||
339 | while (dev = device_find_child(&conn->dev, NULL, __match_tty)) { | 341 | dev = device_find_child(&conn->dev, NULL, __match_tty); |
342 | if (!dev) | ||
343 | break; | ||
340 | device_move(dev, NULL); | 344 | device_move(dev, NULL); |
341 | put_device(dev); | 345 | put_device(dev); |
342 | } | 346 | } |
347 | |||
343 | device_del(&conn->dev); | 348 | device_del(&conn->dev); |
344 | put_device(&conn->dev); | 349 | put_device(&conn->dev); |
350 | hci_dev_put(hdev); | ||
345 | } | 351 | } |
346 | 352 | ||
347 | void hci_conn_del_sysfs(struct hci_conn *conn) | 353 | void hci_conn_del_sysfs(struct hci_conn *conn) |
diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c index e700cbf634c2..ca64c1cc1b47 100644 --- a/net/bridge/netfilter/ebt_dnat.c +++ b/net/bridge/netfilter/ebt_dnat.c | |||
@@ -20,8 +20,8 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr, | |||
20 | { | 20 | { |
21 | const struct ebt_nat_info *info = data; | 21 | const struct ebt_nat_info *info = data; |
22 | 22 | ||
23 | if (skb_make_writable(skb, 0)) | 23 | if (!skb_make_writable(skb, 0)) |
24 | return NF_DROP; | 24 | return EBT_DROP; |
25 | 25 | ||
26 | memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN); | 26 | memcpy(eth_hdr(skb)->h_dest, info->mac, ETH_ALEN); |
27 | return info->target; | 27 | return info->target; |
diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c index bfdf2fb60b1f..b8afe850cf1e 100644 --- a/net/bridge/netfilter/ebt_redirect.c +++ b/net/bridge/netfilter/ebt_redirect.c | |||
@@ -21,8 +21,8 @@ static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr, | |||
21 | { | 21 | { |
22 | const struct ebt_redirect_info *info = data; | 22 | const struct ebt_redirect_info *info = data; |
23 | 23 | ||
24 | if (skb_make_writable(skb, 0)) | 24 | if (!skb_make_writable(skb, 0)) |
25 | return NF_DROP; | 25 | return EBT_DROP; |
26 | 26 | ||
27 | if (hooknr != NF_BR_BROUTING) | 27 | if (hooknr != NF_BR_BROUTING) |
28 | memcpy(eth_hdr(skb)->h_dest, | 28 | memcpy(eth_hdr(skb)->h_dest, |
diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c index e252dabbb143..5425333dda03 100644 --- a/net/bridge/netfilter/ebt_snat.c +++ b/net/bridge/netfilter/ebt_snat.c | |||
@@ -22,8 +22,8 @@ static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr, | |||
22 | { | 22 | { |
23 | const struct ebt_nat_info *info = data; | 23 | const struct ebt_nat_info *info = data; |
24 | 24 | ||
25 | if (skb_make_writable(skb, 0)) | 25 | if (!skb_make_writable(skb, 0)) |
26 | return NF_DROP; | 26 | return EBT_DROP; |
27 | 27 | ||
28 | memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN); | 28 | memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN); |
29 | if (!(info->target & NAT_ARP_BIT) && | 29 | if (!(info->target & NAT_ARP_BIT) && |
diff --git a/net/core/dev.c b/net/core/dev.c index b3e19ae57f95..fcdf03cf3b3f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1071,8 +1071,6 @@ int dev_close(struct net_device *dev) | |||
1071 | */ | 1071 | */ |
1072 | call_netdevice_notifiers(NETDEV_GOING_DOWN, dev); | 1072 | call_netdevice_notifiers(NETDEV_GOING_DOWN, dev); |
1073 | 1073 | ||
1074 | dev_deactivate(dev); | ||
1075 | |||
1076 | clear_bit(__LINK_STATE_START, &dev->state); | 1074 | clear_bit(__LINK_STATE_START, &dev->state); |
1077 | 1075 | ||
1078 | /* Synchronize to scheduled poll. We cannot touch poll list, | 1076 | /* Synchronize to scheduled poll. We cannot touch poll list, |
@@ -1083,6 +1081,8 @@ int dev_close(struct net_device *dev) | |||
1083 | */ | 1081 | */ |
1084 | smp_mb__after_clear_bit(); /* Commit netif_running(). */ | 1082 | smp_mb__after_clear_bit(); /* Commit netif_running(). */ |
1085 | 1083 | ||
1084 | dev_deactivate(dev); | ||
1085 | |||
1086 | /* | 1086 | /* |
1087 | * Call the device specific close. This cannot fail. | 1087 | * Call the device specific close. This cannot fail. |
1088 | * Only if device is UP | 1088 | * Only if device is UP |
@@ -2900,7 +2900,7 @@ int __dev_addr_add(struct dev_addr_list **list, int *count, | |||
2900 | } | 2900 | } |
2901 | } | 2901 | } |
2902 | 2902 | ||
2903 | da = kmalloc(sizeof(*da), GFP_ATOMIC); | 2903 | da = kzalloc(sizeof(*da), GFP_ATOMIC); |
2904 | if (da == NULL) | 2904 | if (da == NULL) |
2905 | return -ENOMEM; | 2905 | return -ENOMEM; |
2906 | memcpy(da->da_addr, addr, alen); | 2906 | memcpy(da->da_addr, addr, alen); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index a16cf1ec5e5e..2328acbd16cd 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -358,11 +358,12 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, | |||
358 | { | 358 | { |
359 | struct neighbour *n; | 359 | struct neighbour *n; |
360 | int key_len = tbl->key_len; | 360 | int key_len = tbl->key_len; |
361 | u32 hash_val = tbl->hash(pkey, dev); | 361 | u32 hash_val; |
362 | 362 | ||
363 | NEIGH_CACHE_STAT_INC(tbl, lookups); | 363 | NEIGH_CACHE_STAT_INC(tbl, lookups); |
364 | 364 | ||
365 | read_lock_bh(&tbl->lock); | 365 | read_lock_bh(&tbl->lock); |
366 | hash_val = tbl->hash(pkey, dev); | ||
366 | for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { | 367 | for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { |
367 | if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) { | 368 | if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) { |
368 | neigh_hold(n); | 369 | neigh_hold(n); |
@@ -379,11 +380,12 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, | |||
379 | { | 380 | { |
380 | struct neighbour *n; | 381 | struct neighbour *n; |
381 | int key_len = tbl->key_len; | 382 | int key_len = tbl->key_len; |
382 | u32 hash_val = tbl->hash(pkey, NULL); | 383 | u32 hash_val; |
383 | 384 | ||
384 | NEIGH_CACHE_STAT_INC(tbl, lookups); | 385 | NEIGH_CACHE_STAT_INC(tbl, lookups); |
385 | 386 | ||
386 | read_lock_bh(&tbl->lock); | 387 | read_lock_bh(&tbl->lock); |
388 | hash_val = tbl->hash(pkey, NULL); | ||
387 | for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { | 389 | for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { |
388 | if (!memcmp(n->primary_key, pkey, key_len) && | 390 | if (!memcmp(n->primary_key, pkey, key_len) && |
389 | (net == n->dev->nd_net)) { | 391 | (net == n->dev->nd_net)) { |
@@ -507,6 +509,7 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, | |||
507 | if (tbl->pconstructor && tbl->pconstructor(n)) { | 509 | if (tbl->pconstructor && tbl->pconstructor(n)) { |
508 | if (dev) | 510 | if (dev) |
509 | dev_put(dev); | 511 | dev_put(dev); |
512 | release_net(net); | ||
510 | kfree(n); | 513 | kfree(n); |
511 | n = NULL; | 514 | n = NULL; |
512 | goto out; | 515 | goto out; |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 61ac8d06292c..2bd9c5f7627d 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -689,10 +689,12 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { | |||
689 | [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN }, | 689 | [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN }, |
690 | [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, | 690 | [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, |
691 | [IFLA_MTU] = { .type = NLA_U32 }, | 691 | [IFLA_MTU] = { .type = NLA_U32 }, |
692 | [IFLA_LINK] = { .type = NLA_U32 }, | ||
692 | [IFLA_TXQLEN] = { .type = NLA_U32 }, | 693 | [IFLA_TXQLEN] = { .type = NLA_U32 }, |
693 | [IFLA_WEIGHT] = { .type = NLA_U32 }, | 694 | [IFLA_WEIGHT] = { .type = NLA_U32 }, |
694 | [IFLA_OPERSTATE] = { .type = NLA_U8 }, | 695 | [IFLA_OPERSTATE] = { .type = NLA_U8 }, |
695 | [IFLA_LINKMODE] = { .type = NLA_U8 }, | 696 | [IFLA_LINKMODE] = { .type = NLA_U8 }, |
697 | [IFLA_LINKINFO] = { .type = NLA_NESTED }, | ||
696 | [IFLA_NET_NS_PID] = { .type = NLA_U32 }, | 698 | [IFLA_NET_NS_PID] = { .type = NLA_U32 }, |
697 | }; | 699 | }; |
698 | 700 | ||
@@ -720,6 +722,21 @@ static struct net *get_net_ns_by_pid(pid_t pid) | |||
720 | return net; | 722 | return net; |
721 | } | 723 | } |
722 | 724 | ||
725 | static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) | ||
726 | { | ||
727 | if (dev) { | ||
728 | if (tb[IFLA_ADDRESS] && | ||
729 | nla_len(tb[IFLA_ADDRESS]) < dev->addr_len) | ||
730 | return -EINVAL; | ||
731 | |||
732 | if (tb[IFLA_BROADCAST] && | ||
733 | nla_len(tb[IFLA_BROADCAST]) < dev->addr_len) | ||
734 | return -EINVAL; | ||
735 | } | ||
736 | |||
737 | return 0; | ||
738 | } | ||
739 | |||
723 | static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | 740 | static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, |
724 | struct nlattr **tb, char *ifname, int modified) | 741 | struct nlattr **tb, char *ifname, int modified) |
725 | { | 742 | { |
@@ -892,12 +909,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
892 | goto errout; | 909 | goto errout; |
893 | } | 910 | } |
894 | 911 | ||
895 | if (tb[IFLA_ADDRESS] && | 912 | if ((err = validate_linkmsg(dev, tb)) < 0) |
896 | nla_len(tb[IFLA_ADDRESS]) < dev->addr_len) | ||
897 | goto errout_dev; | ||
898 | |||
899 | if (tb[IFLA_BROADCAST] && | ||
900 | nla_len(tb[IFLA_BROADCAST]) < dev->addr_len) | ||
901 | goto errout_dev; | 913 | goto errout_dev; |
902 | 914 | ||
903 | err = do_setlink(dev, ifm, tb, ifname, 0); | 915 | err = do_setlink(dev, ifm, tb, ifname, 0); |
@@ -1018,6 +1030,9 @@ replay: | |||
1018 | else | 1030 | else |
1019 | dev = NULL; | 1031 | dev = NULL; |
1020 | 1032 | ||
1033 | if ((err = validate_linkmsg(dev, tb)) < 0) | ||
1034 | return err; | ||
1035 | |||
1021 | if (tb[IFLA_LINKINFO]) { | 1036 | if (tb[IFLA_LINKINFO]) { |
1022 | err = nla_parse_nested(linkinfo, IFLA_INFO_MAX, | 1037 | err = nla_parse_nested(linkinfo, IFLA_INFO_MAX, |
1023 | tb[IFLA_LINKINFO], ifla_info_policy); | 1038 | tb[IFLA_LINKINFO], ifla_info_policy); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index cfc07dac636c..0d0fd28a9041 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -2106,11 +2106,10 @@ int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, | |||
2106 | /** | 2106 | /** |
2107 | * skb_pull_rcsum - pull skb and update receive checksum | 2107 | * skb_pull_rcsum - pull skb and update receive checksum |
2108 | * @skb: buffer to update | 2108 | * @skb: buffer to update |
2109 | * @start: start of data before pull | ||
2110 | * @len: length of data pulled | 2109 | * @len: length of data pulled |
2111 | * | 2110 | * |
2112 | * This function performs an skb_pull on the packet and updates | 2111 | * This function performs an skb_pull on the packet and updates |
2113 | * update the CHECKSUM_COMPLETE checksum. It should be used on | 2112 | * the CHECKSUM_COMPLETE checksum. It should be used on |
2114 | * receive path processing instead of skb_pull unless you know | 2113 | * receive path processing instead of skb_pull unless you know |
2115 | * that the checksum difference is zero (e.g., a valid IP header) | 2114 | * that the checksum difference is zero (e.g., a valid IP header) |
2116 | * or you are setting ip_summed to CHECKSUM_NONE. | 2115 | * or you are setting ip_summed to CHECKSUM_NONE. |
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index 9d4555ec0b59..8219b7e0968d 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c | |||
@@ -96,7 +96,7 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb) | |||
96 | 96 | ||
97 | ah->reserved = 0; | 97 | ah->reserved = 0; |
98 | ah->spi = x->id.spi; | 98 | ah->spi = x->id.spi; |
99 | ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq); | 99 | ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output); |
100 | 100 | ||
101 | spin_lock_bh(&x->lock); | 101 | spin_lock_bh(&x->lock); |
102 | err = ah_mac_digest(ahp, skb, ah->auth_data); | 102 | err = ah_mac_digest(ahp, skb, ah->auth_data); |
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 258d17631b4b..091e6709f831 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -199,7 +199,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
199 | } | 199 | } |
200 | 200 | ||
201 | esph->spi = x->id.spi; | 201 | esph->spi = x->id.spi; |
202 | esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq); | 202 | esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output); |
203 | 203 | ||
204 | sg_init_table(sg, nfrags); | 204 | sg_init_table(sg, nfrags); |
205 | skb_to_sgvec(skb, sg, | 205 | skb_to_sgvec(skb, sg, |
@@ -210,7 +210,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
210 | aead_givcrypt_set_callback(req, 0, esp_output_done, skb); | 210 | aead_givcrypt_set_callback(req, 0, esp_output_done, skb); |
211 | aead_givcrypt_set_crypt(req, sg, sg, clen, iv); | 211 | aead_givcrypt_set_crypt(req, sg, sg, clen, iv); |
212 | aead_givcrypt_set_assoc(req, asg, sizeof(*esph)); | 212 | aead_givcrypt_set_assoc(req, asg, sizeof(*esph)); |
213 | aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq); | 213 | aead_givcrypt_set_giv(req, esph->enc_data, |
214 | XFRM_SKB_CB(skb)->seq.output); | ||
214 | 215 | ||
215 | ESP_SKB_CB(skb)->tmp = tmp; | 216 | ESP_SKB_CB(skb)->tmp = tmp; |
216 | err = crypto_aead_givencrypt(req); | 217 | err = crypto_aead_givencrypt(req); |
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 76b9c684cccd..8d58d85dfac6 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c | |||
@@ -372,7 +372,8 @@ static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key) | |||
372 | static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) | 372 | static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) |
373 | { | 373 | { |
374 | struct fn_hash *table = (struct fn_hash *) tb->tb_data; | 374 | struct fn_hash *table = (struct fn_hash *) tb->tb_data; |
375 | struct fib_node *new_f, *f; | 375 | struct fib_node *new_f = NULL; |
376 | struct fib_node *f; | ||
376 | struct fib_alias *fa, *new_fa; | 377 | struct fib_alias *fa, *new_fa; |
377 | struct fn_zone *fz; | 378 | struct fn_zone *fz; |
378 | struct fib_info *fi; | 379 | struct fib_info *fi; |
@@ -496,7 +497,6 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) | |||
496 | 497 | ||
497 | err = -ENOBUFS; | 498 | err = -ENOBUFS; |
498 | 499 | ||
499 | new_f = NULL; | ||
500 | if (!f) { | 500 | if (!f) { |
501 | new_f = kmem_cache_zalloc(fn_hash_kmem, GFP_KERNEL); | 501 | new_f = kmem_cache_zalloc(fn_hash_kmem, GFP_KERNEL); |
502 | if (new_f == NULL) | 502 | if (new_f == NULL) |
@@ -512,7 +512,7 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) | |||
512 | if (new_fa->fa_info != NULL) { | 512 | if (new_fa->fa_info != NULL) { |
513 | new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); | 513 | new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); |
514 | if (new_fa == NULL) | 514 | if (new_fa == NULL) |
515 | goto out_free_new_f; | 515 | goto out; |
516 | } | 516 | } |
517 | new_fa->fa_info = fi; | 517 | new_fa->fa_info = fi; |
518 | new_fa->fa_tos = tos; | 518 | new_fa->fa_tos = tos; |
@@ -540,9 +540,9 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) | |||
540 | &cfg->fc_nlinfo, 0); | 540 | &cfg->fc_nlinfo, 0); |
541 | return 0; | 541 | return 0; |
542 | 542 | ||
543 | out_free_new_f: | ||
544 | kmem_cache_free(fn_hash_kmem, new_f); | ||
545 | out: | 543 | out: |
544 | if (new_f) | ||
545 | kmem_cache_free(fn_hash_kmem, new_f); | ||
546 | fib_release_info(fi); | 546 | fib_release_info(fi); |
547 | return err; | 547 | return err; |
548 | } | 548 | } |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index f5fba3f71c06..1ff446d0fa8b 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -1762,11 +1762,9 @@ static struct leaf *trie_leafindex(struct trie *t, int index) | |||
1762 | { | 1762 | { |
1763 | struct leaf *l = trie_firstleaf(t); | 1763 | struct leaf *l = trie_firstleaf(t); |
1764 | 1764 | ||
1765 | while (index-- > 0) { | 1765 | while (l && index-- > 0) |
1766 | l = trie_nextleaf(l); | 1766 | l = trie_nextleaf(l); |
1767 | if (!l) | 1767 | |
1768 | break; | ||
1769 | } | ||
1770 | return l; | 1768 | return l; |
1771 | } | 1769 | } |
1772 | 1770 | ||
@@ -2461,6 +2459,84 @@ static const struct file_operations fib_trie_fops = { | |||
2461 | .release = seq_release_net, | 2459 | .release = seq_release_net, |
2462 | }; | 2460 | }; |
2463 | 2461 | ||
2462 | struct fib_route_iter { | ||
2463 | struct seq_net_private p; | ||
2464 | struct trie *main_trie; | ||
2465 | loff_t pos; | ||
2466 | t_key key; | ||
2467 | }; | ||
2468 | |||
2469 | static struct leaf *fib_route_get_idx(struct fib_route_iter *iter, loff_t pos) | ||
2470 | { | ||
2471 | struct leaf *l = NULL; | ||
2472 | struct trie *t = iter->main_trie; | ||
2473 | |||
2474 | /* use cache location of last found key */ | ||
2475 | if (iter->pos > 0 && pos >= iter->pos && (l = fib_find_node(t, iter->key))) | ||
2476 | pos -= iter->pos; | ||
2477 | else { | ||
2478 | iter->pos = 0; | ||
2479 | l = trie_firstleaf(t); | ||
2480 | } | ||
2481 | |||
2482 | while (l && pos-- > 0) { | ||
2483 | iter->pos++; | ||
2484 | l = trie_nextleaf(l); | ||
2485 | } | ||
2486 | |||
2487 | if (l) | ||
2488 | iter->key = pos; /* remember it */ | ||
2489 | else | ||
2490 | iter->pos = 0; /* forget it */ | ||
2491 | |||
2492 | return l; | ||
2493 | } | ||
2494 | |||
2495 | static void *fib_route_seq_start(struct seq_file *seq, loff_t *pos) | ||
2496 | __acquires(RCU) | ||
2497 | { | ||
2498 | struct fib_route_iter *iter = seq->private; | ||
2499 | struct fib_table *tb; | ||
2500 | |||
2501 | rcu_read_lock(); | ||
2502 | tb = fib_get_table(iter->p.net, RT_TABLE_MAIN); | ||
2503 | if (!tb) | ||
2504 | return NULL; | ||
2505 | |||
2506 | iter->main_trie = (struct trie *) tb->tb_data; | ||
2507 | if (*pos == 0) | ||
2508 | return SEQ_START_TOKEN; | ||
2509 | else | ||
2510 | return fib_route_get_idx(iter, *pos - 1); | ||
2511 | } | ||
2512 | |||
2513 | static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
2514 | { | ||
2515 | struct fib_route_iter *iter = seq->private; | ||
2516 | struct leaf *l = v; | ||
2517 | |||
2518 | ++*pos; | ||
2519 | if (v == SEQ_START_TOKEN) { | ||
2520 | iter->pos = 0; | ||
2521 | l = trie_firstleaf(iter->main_trie); | ||
2522 | } else { | ||
2523 | iter->pos++; | ||
2524 | l = trie_nextleaf(l); | ||
2525 | } | ||
2526 | |||
2527 | if (l) | ||
2528 | iter->key = l->key; | ||
2529 | else | ||
2530 | iter->pos = 0; | ||
2531 | return l; | ||
2532 | } | ||
2533 | |||
2534 | static void fib_route_seq_stop(struct seq_file *seq, void *v) | ||
2535 | __releases(RCU) | ||
2536 | { | ||
2537 | rcu_read_unlock(); | ||
2538 | } | ||
2539 | |||
2464 | static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi) | 2540 | static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi) |
2465 | { | 2541 | { |
2466 | static unsigned type2flags[RTN_MAX + 1] = { | 2542 | static unsigned type2flags[RTN_MAX + 1] = { |
@@ -2484,7 +2560,6 @@ static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi) | |||
2484 | */ | 2560 | */ |
2485 | static int fib_route_seq_show(struct seq_file *seq, void *v) | 2561 | static int fib_route_seq_show(struct seq_file *seq, void *v) |
2486 | { | 2562 | { |
2487 | const struct fib_trie_iter *iter = seq->private; | ||
2488 | struct leaf *l = v; | 2563 | struct leaf *l = v; |
2489 | struct leaf_info *li; | 2564 | struct leaf_info *li; |
2490 | struct hlist_node *node; | 2565 | struct hlist_node *node; |
@@ -2496,12 +2571,6 @@ static int fib_route_seq_show(struct seq_file *seq, void *v) | |||
2496 | return 0; | 2571 | return 0; |
2497 | } | 2572 | } |
2498 | 2573 | ||
2499 | if (iter->trie == iter->trie_local) | ||
2500 | return 0; | ||
2501 | |||
2502 | if (IS_TNODE(l)) | ||
2503 | return 0; | ||
2504 | |||
2505 | hlist_for_each_entry_rcu(li, node, &l->list, hlist) { | 2574 | hlist_for_each_entry_rcu(li, node, &l->list, hlist) { |
2506 | struct fib_alias *fa; | 2575 | struct fib_alias *fa; |
2507 | __be32 mask, prefix; | 2576 | __be32 mask, prefix; |
@@ -2544,16 +2613,16 @@ static int fib_route_seq_show(struct seq_file *seq, void *v) | |||
2544 | } | 2613 | } |
2545 | 2614 | ||
2546 | static const struct seq_operations fib_route_seq_ops = { | 2615 | static const struct seq_operations fib_route_seq_ops = { |
2547 | .start = fib_trie_seq_start, | 2616 | .start = fib_route_seq_start, |
2548 | .next = fib_trie_seq_next, | 2617 | .next = fib_route_seq_next, |
2549 | .stop = fib_trie_seq_stop, | 2618 | .stop = fib_route_seq_stop, |
2550 | .show = fib_route_seq_show, | 2619 | .show = fib_route_seq_show, |
2551 | }; | 2620 | }; |
2552 | 2621 | ||
2553 | static int fib_route_seq_open(struct inode *inode, struct file *file) | 2622 | static int fib_route_seq_open(struct inode *inode, struct file *file) |
2554 | { | 2623 | { |
2555 | return seq_open_net(inode, file, &fib_route_seq_ops, | 2624 | return seq_open_net(inode, file, &fib_route_seq_ops, |
2556 | sizeof(struct fib_trie_iter)); | 2625 | sizeof(struct fib_route_iter)); |
2557 | } | 2626 | } |
2558 | 2627 | ||
2559 | static const struct file_operations fib_route_fops = { | 2628 | static const struct file_operations fib_route_fops = { |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 9cac6c034abd..1aba606f6bbb 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -120,8 +120,6 @@ void inet_listen_wlock(struct inet_hashinfo *hashinfo) | |||
120 | } | 120 | } |
121 | } | 121 | } |
122 | 122 | ||
123 | EXPORT_SYMBOL(inet_listen_wlock); | ||
124 | |||
125 | /* | 123 | /* |
126 | * Don't inline this cruft. Here are some nice properties to exploit here. The | 124 | * Don't inline this cruft. Here are some nice properties to exploit here. The |
127 | * BSD API does not allow a listening sock to specify the remote port nor the | 125 | * BSD API does not allow a listening sock to specify the remote port nor the |
@@ -494,7 +492,6 @@ out: | |||
494 | return ret; | 492 | return ret; |
495 | } | 493 | } |
496 | } | 494 | } |
497 | EXPORT_SYMBOL_GPL(__inet_hash_connect); | ||
498 | 495 | ||
499 | /* | 496 | /* |
500 | * Bind a port for a connect operation and hash it. | 497 | * Bind a port for a connect operation and hash it. |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 63f691719353..906cb1ada4c3 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -259,16 +259,8 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int | |||
259 | 259 | ||
260 | if (parms->name[0]) | 260 | if (parms->name[0]) |
261 | strlcpy(name, parms->name, IFNAMSIZ); | 261 | strlcpy(name, parms->name, IFNAMSIZ); |
262 | else { | 262 | else |
263 | int i; | 263 | sprintf(name, "gre%%d"); |
264 | for (i=1; i<100; i++) { | ||
265 | sprintf(name, "gre%d", i); | ||
266 | if (__dev_get_by_name(&init_net, name) == NULL) | ||
267 | break; | ||
268 | } | ||
269 | if (i==100) | ||
270 | goto failed; | ||
271 | } | ||
272 | 264 | ||
273 | dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup); | 265 | dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup); |
274 | if (!dev) | 266 | if (!dev) |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 754b0a5bbfe9..de0572c88859 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -514,11 +514,6 @@ static int do_ip_setsockopt(struct sock *sk, int level, | |||
514 | val &= ~3; | 514 | val &= ~3; |
515 | val |= inet->tos & 3; | 515 | val |= inet->tos & 3; |
516 | } | 516 | } |
517 | if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP && | ||
518 | !capable(CAP_NET_ADMIN)) { | ||
519 | err = -EPERM; | ||
520 | break; | ||
521 | } | ||
522 | if (inet->tos != val) { | 517 | if (inet->tos != val) { |
523 | inet->tos = val; | 518 | inet->tos = val; |
524 | sk->sk_priority = rt_tos2priority(val); | 519 | sk->sk_priority = rt_tos2priority(val); |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index a52b5853aaa8..10013ccee8dd 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -1390,7 +1390,7 @@ static int __init ip_auto_config(void) | |||
1390 | * Clue in the operator. | 1390 | * Clue in the operator. |
1391 | */ | 1391 | */ |
1392 | printk("IP-Config: Complete:"); | 1392 | printk("IP-Config: Complete:"); |
1393 | printk("\n device=%s", ic_dev->name); | 1393 | printk("\n device=%s", ic_dev->name); |
1394 | printk(", addr=%u.%u.%u.%u", NIPQUAD(ic_myaddr)); | 1394 | printk(", addr=%u.%u.%u.%u", NIPQUAD(ic_myaddr)); |
1395 | printk(", mask=%u.%u.%u.%u", NIPQUAD(ic_netmask)); | 1395 | printk(", mask=%u.%u.%u.%u", NIPQUAD(ic_netmask)); |
1396 | printk(", gw=%u.%u.%u.%u", NIPQUAD(ic_gateway)); | 1396 | printk(", gw=%u.%u.%u.%u", NIPQUAD(ic_gateway)); |
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index da281581692c..e77e3b855834 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c | |||
@@ -221,16 +221,8 @@ static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int c | |||
221 | 221 | ||
222 | if (parms->name[0]) | 222 | if (parms->name[0]) |
223 | strlcpy(name, parms->name, IFNAMSIZ); | 223 | strlcpy(name, parms->name, IFNAMSIZ); |
224 | else { | 224 | else |
225 | int i; | 225 | sprintf(name, "tunl%%d"); |
226 | for (i=1; i<100; i++) { | ||
227 | sprintf(name, "tunl%d", i); | ||
228 | if (__dev_get_by_name(&init_net, name) == NULL) | ||
229 | break; | ||
230 | } | ||
231 | if (i==100) | ||
232 | goto failed; | ||
233 | } | ||
234 | 226 | ||
235 | dev = alloc_netdev(sizeof(*t), name, ipip_tunnel_setup); | 227 | dev = alloc_netdev(sizeof(*t), name, ipip_tunnel_setup); |
236 | if (dev == NULL) | 228 | if (dev == NULL) |
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index 45fa4e20094a..3f4222b0a803 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c | |||
@@ -19,7 +19,7 @@ target(struct sk_buff *skb, | |||
19 | unsigned char *arpptr; | 19 | unsigned char *arpptr; |
20 | int pln, hln; | 20 | int pln, hln; |
21 | 21 | ||
22 | if (skb_make_writable(skb, skb->len)) | 22 | if (!skb_make_writable(skb, skb->len)) |
23 | return NF_DROP; | 23 | return NF_DROP; |
24 | 24 | ||
25 | arp = arp_hdr(skb); | 25 | arp = arp_hdr(skb); |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 6bda1102851b..fe05da41d6ba 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -283,8 +283,8 @@ static int | |||
283 | ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct nf_queue_entry *e) | 283 | ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct nf_queue_entry *e) |
284 | { | 284 | { |
285 | int diff; | 285 | int diff; |
286 | int err; | ||
287 | struct iphdr *user_iph = (struct iphdr *)v->payload; | 286 | struct iphdr *user_iph = (struct iphdr *)v->payload; |
287 | struct sk_buff *nskb; | ||
288 | 288 | ||
289 | if (v->data_len < sizeof(*user_iph)) | 289 | if (v->data_len < sizeof(*user_iph)) |
290 | return 0; | 290 | return 0; |
@@ -296,14 +296,16 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct nf_queue_entry *e) | |||
296 | if (v->data_len > 0xFFFF) | 296 | if (v->data_len > 0xFFFF) |
297 | return -EINVAL; | 297 | return -EINVAL; |
298 | if (diff > skb_tailroom(e->skb)) { | 298 | if (diff > skb_tailroom(e->skb)) { |
299 | err = pskb_expand_head(e->skb, 0, | 299 | nskb = skb_copy_expand(e->skb, 0, |
300 | diff - skb_tailroom(e->skb), | 300 | diff - skb_tailroom(e->skb), |
301 | GFP_ATOMIC); | 301 | GFP_ATOMIC); |
302 | if (err) { | 302 | if (!nskb) { |
303 | printk(KERN_WARNING "ip_queue: error " | 303 | printk(KERN_WARNING "ip_queue: error " |
304 | "in mangle, dropping packet: %d\n", -err); | 304 | "in mangle, dropping packet\n"); |
305 | return err; | 305 | return -ENOMEM; |
306 | } | 306 | } |
307 | kfree_skb(e->skb); | ||
308 | e->skb = nskb; | ||
307 | } | 309 | } |
308 | skb_put(e->skb, diff); | 310 | skb_put(e->skb, diff); |
309 | } | 311 | } |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 63414ea427c5..00156bf421ca 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -719,7 +719,7 @@ static void tcp_v4_reqsk_send_ack(struct sk_buff *skb, | |||
719 | } | 719 | } |
720 | 720 | ||
721 | /* | 721 | /* |
722 | * Send a SYN-ACK after having received an ACK. | 722 | * Send a SYN-ACK after having received a SYN. |
723 | * This still operates on a request_sock only, not on a big | 723 | * This still operates on a request_sock only, not on a big |
724 | * socket. | 724 | * socket. |
725 | */ | 725 | */ |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index bddac0e8780f..f0aa97738746 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -752,14 +752,6 @@ static int __init inet6_init(void) | |||
752 | 752 | ||
753 | BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb)); | 753 | BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb)); |
754 | 754 | ||
755 | #ifdef MODULE | ||
756 | #if 0 /* FIXME --RR */ | ||
757 | if (!mod_member_present(&__this_module, can_unload)) | ||
758 | return -EINVAL; | ||
759 | |||
760 | __this_module.can_unload = &ipv6_unload; | ||
761 | #endif | ||
762 | #endif | ||
763 | err = proto_register(&tcpv6_prot, 1); | 755 | err = proto_register(&tcpv6_prot, 1); |
764 | if (err) | 756 | if (err) |
765 | goto out; | 757 | goto out; |
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 379c8e04c36c..2ff0c8233e47 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -283,7 +283,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
283 | 283 | ||
284 | ah->reserved = 0; | 284 | ah->reserved = 0; |
285 | ah->spi = x->id.spi; | 285 | ah->spi = x->id.spi; |
286 | ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq); | 286 | ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output); |
287 | 287 | ||
288 | spin_lock_bh(&x->lock); | 288 | spin_lock_bh(&x->lock); |
289 | err = ah_mac_digest(ahp, skb, ah->auth_data); | 289 | err = ah_mac_digest(ahp, skb, ah->auth_data); |
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 8e0f1428c716..0ec1402320ea 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -188,7 +188,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
188 | *skb_mac_header(skb) = IPPROTO_ESP; | 188 | *skb_mac_header(skb) = IPPROTO_ESP; |
189 | 189 | ||
190 | esph->spi = x->id.spi; | 190 | esph->spi = x->id.spi; |
191 | esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq); | 191 | esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output); |
192 | 192 | ||
193 | sg_init_table(sg, nfrags); | 193 | sg_init_table(sg, nfrags); |
194 | skb_to_sgvec(skb, sg, | 194 | skb_to_sgvec(skb, sg, |
@@ -199,7 +199,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) | |||
199 | aead_givcrypt_set_callback(req, 0, esp_output_done, skb); | 199 | aead_givcrypt_set_callback(req, 0, esp_output_done, skb); |
200 | aead_givcrypt_set_crypt(req, sg, sg, clen, iv); | 200 | aead_givcrypt_set_crypt(req, sg, sg, clen, iv); |
201 | aead_givcrypt_set_assoc(req, asg, sizeof(*esph)); | 201 | aead_givcrypt_set_assoc(req, asg, sizeof(*esph)); |
202 | aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq); | 202 | aead_givcrypt_set_giv(req, esph->enc_data, |
203 | XFRM_SKB_CB(skb)->seq.output); | ||
203 | 204 | ||
204 | ESP_SKB_CB(skb)->tmp = tmp; | 205 | ESP_SKB_CB(skb)->tmp = tmp; |
205 | err = crypto_aead_givencrypt(req); | 206 | err = crypto_aead_givencrypt(req); |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index f93407cf6515..bab72b6f1444 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -1151,7 +1151,7 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, | |||
1151 | fn = fn->parent; | 1151 | fn = fn->parent; |
1152 | } | 1152 | } |
1153 | /* No more references are possible at this point. */ | 1153 | /* No more references are possible at this point. */ |
1154 | if (atomic_read(&rt->rt6i_ref) != 1) BUG(); | 1154 | BUG_ON(atomic_read(&rt->rt6i_ref) != 1); |
1155 | } | 1155 | } |
1156 | 1156 | ||
1157 | inet6_rt_notify(RTM_DELROUTE, rt, info); | 1157 | inet6_rt_notify(RTM_DELROUTE, rt, info); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 9ac6ca2521c3..8b67ca07467d 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -621,7 +621,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
621 | * or if the skb it not generated by a local socket. (This last | 621 | * or if the skb it not generated by a local socket. (This last |
622 | * check should be redundant, but it's free.) | 622 | * check should be redundant, but it's free.) |
623 | */ | 623 | */ |
624 | if (!np || np->pmtudisc >= IPV6_PMTUDISC_DO) { | 624 | if (!skb->local_df) { |
625 | skb->dev = skb->dst->dev; | 625 | skb->dev = skb->dst->dev; |
626 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); | 626 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); |
627 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); | 627 | IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); |
@@ -1420,6 +1420,10 @@ int ip6_push_pending_frames(struct sock *sk) | |||
1420 | tmp_skb->sk = NULL; | 1420 | tmp_skb->sk = NULL; |
1421 | } | 1421 | } |
1422 | 1422 | ||
1423 | /* Allow local fragmentation. */ | ||
1424 | if (np->pmtudisc < IPV6_PMTUDISC_DO) | ||
1425 | skb->local_df = 1; | ||
1426 | |||
1423 | ipv6_addr_copy(final_dst, &fl->fl6_dst); | 1427 | ipv6_addr_copy(final_dst, &fl->fl6_dst); |
1424 | __skb_pull(skb, skb_network_header_len(skb)); | 1428 | __skb_pull(skb, skb_network_header_len(skb)); |
1425 | if (opt && opt->opt_flen) | 1429 | if (opt && opt->opt_flen) |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 9031e521c1df..2a124e9a1b2d 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -229,18 +229,11 @@ static struct ip6_tnl *ip6_tnl_create(struct ip6_tnl_parm *p) | |||
229 | char name[IFNAMSIZ]; | 229 | char name[IFNAMSIZ]; |
230 | int err; | 230 | int err; |
231 | 231 | ||
232 | if (p->name[0]) { | 232 | if (p->name[0]) |
233 | strlcpy(name, p->name, IFNAMSIZ); | 233 | strlcpy(name, p->name, IFNAMSIZ); |
234 | } else { | 234 | else |
235 | int i; | 235 | sprintf(name, "ip6tnl%%d"); |
236 | for (i = 1; i < IP6_TNL_MAX; i++) { | 236 | |
237 | sprintf(name, "ip6tnl%d", i); | ||
238 | if (__dev_get_by_name(&init_net, name) == NULL) | ||
239 | break; | ||
240 | } | ||
241 | if (i == IP6_TNL_MAX) | ||
242 | goto failed; | ||
243 | } | ||
244 | dev = alloc_netdev(sizeof (*t), name, ip6_tnl_dev_setup); | 237 | dev = alloc_netdev(sizeof (*t), name, ip6_tnl_dev_setup); |
245 | if (dev == NULL) | 238 | if (dev == NULL) |
246 | goto failed; | 239 | goto failed; |
@@ -550,6 +543,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
550 | ip_rt_put(rt); | 543 | ip_rt_put(rt); |
551 | goto out; | 544 | goto out; |
552 | } | 545 | } |
546 | skb2->dst = (struct dst_entry *)rt; | ||
553 | } else { | 547 | } else { |
554 | ip_rt_put(rt); | 548 | ip_rt_put(rt); |
555 | if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, | 549 | if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos, |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index e869916b05f1..cc2f9afcf808 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -285,8 +285,8 @@ static int | |||
285 | ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct nf_queue_entry *e) | 285 | ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct nf_queue_entry *e) |
286 | { | 286 | { |
287 | int diff; | 287 | int diff; |
288 | int err; | ||
289 | struct ipv6hdr *user_iph = (struct ipv6hdr *)v->payload; | 288 | struct ipv6hdr *user_iph = (struct ipv6hdr *)v->payload; |
289 | struct sk_buff *nskb; | ||
290 | 290 | ||
291 | if (v->data_len < sizeof(*user_iph)) | 291 | if (v->data_len < sizeof(*user_iph)) |
292 | return 0; | 292 | return 0; |
@@ -298,14 +298,16 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct nf_queue_entry *e) | |||
298 | if (v->data_len > 0xFFFF) | 298 | if (v->data_len > 0xFFFF) |
299 | return -EINVAL; | 299 | return -EINVAL; |
300 | if (diff > skb_tailroom(e->skb)) { | 300 | if (diff > skb_tailroom(e->skb)) { |
301 | err = pskb_expand_head(e->skb, 0, | 301 | nskb = skb_copy_expand(e->skb, 0, |
302 | diff - skb_tailroom(e->skb), | 302 | diff - skb_tailroom(e->skb), |
303 | GFP_ATOMIC); | 303 | GFP_ATOMIC); |
304 | if (err) { | 304 | if (!nskb) { |
305 | printk(KERN_WARNING "ip6_queue: OOM " | 305 | printk(KERN_WARNING "ip6_queue: OOM " |
306 | "in mangle, dropping packet\n"); | 306 | "in mangle, dropping packet\n"); |
307 | return err; | 307 | return -ENOMEM; |
308 | } | 308 | } |
309 | kfree_skb(e->skb); | ||
310 | e->skb = nskb; | ||
309 | } | 311 | } |
310 | skb_put(e->skb, diff); | 312 | skb_put(e->skb, diff); |
311 | } | 313 | } |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index e77239d02bf5..dde7801abeff 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -164,16 +164,8 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int | |||
164 | 164 | ||
165 | if (parms->name[0]) | 165 | if (parms->name[0]) |
166 | strlcpy(name, parms->name, IFNAMSIZ); | 166 | strlcpy(name, parms->name, IFNAMSIZ); |
167 | else { | 167 | else |
168 | int i; | 168 | sprintf(name, "sit%%d"); |
169 | for (i=1; i<100; i++) { | ||
170 | sprintf(name, "sit%d", i); | ||
171 | if (__dev_get_by_name(&init_net, name) == NULL) | ||
172 | break; | ||
173 | } | ||
174 | if (i==100) | ||
175 | goto failed; | ||
176 | } | ||
177 | 169 | ||
178 | dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup); | 170 | dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup); |
179 | if (dev == NULL) | 171 | if (dev == NULL) |
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index b34c58c65656..79ccfb080733 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c | |||
@@ -36,7 +36,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb) | |||
36 | if (mtu < IPV6_MIN_MTU) | 36 | if (mtu < IPV6_MIN_MTU) |
37 | mtu = IPV6_MIN_MTU; | 37 | mtu = IPV6_MIN_MTU; |
38 | 38 | ||
39 | if (skb->len > mtu) { | 39 | if (!skb->local_df && skb->len > mtu) { |
40 | skb->dev = dst->dev; | 40 | skb->dev = dst->dev; |
41 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); | 41 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); |
42 | ret = -EMSGSIZE; | 42 | ret = -EMSGSIZE; |
diff --git a/net/key/af_key.c b/net/key/af_key.c index b3ac85e808ac..1c853927810a 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -2291,6 +2291,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2291 | return 0; | 2291 | return 0; |
2292 | 2292 | ||
2293 | out: | 2293 | out: |
2294 | xp->dead = 1; | ||
2294 | xfrm_policy_destroy(xp); | 2295 | xfrm_policy_destroy(xp); |
2295 | return err; | 2296 | return err; |
2296 | } | 2297 | } |
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 67b7c75c430d..28bcdf9fc3df 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -165,6 +165,7 @@ static int ieee80211_open(struct net_device *dev) | |||
165 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 165 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
166 | struct ieee80211_if_init_conf conf; | 166 | struct ieee80211_if_init_conf conf; |
167 | int res; | 167 | int res; |
168 | bool need_hw_reconfig = 0; | ||
168 | 169 | ||
169 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 170 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
170 | 171 | ||
@@ -218,7 +219,7 @@ static int ieee80211_open(struct net_device *dev) | |||
218 | res = local->ops->start(local_to_hw(local)); | 219 | res = local->ops->start(local_to_hw(local)); |
219 | if (res) | 220 | if (res) |
220 | return res; | 221 | return res; |
221 | ieee80211_hw_config(local); | 222 | need_hw_reconfig = 1; |
222 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); | 223 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); |
223 | } | 224 | } |
224 | 225 | ||
@@ -282,6 +283,8 @@ static int ieee80211_open(struct net_device *dev) | |||
282 | atomic_inc(&local->iff_promiscs); | 283 | atomic_inc(&local->iff_promiscs); |
283 | 284 | ||
284 | local->open_count++; | 285 | local->open_count++; |
286 | if (need_hw_reconfig) | ||
287 | ieee80211_hw_config(local); | ||
285 | 288 | ||
286 | netif_start_queue(dev); | 289 | netif_start_queue(dev); |
287 | 290 | ||
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 202d7fa09483..62567959b66e 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
@@ -945,7 +945,7 @@ static int tcp_packet(struct nf_conn *ct, | |||
945 | 945 | ||
946 | ct->proto.tcp.state = new_state; | 946 | ct->proto.tcp.state = new_state; |
947 | if (old_state != new_state | 947 | if (old_state != new_state |
948 | && new_state == TCP_CONNTRACK_CLOSE) | 948 | && new_state == TCP_CONNTRACK_FIN_WAIT) |
949 | ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT; | 949 | ct->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT; |
950 | timeout = ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans | 950 | timeout = ct->proto.tcp.retrans >= nf_ct_tcp_max_retrans |
951 | && tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans | 951 | && tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index a48b20fe9cd6..0043d3a9f87e 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -443,8 +443,8 @@ err_out: | |||
443 | static int | 443 | static int |
444 | nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e) | 444 | nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e) |
445 | { | 445 | { |
446 | struct sk_buff *nskb; | ||
446 | int diff; | 447 | int diff; |
447 | int err; | ||
448 | 448 | ||
449 | diff = data_len - e->skb->len; | 449 | diff = data_len - e->skb->len; |
450 | if (diff < 0) { | 450 | if (diff < 0) { |
@@ -454,14 +454,16 @@ nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e) | |||
454 | if (data_len > 0xFFFF) | 454 | if (data_len > 0xFFFF) |
455 | return -EINVAL; | 455 | return -EINVAL; |
456 | if (diff > skb_tailroom(e->skb)) { | 456 | if (diff > skb_tailroom(e->skb)) { |
457 | err = pskb_expand_head(e->skb, 0, | 457 | nskb = skb_copy_expand(e->skb, 0, |
458 | diff - skb_tailroom(e->skb), | 458 | diff - skb_tailroom(e->skb), |
459 | GFP_ATOMIC); | 459 | GFP_ATOMIC); |
460 | if (err) { | 460 | if (!nskb) { |
461 | printk(KERN_WARNING "nf_queue: OOM " | 461 | printk(KERN_WARNING "nf_queue: OOM " |
462 | "in mangle, dropping packet\n"); | 462 | "in mangle, dropping packet\n"); |
463 | return err; | 463 | return -ENOMEM; |
464 | } | 464 | } |
465 | kfree_skb(e->skb); | ||
466 | e->skb = nskb; | ||
465 | } | 467 | } |
466 | skb_put(e->skb, diff); | 468 | skb_put(e->skb, diff); |
467 | } | 469 | } |
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index 7708e2084ce2..c0284856ccd4 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c | |||
@@ -111,7 +111,7 @@ secmark_tg_check(const char *tablename, const void *entry, | |||
111 | return true; | 111 | return true; |
112 | } | 112 | } |
113 | 113 | ||
114 | void secmark_tg_destroy(const struct xt_target *target, void *targinfo) | 114 | static void secmark_tg_destroy(const struct xt_target *target, void *targinfo) |
115 | { | 115 | { |
116 | switch (mode) { | 116 | switch (mode) { |
117 | case SECMARK_MODE_SEL: | 117 | case SECMARK_MODE_SEL: |
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 744c7f2ab0b1..5418ce59ac3a 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c | |||
@@ -774,9 +774,6 @@ hashlimit_mt_check(const char *tablename, const void *inf, | |||
774 | return false; | 774 | return false; |
775 | } | 775 | } |
776 | mutex_unlock(&hlimit_mutex); | 776 | mutex_unlock(&hlimit_mutex); |
777 | |||
778 | /* Ugly hack: For SMP, we only want to use one set */ | ||
779 | info->master = info; | ||
780 | return true; | 777 | return true; |
781 | } | 778 | } |
782 | 779 | ||
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c index 4f984dc60319..500528d60cd7 100644 --- a/net/netfilter/xt_iprange.c +++ b/net/netfilter/xt_iprange.c | |||
@@ -102,7 +102,7 @@ iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b) | |||
102 | int r; | 102 | int r; |
103 | 103 | ||
104 | for (i = 0; i < 4; ++i) { | 104 | for (i = 0; i < 4; ++i) { |
105 | r = (__force u32)a->s6_addr32[i] - (__force u32)b->s6_addr32[i]; | 105 | r = ntohl(a->s6_addr32[i]) - ntohl(b->s6_addr32[i]); |
106 | if (r != 0) | 106 | if (r != 0) |
107 | return r; | 107 | return r; |
108 | } | 108 | } |
diff --git a/net/netfilter/xt_u32.c b/net/netfilter/xt_u32.c index 9b8ed390a8e0..627e0f336d54 100644 --- a/net/netfilter/xt_u32.c +++ b/net/netfilter/xt_u32.c | |||
@@ -26,7 +26,6 @@ static bool u32_match_it(const struct xt_u32 *data, | |||
26 | u_int32_t pos; | 26 | u_int32_t pos; |
27 | u_int32_t val; | 27 | u_int32_t val; |
28 | u_int32_t at; | 28 | u_int32_t at; |
29 | int ret; | ||
30 | 29 | ||
31 | /* | 30 | /* |
32 | * Small example: "0 >> 28 == 4 && 8 & 0xFF0000 >> 16 = 6, 17" | 31 | * Small example: "0 >> 28 == 4 && 8 & 0xFF0000 >> 16 = 6, 17" |
@@ -40,8 +39,8 @@ static bool u32_match_it(const struct xt_u32 *data, | |||
40 | if (skb->len < 4 || pos > skb->len - 4) | 39 | if (skb->len < 4 || pos > skb->len - 4) |
41 | return false; | 40 | return false; |
42 | 41 | ||
43 | ret = skb_copy_bits(skb, pos, &n, sizeof(n)); | 42 | if (skb_copy_bits(skb, pos, &n, sizeof(n)) < 0) |
44 | BUG_ON(ret < 0); | 43 | BUG(); |
45 | val = ntohl(n); | 44 | val = ntohl(n); |
46 | nnums = ct->nnums; | 45 | nnums = ct->nnums; |
47 | 46 | ||
@@ -67,9 +66,9 @@ static bool u32_match_it(const struct xt_u32 *data, | |||
67 | pos > skb->len - at - 4) | 66 | pos > skb->len - at - 4) |
68 | return false; | 67 | return false; |
69 | 68 | ||
70 | ret = skb_copy_bits(skb, at + pos, &n, | 69 | if (skb_copy_bits(skb, at + pos, &n, |
71 | sizeof(n)); | 70 | sizeof(n)) < 0) |
72 | BUG_ON(ret < 0); | 71 | BUG(); |
73 | val = ntohl(n); | 72 | val = ntohl(n); |
74 | break; | 73 | break; |
75 | } | 74 | } |
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index c7ad64d664ad..fdc14a0d21af 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c | |||
@@ -718,36 +718,35 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info) | |||
718 | * NetLabel Generic NETLINK Command Definitions | 718 | * NetLabel Generic NETLINK Command Definitions |
719 | */ | 719 | */ |
720 | 720 | ||
721 | static struct genl_ops netlbl_cipsov4_genl_c_add = { | 721 | static struct genl_ops netlbl_cipsov4_ops[] = { |
722 | { | ||
722 | .cmd = NLBL_CIPSOV4_C_ADD, | 723 | .cmd = NLBL_CIPSOV4_C_ADD, |
723 | .flags = GENL_ADMIN_PERM, | 724 | .flags = GENL_ADMIN_PERM, |
724 | .policy = netlbl_cipsov4_genl_policy, | 725 | .policy = netlbl_cipsov4_genl_policy, |
725 | .doit = netlbl_cipsov4_add, | 726 | .doit = netlbl_cipsov4_add, |
726 | .dumpit = NULL, | 727 | .dumpit = NULL, |
727 | }; | 728 | }, |
728 | 729 | { | |
729 | static struct genl_ops netlbl_cipsov4_genl_c_remove = { | ||
730 | .cmd = NLBL_CIPSOV4_C_REMOVE, | 730 | .cmd = NLBL_CIPSOV4_C_REMOVE, |
731 | .flags = GENL_ADMIN_PERM, | 731 | .flags = GENL_ADMIN_PERM, |
732 | .policy = netlbl_cipsov4_genl_policy, | 732 | .policy = netlbl_cipsov4_genl_policy, |
733 | .doit = netlbl_cipsov4_remove, | 733 | .doit = netlbl_cipsov4_remove, |
734 | .dumpit = NULL, | 734 | .dumpit = NULL, |
735 | }; | 735 | }, |
736 | 736 | { | |
737 | static struct genl_ops netlbl_cipsov4_genl_c_list = { | ||
738 | .cmd = NLBL_CIPSOV4_C_LIST, | 737 | .cmd = NLBL_CIPSOV4_C_LIST, |
739 | .flags = 0, | 738 | .flags = 0, |
740 | .policy = netlbl_cipsov4_genl_policy, | 739 | .policy = netlbl_cipsov4_genl_policy, |
741 | .doit = netlbl_cipsov4_list, | 740 | .doit = netlbl_cipsov4_list, |
742 | .dumpit = NULL, | 741 | .dumpit = NULL, |
743 | }; | 742 | }, |
744 | 743 | { | |
745 | static struct genl_ops netlbl_cipsov4_genl_c_listall = { | ||
746 | .cmd = NLBL_CIPSOV4_C_LISTALL, | 744 | .cmd = NLBL_CIPSOV4_C_LISTALL, |
747 | .flags = 0, | 745 | .flags = 0, |
748 | .policy = netlbl_cipsov4_genl_policy, | 746 | .policy = netlbl_cipsov4_genl_policy, |
749 | .doit = NULL, | 747 | .doit = NULL, |
750 | .dumpit = netlbl_cipsov4_listall, | 748 | .dumpit = netlbl_cipsov4_listall, |
749 | }, | ||
751 | }; | 750 | }; |
752 | 751 | ||
753 | /* | 752 | /* |
@@ -762,30 +761,20 @@ static struct genl_ops netlbl_cipsov4_genl_c_listall = { | |||
762 | * mechanism. Returns zero on success, negative values on failure. | 761 | * mechanism. Returns zero on success, negative values on failure. |
763 | * | 762 | * |
764 | */ | 763 | */ |
765 | int netlbl_cipsov4_genl_init(void) | 764 | int __init netlbl_cipsov4_genl_init(void) |
766 | { | 765 | { |
767 | int ret_val; | 766 | int ret_val, i; |
768 | 767 | ||
769 | ret_val = genl_register_family(&netlbl_cipsov4_gnl_family); | 768 | ret_val = genl_register_family(&netlbl_cipsov4_gnl_family); |
770 | if (ret_val != 0) | 769 | if (ret_val != 0) |
771 | return ret_val; | 770 | return ret_val; |
772 | 771 | ||
773 | ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, | 772 | for (i = 0; i < ARRAY_SIZE(netlbl_cipsov4_ops); i++) { |
774 | &netlbl_cipsov4_genl_c_add); | 773 | ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, |
775 | if (ret_val != 0) | 774 | &netlbl_cipsov4_ops[i]); |
776 | return ret_val; | 775 | if (ret_val != 0) |
777 | ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, | 776 | return ret_val; |
778 | &netlbl_cipsov4_genl_c_remove); | 777 | } |
779 | if (ret_val != 0) | ||
780 | return ret_val; | ||
781 | ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, | ||
782 | &netlbl_cipsov4_genl_c_list); | ||
783 | if (ret_val != 0) | ||
784 | return ret_val; | ||
785 | ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family, | ||
786 | &netlbl_cipsov4_genl_c_listall); | ||
787 | if (ret_val != 0) | ||
788 | return ret_val; | ||
789 | 778 | ||
790 | return 0; | 779 | return 0; |
791 | } | 780 | } |
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index 9a8ea0195c4f..02c2f7c0b255 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c | |||
@@ -150,11 +150,11 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain) | |||
150 | entry = netlbl_domhsh_search(domain); | 150 | entry = netlbl_domhsh_search(domain); |
151 | if (entry == NULL) { | 151 | if (entry == NULL) { |
152 | entry = rcu_dereference(netlbl_domhsh_def); | 152 | entry = rcu_dereference(netlbl_domhsh_def); |
153 | if (entry != NULL && entry->valid) | 153 | if (entry != NULL && !entry->valid) |
154 | return entry; | 154 | entry = NULL; |
155 | } | 155 | } |
156 | 156 | ||
157 | return NULL; | 157 | return entry; |
158 | } | 158 | } |
159 | 159 | ||
160 | /* | 160 | /* |
@@ -171,7 +171,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain) | |||
171 | * values on error. | 171 | * values on error. |
172 | * | 172 | * |
173 | */ | 173 | */ |
174 | int netlbl_domhsh_init(u32 size) | 174 | int __init netlbl_domhsh_init(u32 size) |
175 | { | 175 | { |
176 | u32 iter; | 176 | u32 iter; |
177 | struct netlbl_domhsh_tbl *hsh_tbl; | 177 | struct netlbl_domhsh_tbl *hsh_tbl; |
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index e2258dc3c845..22c191267808 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c | |||
@@ -517,68 +517,63 @@ version_failure: | |||
517 | * NetLabel Generic NETLINK Command Definitions | 517 | * NetLabel Generic NETLINK Command Definitions |
518 | */ | 518 | */ |
519 | 519 | ||
520 | static struct genl_ops netlbl_mgmt_genl_c_add = { | 520 | static struct genl_ops netlbl_mgmt_genl_ops[] = { |
521 | { | ||
521 | .cmd = NLBL_MGMT_C_ADD, | 522 | .cmd = NLBL_MGMT_C_ADD, |
522 | .flags = GENL_ADMIN_PERM, | 523 | .flags = GENL_ADMIN_PERM, |
523 | .policy = netlbl_mgmt_genl_policy, | 524 | .policy = netlbl_mgmt_genl_policy, |
524 | .doit = netlbl_mgmt_add, | 525 | .doit = netlbl_mgmt_add, |
525 | .dumpit = NULL, | 526 | .dumpit = NULL, |
526 | }; | 527 | }, |
527 | 528 | { | |
528 | static struct genl_ops netlbl_mgmt_genl_c_remove = { | ||
529 | .cmd = NLBL_MGMT_C_REMOVE, | 529 | .cmd = NLBL_MGMT_C_REMOVE, |
530 | .flags = GENL_ADMIN_PERM, | 530 | .flags = GENL_ADMIN_PERM, |
531 | .policy = netlbl_mgmt_genl_policy, | 531 | .policy = netlbl_mgmt_genl_policy, |
532 | .doit = netlbl_mgmt_remove, | 532 | .doit = netlbl_mgmt_remove, |
533 | .dumpit = NULL, | 533 | .dumpit = NULL, |
534 | }; | 534 | }, |
535 | 535 | { | |
536 | static struct genl_ops netlbl_mgmt_genl_c_listall = { | ||
537 | .cmd = NLBL_MGMT_C_LISTALL, | 536 | .cmd = NLBL_MGMT_C_LISTALL, |
538 | .flags = 0, | 537 | .flags = 0, |
539 | .policy = netlbl_mgmt_genl_policy, | 538 | .policy = netlbl_mgmt_genl_policy, |
540 | .doit = NULL, | 539 | .doit = NULL, |
541 | .dumpit = netlbl_mgmt_listall, | 540 | .dumpit = netlbl_mgmt_listall, |
542 | }; | 541 | }, |
543 | 542 | { | |
544 | static struct genl_ops netlbl_mgmt_genl_c_adddef = { | ||
545 | .cmd = NLBL_MGMT_C_ADDDEF, | 543 | .cmd = NLBL_MGMT_C_ADDDEF, |
546 | .flags = GENL_ADMIN_PERM, | 544 | .flags = GENL_ADMIN_PERM, |
547 | .policy = netlbl_mgmt_genl_policy, | 545 | .policy = netlbl_mgmt_genl_policy, |
548 | .doit = netlbl_mgmt_adddef, | 546 | .doit = netlbl_mgmt_adddef, |
549 | .dumpit = NULL, | 547 | .dumpit = NULL, |
550 | }; | 548 | }, |
551 | 549 | { | |
552 | static struct genl_ops netlbl_mgmt_genl_c_removedef = { | ||
553 | .cmd = NLBL_MGMT_C_REMOVEDEF, | 550 | .cmd = NLBL_MGMT_C_REMOVEDEF, |
554 | .flags = GENL_ADMIN_PERM, | 551 | .flags = GENL_ADMIN_PERM, |
555 | .policy = netlbl_mgmt_genl_policy, | 552 | .policy = netlbl_mgmt_genl_policy, |
556 | .doit = netlbl_mgmt_removedef, | 553 | .doit = netlbl_mgmt_removedef, |
557 | .dumpit = NULL, | 554 | .dumpit = NULL, |
558 | }; | 555 | }, |
559 | 556 | { | |
560 | static struct genl_ops netlbl_mgmt_genl_c_listdef = { | ||
561 | .cmd = NLBL_MGMT_C_LISTDEF, | 557 | .cmd = NLBL_MGMT_C_LISTDEF, |
562 | .flags = 0, | 558 | .flags = 0, |
563 | .policy = netlbl_mgmt_genl_policy, | 559 | .policy = netlbl_mgmt_genl_policy, |
564 | .doit = netlbl_mgmt_listdef, | 560 | .doit = netlbl_mgmt_listdef, |
565 | .dumpit = NULL, | 561 | .dumpit = NULL, |
566 | }; | 562 | }, |
567 | 563 | { | |
568 | static struct genl_ops netlbl_mgmt_genl_c_protocols = { | ||
569 | .cmd = NLBL_MGMT_C_PROTOCOLS, | 564 | .cmd = NLBL_MGMT_C_PROTOCOLS, |
570 | .flags = 0, | 565 | .flags = 0, |
571 | .policy = netlbl_mgmt_genl_policy, | 566 | .policy = netlbl_mgmt_genl_policy, |
572 | .doit = NULL, | 567 | .doit = NULL, |
573 | .dumpit = netlbl_mgmt_protocols, | 568 | .dumpit = netlbl_mgmt_protocols, |
574 | }; | 569 | }, |
575 | 570 | { | |
576 | static struct genl_ops netlbl_mgmt_genl_c_version = { | ||
577 | .cmd = NLBL_MGMT_C_VERSION, | 571 | .cmd = NLBL_MGMT_C_VERSION, |
578 | .flags = 0, | 572 | .flags = 0, |
579 | .policy = netlbl_mgmt_genl_policy, | 573 | .policy = netlbl_mgmt_genl_policy, |
580 | .doit = netlbl_mgmt_version, | 574 | .doit = netlbl_mgmt_version, |
581 | .dumpit = NULL, | 575 | .dumpit = NULL, |
576 | }, | ||
582 | }; | 577 | }; |
583 | 578 | ||
584 | /* | 579 | /* |
@@ -593,46 +588,20 @@ static struct genl_ops netlbl_mgmt_genl_c_version = { | |||
593 | * mechanism. Returns zero on success, negative values on failure. | 588 | * mechanism. Returns zero on success, negative values on failure. |
594 | * | 589 | * |
595 | */ | 590 | */ |
596 | int netlbl_mgmt_genl_init(void) | 591 | int __init netlbl_mgmt_genl_init(void) |
597 | { | 592 | { |
598 | int ret_val; | 593 | int ret_val, i; |
599 | 594 | ||
600 | ret_val = genl_register_family(&netlbl_mgmt_gnl_family); | 595 | ret_val = genl_register_family(&netlbl_mgmt_gnl_family); |
601 | if (ret_val != 0) | 596 | if (ret_val != 0) |
602 | return ret_val; | 597 | return ret_val; |
603 | 598 | ||
604 | ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, | 599 | for (i = 0; i < ARRAY_SIZE(netlbl_mgmt_genl_ops); i++) { |
605 | &netlbl_mgmt_genl_c_add); | 600 | ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, |
606 | if (ret_val != 0) | 601 | &netlbl_mgmt_genl_ops[i]); |
607 | return ret_val; | 602 | if (ret_val != 0) |
608 | ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, | 603 | return ret_val; |
609 | &netlbl_mgmt_genl_c_remove); | 604 | } |
610 | if (ret_val != 0) | ||
611 | return ret_val; | ||
612 | ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, | ||
613 | &netlbl_mgmt_genl_c_listall); | ||
614 | if (ret_val != 0) | ||
615 | return ret_val; | ||
616 | ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, | ||
617 | &netlbl_mgmt_genl_c_adddef); | ||
618 | if (ret_val != 0) | ||
619 | return ret_val; | ||
620 | ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, | ||
621 | &netlbl_mgmt_genl_c_removedef); | ||
622 | if (ret_val != 0) | ||
623 | return ret_val; | ||
624 | ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, | ||
625 | &netlbl_mgmt_genl_c_listdef); | ||
626 | if (ret_val != 0) | ||
627 | return ret_val; | ||
628 | ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, | ||
629 | &netlbl_mgmt_genl_c_protocols); | ||
630 | if (ret_val != 0) | ||
631 | return ret_val; | ||
632 | ret_val = genl_register_ops(&netlbl_mgmt_gnl_family, | ||
633 | &netlbl_mgmt_genl_c_version); | ||
634 | if (ret_val != 0) | ||
635 | return ret_val; | ||
636 | 605 | ||
637 | return 0; | 606 | return 0; |
638 | } | 607 | } |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 42e81fd8cc49..4478f2f6079d 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -180,6 +180,7 @@ static void netlbl_unlabel_audit_addr4(struct audit_buffer *audit_buf, | |||
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
183 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
183 | /** | 184 | /** |
184 | * netlbl_unlabel_audit_addr6 - Audit an IPv6 address | 185 | * netlbl_unlabel_audit_addr6 - Audit an IPv6 address |
185 | * @audit_buf: audit buffer | 186 | * @audit_buf: audit buffer |
@@ -213,6 +214,7 @@ static void netlbl_unlabel_audit_addr6(struct audit_buffer *audit_buf, | |||
213 | audit_log_format(audit_buf, " src_prefixlen=%d", mask_len); | 214 | audit_log_format(audit_buf, " src_prefixlen=%d", mask_len); |
214 | } | 215 | } |
215 | } | 216 | } |
217 | #endif /* IPv6 */ | ||
216 | 218 | ||
217 | /* | 219 | /* |
218 | * Unlabeled Connection Hash Table Functions | 220 | * Unlabeled Connection Hash Table Functions |
@@ -617,8 +619,6 @@ static int netlbl_unlhsh_add(struct net *net, | |||
617 | int ifindex; | 619 | int ifindex; |
618 | struct net_device *dev; | 620 | struct net_device *dev; |
619 | struct netlbl_unlhsh_iface *iface; | 621 | struct netlbl_unlhsh_iface *iface; |
620 | struct in_addr *addr4, *mask4; | ||
621 | struct in6_addr *addr6, *mask6; | ||
622 | struct audit_buffer *audit_buf = NULL; | 622 | struct audit_buffer *audit_buf = NULL; |
623 | char *secctx = NULL; | 623 | char *secctx = NULL; |
624 | u32 secctx_len; | 624 | u32 secctx_len; |
@@ -651,7 +651,9 @@ static int netlbl_unlhsh_add(struct net *net, | |||
651 | audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCADD, | 651 | audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCADD, |
652 | audit_info); | 652 | audit_info); |
653 | switch (addr_len) { | 653 | switch (addr_len) { |
654 | case sizeof(struct in_addr): | 654 | case sizeof(struct in_addr): { |
655 | struct in_addr *addr4, *mask4; | ||
656 | |||
655 | addr4 = (struct in_addr *)addr; | 657 | addr4 = (struct in_addr *)addr; |
656 | mask4 = (struct in_addr *)mask; | 658 | mask4 = (struct in_addr *)mask; |
657 | ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid); | 659 | ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid); |
@@ -661,8 +663,11 @@ static int netlbl_unlhsh_add(struct net *net, | |||
661 | addr4->s_addr, | 663 | addr4->s_addr, |
662 | mask4->s_addr); | 664 | mask4->s_addr); |
663 | break; | 665 | break; |
666 | } | ||
664 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 667 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
665 | case sizeof(struct in6_addr): | 668 | case sizeof(struct in6_addr): { |
669 | struct in6_addr *addr6, *mask6; | ||
670 | |||
666 | addr6 = (struct in6_addr *)addr; | 671 | addr6 = (struct in6_addr *)addr; |
667 | mask6 = (struct in6_addr *)mask; | 672 | mask6 = (struct in6_addr *)mask; |
668 | ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid); | 673 | ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid); |
@@ -671,6 +676,7 @@ static int netlbl_unlhsh_add(struct net *net, | |||
671 | dev_name, | 676 | dev_name, |
672 | addr6, mask6); | 677 | addr6, mask6); |
673 | break; | 678 | break; |
679 | } | ||
674 | #endif /* IPv6 */ | 680 | #endif /* IPv6 */ |
675 | default: | 681 | default: |
676 | ret_val = -EINVAL; | 682 | ret_val = -EINVAL; |
@@ -1547,68 +1553,63 @@ unlabel_staticlistdef_return: | |||
1547 | * NetLabel Generic NETLINK Command Definitions | 1553 | * NetLabel Generic NETLINK Command Definitions |
1548 | */ | 1554 | */ |
1549 | 1555 | ||
1550 | static struct genl_ops netlbl_unlabel_genl_c_staticadd = { | 1556 | static struct genl_ops netlbl_unlabel_genl_ops[] = { |
1557 | { | ||
1551 | .cmd = NLBL_UNLABEL_C_STATICADD, | 1558 | .cmd = NLBL_UNLABEL_C_STATICADD, |
1552 | .flags = GENL_ADMIN_PERM, | 1559 | .flags = GENL_ADMIN_PERM, |
1553 | .policy = netlbl_unlabel_genl_policy, | 1560 | .policy = netlbl_unlabel_genl_policy, |
1554 | .doit = netlbl_unlabel_staticadd, | 1561 | .doit = netlbl_unlabel_staticadd, |
1555 | .dumpit = NULL, | 1562 | .dumpit = NULL, |
1556 | }; | 1563 | }, |
1557 | 1564 | { | |
1558 | static struct genl_ops netlbl_unlabel_genl_c_staticremove = { | ||
1559 | .cmd = NLBL_UNLABEL_C_STATICREMOVE, | 1565 | .cmd = NLBL_UNLABEL_C_STATICREMOVE, |
1560 | .flags = GENL_ADMIN_PERM, | 1566 | .flags = GENL_ADMIN_PERM, |
1561 | .policy = netlbl_unlabel_genl_policy, | 1567 | .policy = netlbl_unlabel_genl_policy, |
1562 | .doit = netlbl_unlabel_staticremove, | 1568 | .doit = netlbl_unlabel_staticremove, |
1563 | .dumpit = NULL, | 1569 | .dumpit = NULL, |
1564 | }; | 1570 | }, |
1565 | 1571 | { | |
1566 | static struct genl_ops netlbl_unlabel_genl_c_staticlist = { | ||
1567 | .cmd = NLBL_UNLABEL_C_STATICLIST, | 1572 | .cmd = NLBL_UNLABEL_C_STATICLIST, |
1568 | .flags = 0, | 1573 | .flags = 0, |
1569 | .policy = netlbl_unlabel_genl_policy, | 1574 | .policy = netlbl_unlabel_genl_policy, |
1570 | .doit = NULL, | 1575 | .doit = NULL, |
1571 | .dumpit = netlbl_unlabel_staticlist, | 1576 | .dumpit = netlbl_unlabel_staticlist, |
1572 | }; | 1577 | }, |
1573 | 1578 | { | |
1574 | static struct genl_ops netlbl_unlabel_genl_c_staticadddef = { | ||
1575 | .cmd = NLBL_UNLABEL_C_STATICADDDEF, | 1579 | .cmd = NLBL_UNLABEL_C_STATICADDDEF, |
1576 | .flags = GENL_ADMIN_PERM, | 1580 | .flags = GENL_ADMIN_PERM, |
1577 | .policy = netlbl_unlabel_genl_policy, | 1581 | .policy = netlbl_unlabel_genl_policy, |
1578 | .doit = netlbl_unlabel_staticadddef, | 1582 | .doit = netlbl_unlabel_staticadddef, |
1579 | .dumpit = NULL, | 1583 | .dumpit = NULL, |
1580 | }; | 1584 | }, |
1581 | 1585 | { | |
1582 | static struct genl_ops netlbl_unlabel_genl_c_staticremovedef = { | ||
1583 | .cmd = NLBL_UNLABEL_C_STATICREMOVEDEF, | 1586 | .cmd = NLBL_UNLABEL_C_STATICREMOVEDEF, |
1584 | .flags = GENL_ADMIN_PERM, | 1587 | .flags = GENL_ADMIN_PERM, |
1585 | .policy = netlbl_unlabel_genl_policy, | 1588 | .policy = netlbl_unlabel_genl_policy, |
1586 | .doit = netlbl_unlabel_staticremovedef, | 1589 | .doit = netlbl_unlabel_staticremovedef, |
1587 | .dumpit = NULL, | 1590 | .dumpit = NULL, |
1588 | }; | 1591 | }, |
1589 | 1592 | { | |
1590 | static struct genl_ops netlbl_unlabel_genl_c_staticlistdef = { | ||
1591 | .cmd = NLBL_UNLABEL_C_STATICLISTDEF, | 1593 | .cmd = NLBL_UNLABEL_C_STATICLISTDEF, |
1592 | .flags = 0, | 1594 | .flags = 0, |
1593 | .policy = netlbl_unlabel_genl_policy, | 1595 | .policy = netlbl_unlabel_genl_policy, |
1594 | .doit = NULL, | 1596 | .doit = NULL, |
1595 | .dumpit = netlbl_unlabel_staticlistdef, | 1597 | .dumpit = netlbl_unlabel_staticlistdef, |
1596 | }; | 1598 | }, |
1597 | 1599 | { | |
1598 | static struct genl_ops netlbl_unlabel_genl_c_accept = { | ||
1599 | .cmd = NLBL_UNLABEL_C_ACCEPT, | 1600 | .cmd = NLBL_UNLABEL_C_ACCEPT, |
1600 | .flags = GENL_ADMIN_PERM, | 1601 | .flags = GENL_ADMIN_PERM, |
1601 | .policy = netlbl_unlabel_genl_policy, | 1602 | .policy = netlbl_unlabel_genl_policy, |
1602 | .doit = netlbl_unlabel_accept, | 1603 | .doit = netlbl_unlabel_accept, |
1603 | .dumpit = NULL, | 1604 | .dumpit = NULL, |
1604 | }; | 1605 | }, |
1605 | 1606 | { | |
1606 | static struct genl_ops netlbl_unlabel_genl_c_list = { | ||
1607 | .cmd = NLBL_UNLABEL_C_LIST, | 1607 | .cmd = NLBL_UNLABEL_C_LIST, |
1608 | .flags = 0, | 1608 | .flags = 0, |
1609 | .policy = netlbl_unlabel_genl_policy, | 1609 | .policy = netlbl_unlabel_genl_policy, |
1610 | .doit = netlbl_unlabel_list, | 1610 | .doit = netlbl_unlabel_list, |
1611 | .dumpit = NULL, | 1611 | .dumpit = NULL, |
1612 | }, | ||
1612 | }; | 1613 | }; |
1613 | 1614 | ||
1614 | /* | 1615 | /* |
@@ -1623,53 +1624,20 @@ static struct genl_ops netlbl_unlabel_genl_c_list = { | |||
1623 | * mechanism. Returns zero on success, negative values on failure. | 1624 | * mechanism. Returns zero on success, negative values on failure. |
1624 | * | 1625 | * |
1625 | */ | 1626 | */ |
1626 | int netlbl_unlabel_genl_init(void) | 1627 | int __init netlbl_unlabel_genl_init(void) |
1627 | { | 1628 | { |
1628 | int ret_val; | 1629 | int ret_val, i; |
1629 | 1630 | ||
1630 | ret_val = genl_register_family(&netlbl_unlabel_gnl_family); | 1631 | ret_val = genl_register_family(&netlbl_unlabel_gnl_family); |
1631 | if (ret_val != 0) | 1632 | if (ret_val != 0) |
1632 | return ret_val; | 1633 | return ret_val; |
1633 | 1634 | ||
1634 | ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, | 1635 | for (i = 0; i < ARRAY_SIZE(netlbl_unlabel_genl_ops); i++) { |
1635 | &netlbl_unlabel_genl_c_staticadd); | 1636 | ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, |
1636 | if (ret_val != 0) | 1637 | &netlbl_unlabel_genl_ops[i]); |
1637 | return ret_val; | 1638 | if (ret_val != 0) |
1638 | 1639 | return ret_val; | |
1639 | ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, | 1640 | } |
1640 | &netlbl_unlabel_genl_c_staticremove); | ||
1641 | if (ret_val != 0) | ||
1642 | return ret_val; | ||
1643 | |||
1644 | ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, | ||
1645 | &netlbl_unlabel_genl_c_staticlist); | ||
1646 | if (ret_val != 0) | ||
1647 | return ret_val; | ||
1648 | |||
1649 | ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, | ||
1650 | &netlbl_unlabel_genl_c_staticadddef); | ||
1651 | if (ret_val != 0) | ||
1652 | return ret_val; | ||
1653 | |||
1654 | ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, | ||
1655 | &netlbl_unlabel_genl_c_staticremovedef); | ||
1656 | if (ret_val != 0) | ||
1657 | return ret_val; | ||
1658 | |||
1659 | ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, | ||
1660 | &netlbl_unlabel_genl_c_staticlistdef); | ||
1661 | if (ret_val != 0) | ||
1662 | return ret_val; | ||
1663 | |||
1664 | ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, | ||
1665 | &netlbl_unlabel_genl_c_accept); | ||
1666 | if (ret_val != 0) | ||
1667 | return ret_val; | ||
1668 | |||
1669 | ret_val = genl_register_ops(&netlbl_unlabel_gnl_family, | ||
1670 | &netlbl_unlabel_genl_c_list); | ||
1671 | if (ret_val != 0) | ||
1672 | return ret_val; | ||
1673 | 1641 | ||
1674 | return 0; | 1642 | return 0; |
1675 | } | 1643 | } |
@@ -1693,7 +1661,7 @@ static struct notifier_block netlbl_unlhsh_netdev_notifier = { | |||
1693 | * non-zero values on error. | 1661 | * non-zero values on error. |
1694 | * | 1662 | * |
1695 | */ | 1663 | */ |
1696 | int netlbl_unlabel_init(u32 size) | 1664 | int __init netlbl_unlabel_init(u32 size) |
1697 | { | 1665 | { |
1698 | u32 iter; | 1666 | u32 iter; |
1699 | struct netlbl_unlhsh_tbl *hsh_tbl; | 1667 | struct netlbl_unlhsh_tbl *hsh_tbl; |
@@ -1741,10 +1709,6 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, | |||
1741 | u16 family, | 1709 | u16 family, |
1742 | struct netlbl_lsm_secattr *secattr) | 1710 | struct netlbl_lsm_secattr *secattr) |
1743 | { | 1711 | { |
1744 | struct iphdr *hdr4; | ||
1745 | struct ipv6hdr *hdr6; | ||
1746 | struct netlbl_unlhsh_addr4 *addr4; | ||
1747 | struct netlbl_unlhsh_addr6 *addr6; | ||
1748 | struct netlbl_unlhsh_iface *iface; | 1712 | struct netlbl_unlhsh_iface *iface; |
1749 | 1713 | ||
1750 | rcu_read_lock(); | 1714 | rcu_read_lock(); |
@@ -1752,21 +1716,29 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb, | |||
1752 | if (iface == NULL) | 1716 | if (iface == NULL) |
1753 | goto unlabel_getattr_nolabel; | 1717 | goto unlabel_getattr_nolabel; |
1754 | switch (family) { | 1718 | switch (family) { |
1755 | case PF_INET: | 1719 | case PF_INET: { |
1720 | struct iphdr *hdr4; | ||
1721 | struct netlbl_unlhsh_addr4 *addr4; | ||
1722 | |||
1756 | hdr4 = ip_hdr(skb); | 1723 | hdr4 = ip_hdr(skb); |
1757 | addr4 = netlbl_unlhsh_search_addr4(hdr4->saddr, iface); | 1724 | addr4 = netlbl_unlhsh_search_addr4(hdr4->saddr, iface); |
1758 | if (addr4 == NULL) | 1725 | if (addr4 == NULL) |
1759 | goto unlabel_getattr_nolabel; | 1726 | goto unlabel_getattr_nolabel; |
1760 | secattr->attr.secid = addr4->secid; | 1727 | secattr->attr.secid = addr4->secid; |
1761 | break; | 1728 | break; |
1729 | } | ||
1762 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 1730 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
1763 | case PF_INET6: | 1731 | case PF_INET6: { |
1732 | struct ipv6hdr *hdr6; | ||
1733 | struct netlbl_unlhsh_addr6 *addr6; | ||
1734 | |||
1764 | hdr6 = ipv6_hdr(skb); | 1735 | hdr6 = ipv6_hdr(skb); |
1765 | addr6 = netlbl_unlhsh_search_addr6(&hdr6->saddr, iface); | 1736 | addr6 = netlbl_unlhsh_search_addr6(&hdr6->saddr, iface); |
1766 | if (addr6 == NULL) | 1737 | if (addr6 == NULL) |
1767 | goto unlabel_getattr_nolabel; | 1738 | goto unlabel_getattr_nolabel; |
1768 | secattr->attr.secid = addr6->secid; | 1739 | secattr->attr.secid = addr6->secid; |
1769 | break; | 1740 | break; |
1741 | } | ||
1770 | #endif /* IPv6 */ | 1742 | #endif /* IPv6 */ |
1771 | default: | 1743 | default: |
1772 | goto unlabel_getattr_nolabel; | 1744 | goto unlabel_getattr_nolabel; |
@@ -1793,7 +1765,7 @@ unlabel_getattr_nolabel: | |||
1793 | * and to send unlabeled network traffic by default. | 1765 | * and to send unlabeled network traffic by default. |
1794 | * | 1766 | * |
1795 | */ | 1767 | */ |
1796 | int netlbl_unlabel_defconf(void) | 1768 | int __init netlbl_unlabel_defconf(void) |
1797 | { | 1769 | { |
1798 | int ret_val; | 1770 | int ret_val; |
1799 | struct netlbl_dom_map *entry; | 1771 | struct netlbl_dom_map *entry; |
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index 85a96a3fddaa..b17d4203806e 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c | |||
@@ -59,7 +59,7 @@ | |||
59 | * non-zero on failure. | 59 | * non-zero on failure. |
60 | * | 60 | * |
61 | */ | 61 | */ |
62 | int netlbl_netlink_init(void) | 62 | int __init netlbl_netlink_init(void) |
63 | { | 63 | { |
64 | int ret_val; | 64 | int ret_val; |
65 | 65 | ||
@@ -96,7 +96,6 @@ int netlbl_netlink_init(void) | |||
96 | struct audit_buffer *netlbl_audit_start_common(int type, | 96 | struct audit_buffer *netlbl_audit_start_common(int type, |
97 | struct netlbl_audit *audit_info) | 97 | struct netlbl_audit *audit_info) |
98 | { | 98 | { |
99 | struct audit_context *audit_ctx = current->audit_context; | ||
100 | struct audit_buffer *audit_buf; | 99 | struct audit_buffer *audit_buf; |
101 | char *secctx; | 100 | char *secctx; |
102 | u32 secctx_len; | 101 | u32 secctx_len; |
@@ -104,7 +103,7 @@ struct audit_buffer *netlbl_audit_start_common(int type, | |||
104 | if (audit_enabled == 0) | 103 | if (audit_enabled == 0) |
105 | return NULL; | 104 | return NULL; |
106 | 105 | ||
107 | audit_buf = audit_log_start(audit_ctx, GFP_ATOMIC, type); | 106 | audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, type); |
108 | if (audit_buf == NULL) | 107 | if (audit_buf == NULL) |
109 | return NULL; | 108 | return NULL; |
110 | 109 | ||
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 150579a21469..d16929c9b4bc 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -230,10 +230,8 @@ static void genl_unregister_mc_groups(struct genl_family *family) | |||
230 | { | 230 | { |
231 | struct genl_multicast_group *grp, *tmp; | 231 | struct genl_multicast_group *grp, *tmp; |
232 | 232 | ||
233 | genl_lock(); | ||
234 | list_for_each_entry_safe(grp, tmp, &family->mcast_groups, list) | 233 | list_for_each_entry_safe(grp, tmp, &family->mcast_groups, list) |
235 | __genl_unregister_mc_group(family, grp); | 234 | __genl_unregister_mc_group(family, grp); |
236 | genl_unlock(); | ||
237 | } | 235 | } |
238 | 236 | ||
239 | /** | 237 | /** |
@@ -396,10 +394,10 @@ int genl_unregister_family(struct genl_family *family) | |||
396 | { | 394 | { |
397 | struct genl_family *rc; | 395 | struct genl_family *rc; |
398 | 396 | ||
399 | genl_unregister_mc_groups(family); | ||
400 | |||
401 | genl_lock(); | 397 | genl_lock(); |
402 | 398 | ||
399 | genl_unregister_mc_groups(family); | ||
400 | |||
403 | list_for_each_entry(rc, genl_family_chain(family->id), family_list) { | 401 | list_for_each_entry(rc, genl_family_chain(family->id), family_list) { |
404 | if (family->id != rc->id || strcmp(rc->name, family->name)) | 402 | if (family->id != rc->id || strcmp(rc->name, family->name)) |
405 | continue; | 403 | continue; |
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 1a47f5d1be17..140a0a8c6b02 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c | |||
@@ -232,7 +232,7 @@ static int rfkill_suspend(struct device *dev, pm_message_t state) | |||
232 | struct rfkill *rfkill = to_rfkill(dev); | 232 | struct rfkill *rfkill = to_rfkill(dev); |
233 | 233 | ||
234 | if (dev->power.power_state.event != state.event) { | 234 | if (dev->power.power_state.event != state.event) { |
235 | if (state.event == PM_EVENT_SUSPEND) { | 235 | if (state.event & PM_EVENT_SLEEP) { |
236 | mutex_lock(&rfkill->mutex); | 236 | mutex_lock(&rfkill->mutex); |
237 | 237 | ||
238 | if (rfkill->state == RFKILL_STATE_ON) | 238 | if (rfkill->state == RFKILL_STATE_ON) |
diff --git a/net/rxrpc/ar-accept.c b/net/rxrpc/ar-accept.c index 92a87fde8bfe..bdfb77417794 100644 --- a/net/rxrpc/ar-accept.c +++ b/net/rxrpc/ar-accept.c | |||
@@ -156,8 +156,7 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local, | |||
156 | false); | 156 | false); |
157 | spin_unlock(&call->lock); | 157 | spin_unlock(&call->lock); |
158 | notification = NULL; | 158 | notification = NULL; |
159 | if (ret < 0) | 159 | BUG_ON(ret < 0); |
160 | BUG(); | ||
161 | } | 160 | } |
162 | spin_unlock(&call->conn->state_lock); | 161 | spin_unlock(&call->conn->state_lock); |
163 | 162 | ||
diff --git a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c index 657ee69f2133..3ac1672e1070 100644 --- a/net/rxrpc/ar-ack.c +++ b/net/rxrpc/ar-ack.c | |||
@@ -814,8 +814,7 @@ static int rxrpc_post_message(struct rxrpc_call *call, u32 mark, u32 error, | |||
814 | spin_lock_bh(&call->lock); | 814 | spin_lock_bh(&call->lock); |
815 | ret = rxrpc_queue_rcv_skb(call, skb, true, fatal); | 815 | ret = rxrpc_queue_rcv_skb(call, skb, true, fatal); |
816 | spin_unlock_bh(&call->lock); | 816 | spin_unlock_bh(&call->lock); |
817 | if (ret < 0) | 817 | BUG_ON(ret < 0); |
818 | BUG(); | ||
819 | } | 818 | } |
820 | 819 | ||
821 | return 0; | 820 | return 0; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index d47d5787e2e5..44797ad88a05 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -6488,6 +6488,7 @@ struct proto sctp_prot = { | |||
6488 | .memory_pressure = &sctp_memory_pressure, | 6488 | .memory_pressure = &sctp_memory_pressure, |
6489 | .enter_memory_pressure = sctp_enter_memory_pressure, | 6489 | .enter_memory_pressure = sctp_enter_memory_pressure, |
6490 | .memory_allocated = &sctp_memory_allocated, | 6490 | .memory_allocated = &sctp_memory_allocated, |
6491 | .sockets_allocated = &sctp_sockets_allocated, | ||
6491 | REF_PROTO_INUSE(sctp) | 6492 | REF_PROTO_INUSE(sctp) |
6492 | }; | 6493 | }; |
6493 | 6494 | ||
@@ -6521,6 +6522,7 @@ struct proto sctpv6_prot = { | |||
6521 | .memory_pressure = &sctp_memory_pressure, | 6522 | .memory_pressure = &sctp_memory_pressure, |
6522 | .enter_memory_pressure = sctp_enter_memory_pressure, | 6523 | .enter_memory_pressure = sctp_enter_memory_pressure, |
6523 | .memory_allocated = &sctp_memory_allocated, | 6524 | .memory_allocated = &sctp_memory_allocated, |
6525 | .sockets_allocated = &sctp_sockets_allocated, | ||
6524 | REF_PROTO_INUSE(sctpv6) | 6526 | REF_PROTO_INUSE(sctpv6) |
6525 | }; | 6527 | }; |
6526 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | 6528 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ |
diff --git a/net/socket.c b/net/socket.c index 7651de008502..b6d35cd72a50 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -701,6 +701,9 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos, | |||
701 | { | 701 | { |
702 | struct socket *sock = file->private_data; | 702 | struct socket *sock = file->private_data; |
703 | 703 | ||
704 | if (unlikely(!sock->ops->splice_read)) | ||
705 | return -EINVAL; | ||
706 | |||
704 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); | 707 | return sock->ops->splice_read(sock, ppos, pipe, len, flags); |
705 | } | 708 | } |
706 | 709 | ||
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 6dac38792288..ef6384961808 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -266,6 +266,7 @@ gss_release_msg(struct gss_upcall_msg *gss_msg) | |||
266 | BUG_ON(!list_empty(&gss_msg->list)); | 266 | BUG_ON(!list_empty(&gss_msg->list)); |
267 | if (gss_msg->ctx != NULL) | 267 | if (gss_msg->ctx != NULL) |
268 | gss_put_ctx(gss_msg->ctx); | 268 | gss_put_ctx(gss_msg->ctx); |
269 | rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue); | ||
269 | kfree(gss_msg); | 270 | kfree(gss_msg); |
270 | } | 271 | } |
271 | 272 | ||
@@ -408,13 +409,13 @@ gss_refresh_upcall(struct rpc_task *task) | |||
408 | } | 409 | } |
409 | spin_lock(&inode->i_lock); | 410 | spin_lock(&inode->i_lock); |
410 | if (gss_cred->gc_upcall != NULL) | 411 | if (gss_cred->gc_upcall != NULL) |
411 | rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL, NULL); | 412 | rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL); |
412 | else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) { | 413 | else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) { |
413 | task->tk_timeout = 0; | 414 | task->tk_timeout = 0; |
414 | gss_cred->gc_upcall = gss_msg; | 415 | gss_cred->gc_upcall = gss_msg; |
415 | /* gss_upcall_callback will release the reference to gss_upcall_msg */ | 416 | /* gss_upcall_callback will release the reference to gss_upcall_msg */ |
416 | atomic_inc(&gss_msg->count); | 417 | atomic_inc(&gss_msg->count); |
417 | rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback, NULL); | 418 | rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback); |
418 | } else | 419 | } else |
419 | err = gss_msg->msg.errno; | 420 | err = gss_msg->msg.errno; |
420 | spin_unlock(&inode->i_lock); | 421 | spin_unlock(&inode->i_lock); |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index a23512bb240d..ea14314331b0 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -1066,7 +1066,7 @@ call_transmit(struct rpc_task *task) | |||
1066 | if (task->tk_msg.rpc_proc->p_decode != NULL) | 1066 | if (task->tk_msg.rpc_proc->p_decode != NULL) |
1067 | return; | 1067 | return; |
1068 | task->tk_action = rpc_exit_task; | 1068 | task->tk_action = rpc_exit_task; |
1069 | rpc_wake_up_task(task); | 1069 | rpc_wake_up_queued_task(&task->tk_xprt->pending, task); |
1070 | } | 1070 | } |
1071 | 1071 | ||
1072 | /* | 1072 | /* |
@@ -1535,7 +1535,7 @@ void rpc_show_tasks(void) | |||
1535 | proc = -1; | 1535 | proc = -1; |
1536 | 1536 | ||
1537 | if (RPC_IS_QUEUED(t)) | 1537 | if (RPC_IS_QUEUED(t)) |
1538 | rpc_waitq = rpc_qname(t->u.tk_wait.rpc_waitq); | 1538 | rpc_waitq = rpc_qname(t->tk_waitqueue); |
1539 | 1539 | ||
1540 | printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n", | 1540 | printk("%5u %04d %04x %6d %8p %6d %8p %8ld %8s %8p %8p\n", |
1541 | t->tk_pid, proc, | 1541 | t->tk_pid, proc, |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 0e3ead7e11b9..1b395a41a8b2 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -495,7 +495,7 @@ rpc_lookup_parent(char *path, struct nameidata *nd) | |||
495 | static void | 495 | static void |
496 | rpc_release_path(struct nameidata *nd) | 496 | rpc_release_path(struct nameidata *nd) |
497 | { | 497 | { |
498 | path_release(nd); | 498 | path_put(&nd->path); |
499 | rpc_put_mount(); | 499 | rpc_put_mount(); |
500 | } | 500 | } |
501 | 501 | ||
@@ -668,7 +668,8 @@ rpc_lookup_negative(char *path, struct nameidata *nd) | |||
668 | 668 | ||
669 | if ((error = rpc_lookup_parent(path, nd)) != 0) | 669 | if ((error = rpc_lookup_parent(path, nd)) != 0) |
670 | return ERR_PTR(error); | 670 | return ERR_PTR(error); |
671 | dentry = rpc_lookup_create(nd->dentry, nd->last.name, nd->last.len, 1); | 671 | dentry = rpc_lookup_create(nd->path.dentry, nd->last.name, nd->last.len, |
672 | 1); | ||
672 | if (IS_ERR(dentry)) | 673 | if (IS_ERR(dentry)) |
673 | rpc_release_path(nd); | 674 | rpc_release_path(nd); |
674 | return dentry; | 675 | return dentry; |
@@ -695,7 +696,7 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client) | |||
695 | dentry = rpc_lookup_negative(path, &nd); | 696 | dentry = rpc_lookup_negative(path, &nd); |
696 | if (IS_ERR(dentry)) | 697 | if (IS_ERR(dentry)) |
697 | return dentry; | 698 | return dentry; |
698 | dir = nd.dentry->d_inode; | 699 | dir = nd.path.dentry->d_inode; |
699 | if ((error = __rpc_mkdir(dir, dentry)) != 0) | 700 | if ((error = __rpc_mkdir(dir, dentry)) != 0) |
700 | goto err_dput; | 701 | goto err_dput; |
701 | RPC_I(dentry->d_inode)->private = rpc_client; | 702 | RPC_I(dentry->d_inode)->private = rpc_client; |
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 3164a0871cf0..f480c718b400 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
@@ -298,7 +298,7 @@ void rpcb_getport_async(struct rpc_task *task) | |||
298 | 298 | ||
299 | /* Put self on queue before sending rpcbind request, in case | 299 | /* Put self on queue before sending rpcbind request, in case |
300 | * rpcb_getport_done completes before we return from rpc_run_task */ | 300 | * rpcb_getport_done completes before we return from rpc_run_task */ |
301 | rpc_sleep_on(&xprt->binding, task, NULL, NULL); | 301 | rpc_sleep_on(&xprt->binding, task, NULL); |
302 | 302 | ||
303 | /* Someone else may have bound if we slept */ | 303 | /* Someone else may have bound if we slept */ |
304 | if (xprt_bound(xprt)) { | 304 | if (xprt_bound(xprt)) { |
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 4c669121e607..cae219c8caeb 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -38,9 +38,9 @@ static struct kmem_cache *rpc_buffer_slabp __read_mostly; | |||
38 | static mempool_t *rpc_task_mempool __read_mostly; | 38 | static mempool_t *rpc_task_mempool __read_mostly; |
39 | static mempool_t *rpc_buffer_mempool __read_mostly; | 39 | static mempool_t *rpc_buffer_mempool __read_mostly; |
40 | 40 | ||
41 | static void __rpc_default_timer(struct rpc_task *task); | ||
42 | static void rpc_async_schedule(struct work_struct *); | 41 | static void rpc_async_schedule(struct work_struct *); |
43 | static void rpc_release_task(struct rpc_task *task); | 42 | static void rpc_release_task(struct rpc_task *task); |
43 | static void __rpc_queue_timer_fn(unsigned long ptr); | ||
44 | 44 | ||
45 | /* | 45 | /* |
46 | * RPC tasks sit here while waiting for conditions to improve. | 46 | * RPC tasks sit here while waiting for conditions to improve. |
@@ -57,41 +57,30 @@ struct workqueue_struct *rpciod_workqueue; | |||
57 | * queue->lock and bh_disabled in order to avoid races within | 57 | * queue->lock and bh_disabled in order to avoid races within |
58 | * rpc_run_timer(). | 58 | * rpc_run_timer(). |
59 | */ | 59 | */ |
60 | static inline void | 60 | static void |
61 | __rpc_disable_timer(struct rpc_task *task) | 61 | __rpc_disable_timer(struct rpc_wait_queue *queue, struct rpc_task *task) |
62 | { | 62 | { |
63 | if (task->tk_timeout == 0) | ||
64 | return; | ||
63 | dprintk("RPC: %5u disabling timer\n", task->tk_pid); | 65 | dprintk("RPC: %5u disabling timer\n", task->tk_pid); |
64 | task->tk_timeout_fn = NULL; | ||
65 | task->tk_timeout = 0; | 66 | task->tk_timeout = 0; |
67 | list_del(&task->u.tk_wait.timer_list); | ||
68 | if (list_empty(&queue->timer_list.list)) | ||
69 | del_timer(&queue->timer_list.timer); | ||
66 | } | 70 | } |
67 | 71 | ||
68 | /* | 72 | static void |
69 | * Run a timeout function. | 73 | rpc_set_queue_timer(struct rpc_wait_queue *queue, unsigned long expires) |
70 | * We use the callback in order to allow __rpc_wake_up_task() | ||
71 | * and friends to disable the timer synchronously on SMP systems | ||
72 | * without calling del_timer_sync(). The latter could cause a | ||
73 | * deadlock if called while we're holding spinlocks... | ||
74 | */ | ||
75 | static void rpc_run_timer(struct rpc_task *task) | ||
76 | { | 74 | { |
77 | void (*callback)(struct rpc_task *); | 75 | queue->timer_list.expires = expires; |
78 | 76 | mod_timer(&queue->timer_list.timer, expires); | |
79 | callback = task->tk_timeout_fn; | ||
80 | task->tk_timeout_fn = NULL; | ||
81 | if (callback && RPC_IS_QUEUED(task)) { | ||
82 | dprintk("RPC: %5u running timer\n", task->tk_pid); | ||
83 | callback(task); | ||
84 | } | ||
85 | smp_mb__before_clear_bit(); | ||
86 | clear_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate); | ||
87 | smp_mb__after_clear_bit(); | ||
88 | } | 77 | } |
89 | 78 | ||
90 | /* | 79 | /* |
91 | * Set up a timer for the current task. | 80 | * Set up a timer for the current task. |
92 | */ | 81 | */ |
93 | static inline void | 82 | static void |
94 | __rpc_add_timer(struct rpc_task *task, rpc_action timer) | 83 | __rpc_add_timer(struct rpc_wait_queue *queue, struct rpc_task *task) |
95 | { | 84 | { |
96 | if (!task->tk_timeout) | 85 | if (!task->tk_timeout) |
97 | return; | 86 | return; |
@@ -99,27 +88,10 @@ __rpc_add_timer(struct rpc_task *task, rpc_action timer) | |||
99 | dprintk("RPC: %5u setting alarm for %lu ms\n", | 88 | dprintk("RPC: %5u setting alarm for %lu ms\n", |
100 | task->tk_pid, task->tk_timeout * 1000 / HZ); | 89 | task->tk_pid, task->tk_timeout * 1000 / HZ); |
101 | 90 | ||
102 | if (timer) | 91 | task->u.tk_wait.expires = jiffies + task->tk_timeout; |
103 | task->tk_timeout_fn = timer; | 92 | if (list_empty(&queue->timer_list.list) || time_before(task->u.tk_wait.expires, queue->timer_list.expires)) |
104 | else | 93 | rpc_set_queue_timer(queue, task->u.tk_wait.expires); |
105 | task->tk_timeout_fn = __rpc_default_timer; | 94 | list_add(&task->u.tk_wait.timer_list, &queue->timer_list.list); |
106 | set_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate); | ||
107 | mod_timer(&task->tk_timer, jiffies + task->tk_timeout); | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Delete any timer for the current task. Because we use del_timer_sync(), | ||
112 | * this function should never be called while holding queue->lock. | ||
113 | */ | ||
114 | static void | ||
115 | rpc_delete_timer(struct rpc_task *task) | ||
116 | { | ||
117 | if (RPC_IS_QUEUED(task)) | ||
118 | return; | ||
119 | if (test_and_clear_bit(RPC_TASK_HAS_TIMER, &task->tk_runstate)) { | ||
120 | del_singleshot_timer_sync(&task->tk_timer); | ||
121 | dprintk("RPC: %5u deleting timer\n", task->tk_pid); | ||
122 | } | ||
123 | } | 95 | } |
124 | 96 | ||
125 | /* | 97 | /* |
@@ -161,7 +133,7 @@ static void __rpc_add_wait_queue(struct rpc_wait_queue *queue, struct rpc_task * | |||
161 | list_add(&task->u.tk_wait.list, &queue->tasks[0]); | 133 | list_add(&task->u.tk_wait.list, &queue->tasks[0]); |
162 | else | 134 | else |
163 | list_add_tail(&task->u.tk_wait.list, &queue->tasks[0]); | 135 | list_add_tail(&task->u.tk_wait.list, &queue->tasks[0]); |
164 | task->u.tk_wait.rpc_waitq = queue; | 136 | task->tk_waitqueue = queue; |
165 | queue->qlen++; | 137 | queue->qlen++; |
166 | rpc_set_queued(task); | 138 | rpc_set_queued(task); |
167 | 139 | ||
@@ -181,22 +153,18 @@ static void __rpc_remove_wait_queue_priority(struct rpc_task *task) | |||
181 | list_move(&t->u.tk_wait.list, &task->u.tk_wait.list); | 153 | list_move(&t->u.tk_wait.list, &task->u.tk_wait.list); |
182 | list_splice_init(&task->u.tk_wait.links, &t->u.tk_wait.links); | 154 | list_splice_init(&task->u.tk_wait.links, &t->u.tk_wait.links); |
183 | } | 155 | } |
184 | list_del(&task->u.tk_wait.list); | ||
185 | } | 156 | } |
186 | 157 | ||
187 | /* | 158 | /* |
188 | * Remove request from queue. | 159 | * Remove request from queue. |
189 | * Note: must be called with spin lock held. | 160 | * Note: must be called with spin lock held. |
190 | */ | 161 | */ |
191 | static void __rpc_remove_wait_queue(struct rpc_task *task) | 162 | static void __rpc_remove_wait_queue(struct rpc_wait_queue *queue, struct rpc_task *task) |
192 | { | 163 | { |
193 | struct rpc_wait_queue *queue; | 164 | __rpc_disable_timer(queue, task); |
194 | queue = task->u.tk_wait.rpc_waitq; | ||
195 | |||
196 | if (RPC_IS_PRIORITY(queue)) | 165 | if (RPC_IS_PRIORITY(queue)) |
197 | __rpc_remove_wait_queue_priority(task); | 166 | __rpc_remove_wait_queue_priority(task); |
198 | else | 167 | list_del(&task->u.tk_wait.list); |
199 | list_del(&task->u.tk_wait.list); | ||
200 | queue->qlen--; | 168 | queue->qlen--; |
201 | dprintk("RPC: %5u removed from queue %p \"%s\"\n", | 169 | dprintk("RPC: %5u removed from queue %p \"%s\"\n", |
202 | task->tk_pid, queue, rpc_qname(queue)); | 170 | task->tk_pid, queue, rpc_qname(queue)); |
@@ -229,6 +197,9 @@ static void __rpc_init_priority_wait_queue(struct rpc_wait_queue *queue, const c | |||
229 | INIT_LIST_HEAD(&queue->tasks[i]); | 197 | INIT_LIST_HEAD(&queue->tasks[i]); |
230 | queue->maxpriority = nr_queues - 1; | 198 | queue->maxpriority = nr_queues - 1; |
231 | rpc_reset_waitqueue_priority(queue); | 199 | rpc_reset_waitqueue_priority(queue); |
200 | queue->qlen = 0; | ||
201 | setup_timer(&queue->timer_list.timer, __rpc_queue_timer_fn, (unsigned long)queue); | ||
202 | INIT_LIST_HEAD(&queue->timer_list.list); | ||
232 | #ifdef RPC_DEBUG | 203 | #ifdef RPC_DEBUG |
233 | queue->name = qname; | 204 | queue->name = qname; |
234 | #endif | 205 | #endif |
@@ -245,6 +216,12 @@ void rpc_init_wait_queue(struct rpc_wait_queue *queue, const char *qname) | |||
245 | } | 216 | } |
246 | EXPORT_SYMBOL_GPL(rpc_init_wait_queue); | 217 | EXPORT_SYMBOL_GPL(rpc_init_wait_queue); |
247 | 218 | ||
219 | void rpc_destroy_wait_queue(struct rpc_wait_queue *queue) | ||
220 | { | ||
221 | del_timer_sync(&queue->timer_list.timer); | ||
222 | } | ||
223 | EXPORT_SYMBOL_GPL(rpc_destroy_wait_queue); | ||
224 | |||
248 | static int rpc_wait_bit_killable(void *word) | 225 | static int rpc_wait_bit_killable(void *word) |
249 | { | 226 | { |
250 | if (fatal_signal_pending(current)) | 227 | if (fatal_signal_pending(current)) |
@@ -313,7 +290,6 @@ EXPORT_SYMBOL_GPL(__rpc_wait_for_completion_task); | |||
313 | */ | 290 | */ |
314 | static void rpc_make_runnable(struct rpc_task *task) | 291 | static void rpc_make_runnable(struct rpc_task *task) |
315 | { | 292 | { |
316 | BUG_ON(task->tk_timeout_fn); | ||
317 | rpc_clear_queued(task); | 293 | rpc_clear_queued(task); |
318 | if (rpc_test_and_set_running(task)) | 294 | if (rpc_test_and_set_running(task)) |
319 | return; | 295 | return; |
@@ -326,7 +302,7 @@ static void rpc_make_runnable(struct rpc_task *task) | |||
326 | int status; | 302 | int status; |
327 | 303 | ||
328 | INIT_WORK(&task->u.tk_work, rpc_async_schedule); | 304 | INIT_WORK(&task->u.tk_work, rpc_async_schedule); |
329 | status = queue_work(task->tk_workqueue, &task->u.tk_work); | 305 | status = queue_work(rpciod_workqueue, &task->u.tk_work); |
330 | if (status < 0) { | 306 | if (status < 0) { |
331 | printk(KERN_WARNING "RPC: failed to add task to queue: error: %d!\n", status); | 307 | printk(KERN_WARNING "RPC: failed to add task to queue: error: %d!\n", status); |
332 | task->tk_status = status; | 308 | task->tk_status = status; |
@@ -343,7 +319,7 @@ static void rpc_make_runnable(struct rpc_task *task) | |||
343 | * as it's on a wait queue. | 319 | * as it's on a wait queue. |
344 | */ | 320 | */ |
345 | static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | 321 | static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, |
346 | rpc_action action, rpc_action timer) | 322 | rpc_action action) |
347 | { | 323 | { |
348 | dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n", | 324 | dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n", |
349 | task->tk_pid, rpc_qname(q), jiffies); | 325 | task->tk_pid, rpc_qname(q), jiffies); |
@@ -357,11 +333,11 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | |||
357 | 333 | ||
358 | BUG_ON(task->tk_callback != NULL); | 334 | BUG_ON(task->tk_callback != NULL); |
359 | task->tk_callback = action; | 335 | task->tk_callback = action; |
360 | __rpc_add_timer(task, timer); | 336 | __rpc_add_timer(q, task); |
361 | } | 337 | } |
362 | 338 | ||
363 | void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | 339 | void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, |
364 | rpc_action action, rpc_action timer) | 340 | rpc_action action) |
365 | { | 341 | { |
366 | /* Mark the task as being activated if so needed */ | 342 | /* Mark the task as being activated if so needed */ |
367 | rpc_set_active(task); | 343 | rpc_set_active(task); |
@@ -370,18 +346,19 @@ void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | |||
370 | * Protect the queue operations. | 346 | * Protect the queue operations. |
371 | */ | 347 | */ |
372 | spin_lock_bh(&q->lock); | 348 | spin_lock_bh(&q->lock); |
373 | __rpc_sleep_on(q, task, action, timer); | 349 | __rpc_sleep_on(q, task, action); |
374 | spin_unlock_bh(&q->lock); | 350 | spin_unlock_bh(&q->lock); |
375 | } | 351 | } |
376 | EXPORT_SYMBOL_GPL(rpc_sleep_on); | 352 | EXPORT_SYMBOL_GPL(rpc_sleep_on); |
377 | 353 | ||
378 | /** | 354 | /** |
379 | * __rpc_do_wake_up_task - wake up a single rpc_task | 355 | * __rpc_do_wake_up_task - wake up a single rpc_task |
356 | * @queue: wait queue | ||
380 | * @task: task to be woken up | 357 | * @task: task to be woken up |
381 | * | 358 | * |
382 | * Caller must hold queue->lock, and have cleared the task queued flag. | 359 | * Caller must hold queue->lock, and have cleared the task queued flag. |
383 | */ | 360 | */ |
384 | static void __rpc_do_wake_up_task(struct rpc_task *task) | 361 | static void __rpc_do_wake_up_task(struct rpc_wait_queue *queue, struct rpc_task *task) |
385 | { | 362 | { |
386 | dprintk("RPC: %5u __rpc_wake_up_task (now %lu)\n", | 363 | dprintk("RPC: %5u __rpc_wake_up_task (now %lu)\n", |
387 | task->tk_pid, jiffies); | 364 | task->tk_pid, jiffies); |
@@ -395,8 +372,7 @@ static void __rpc_do_wake_up_task(struct rpc_task *task) | |||
395 | return; | 372 | return; |
396 | } | 373 | } |
397 | 374 | ||
398 | __rpc_disable_timer(task); | 375 | __rpc_remove_wait_queue(queue, task); |
399 | __rpc_remove_wait_queue(task); | ||
400 | 376 | ||
401 | rpc_make_runnable(task); | 377 | rpc_make_runnable(task); |
402 | 378 | ||
@@ -404,48 +380,32 @@ static void __rpc_do_wake_up_task(struct rpc_task *task) | |||
404 | } | 380 | } |
405 | 381 | ||
406 | /* | 382 | /* |
407 | * Wake up the specified task | 383 | * Wake up a queued task while the queue lock is being held |
408 | */ | 384 | */ |
409 | static void __rpc_wake_up_task(struct rpc_task *task) | 385 | static void rpc_wake_up_task_queue_locked(struct rpc_wait_queue *queue, struct rpc_task *task) |
410 | { | 386 | { |
411 | if (rpc_start_wakeup(task)) { | 387 | if (RPC_IS_QUEUED(task) && task->tk_waitqueue == queue) |
412 | if (RPC_IS_QUEUED(task)) | 388 | __rpc_do_wake_up_task(queue, task); |
413 | __rpc_do_wake_up_task(task); | ||
414 | rpc_finish_wakeup(task); | ||
415 | } | ||
416 | } | 389 | } |
417 | 390 | ||
418 | /* | 391 | /* |
419 | * Default timeout handler if none specified by user | 392 | * Wake up a task on a specific queue |
420 | */ | 393 | */ |
421 | static void | 394 | void rpc_wake_up_queued_task(struct rpc_wait_queue *queue, struct rpc_task *task) |
422 | __rpc_default_timer(struct rpc_task *task) | ||
423 | { | 395 | { |
424 | dprintk("RPC: %5u timeout (default timer)\n", task->tk_pid); | 396 | spin_lock_bh(&queue->lock); |
425 | task->tk_status = -ETIMEDOUT; | 397 | rpc_wake_up_task_queue_locked(queue, task); |
426 | rpc_wake_up_task(task); | 398 | spin_unlock_bh(&queue->lock); |
427 | } | 399 | } |
400 | EXPORT_SYMBOL_GPL(rpc_wake_up_queued_task); | ||
428 | 401 | ||
429 | /* | 402 | /* |
430 | * Wake up the specified task | 403 | * Wake up the specified task |
431 | */ | 404 | */ |
432 | void rpc_wake_up_task(struct rpc_task *task) | 405 | static void rpc_wake_up_task(struct rpc_task *task) |
433 | { | 406 | { |
434 | rcu_read_lock_bh(); | 407 | rpc_wake_up_queued_task(task->tk_waitqueue, task); |
435 | if (rpc_start_wakeup(task)) { | ||
436 | if (RPC_IS_QUEUED(task)) { | ||
437 | struct rpc_wait_queue *queue = task->u.tk_wait.rpc_waitq; | ||
438 | |||
439 | /* Note: we're already in a bh-safe context */ | ||
440 | spin_lock(&queue->lock); | ||
441 | __rpc_do_wake_up_task(task); | ||
442 | spin_unlock(&queue->lock); | ||
443 | } | ||
444 | rpc_finish_wakeup(task); | ||
445 | } | ||
446 | rcu_read_unlock_bh(); | ||
447 | } | 408 | } |
448 | EXPORT_SYMBOL_GPL(rpc_wake_up_task); | ||
449 | 409 | ||
450 | /* | 410 | /* |
451 | * Wake up the next task on a priority queue. | 411 | * Wake up the next task on a priority queue. |
@@ -495,7 +455,7 @@ new_queue: | |||
495 | new_owner: | 455 | new_owner: |
496 | rpc_set_waitqueue_owner(queue, task->tk_owner); | 456 | rpc_set_waitqueue_owner(queue, task->tk_owner); |
497 | out: | 457 | out: |
498 | __rpc_wake_up_task(task); | 458 | rpc_wake_up_task_queue_locked(queue, task); |
499 | return task; | 459 | return task; |
500 | } | 460 | } |
501 | 461 | ||
@@ -508,16 +468,14 @@ struct rpc_task * rpc_wake_up_next(struct rpc_wait_queue *queue) | |||
508 | 468 | ||
509 | dprintk("RPC: wake_up_next(%p \"%s\")\n", | 469 | dprintk("RPC: wake_up_next(%p \"%s\")\n", |
510 | queue, rpc_qname(queue)); | 470 | queue, rpc_qname(queue)); |
511 | rcu_read_lock_bh(); | 471 | spin_lock_bh(&queue->lock); |
512 | spin_lock(&queue->lock); | ||
513 | if (RPC_IS_PRIORITY(queue)) | 472 | if (RPC_IS_PRIORITY(queue)) |
514 | task = __rpc_wake_up_next_priority(queue); | 473 | task = __rpc_wake_up_next_priority(queue); |
515 | else { | 474 | else { |
516 | task_for_first(task, &queue->tasks[0]) | 475 | task_for_first(task, &queue->tasks[0]) |
517 | __rpc_wake_up_task(task); | 476 | rpc_wake_up_task_queue_locked(queue, task); |
518 | } | 477 | } |
519 | spin_unlock(&queue->lock); | 478 | spin_unlock_bh(&queue->lock); |
520 | rcu_read_unlock_bh(); | ||
521 | 479 | ||
522 | return task; | 480 | return task; |
523 | } | 481 | } |
@@ -534,18 +492,16 @@ void rpc_wake_up(struct rpc_wait_queue *queue) | |||
534 | struct rpc_task *task, *next; | 492 | struct rpc_task *task, *next; |
535 | struct list_head *head; | 493 | struct list_head *head; |
536 | 494 | ||
537 | rcu_read_lock_bh(); | 495 | spin_lock_bh(&queue->lock); |
538 | spin_lock(&queue->lock); | ||
539 | head = &queue->tasks[queue->maxpriority]; | 496 | head = &queue->tasks[queue->maxpriority]; |
540 | for (;;) { | 497 | for (;;) { |
541 | list_for_each_entry_safe(task, next, head, u.tk_wait.list) | 498 | list_for_each_entry_safe(task, next, head, u.tk_wait.list) |
542 | __rpc_wake_up_task(task); | 499 | rpc_wake_up_task_queue_locked(queue, task); |
543 | if (head == &queue->tasks[0]) | 500 | if (head == &queue->tasks[0]) |
544 | break; | 501 | break; |
545 | head--; | 502 | head--; |
546 | } | 503 | } |
547 | spin_unlock(&queue->lock); | 504 | spin_unlock_bh(&queue->lock); |
548 | rcu_read_unlock_bh(); | ||
549 | } | 505 | } |
550 | EXPORT_SYMBOL_GPL(rpc_wake_up); | 506 | EXPORT_SYMBOL_GPL(rpc_wake_up); |
551 | 507 | ||
@@ -561,26 +517,48 @@ void rpc_wake_up_status(struct rpc_wait_queue *queue, int status) | |||
561 | struct rpc_task *task, *next; | 517 | struct rpc_task *task, *next; |
562 | struct list_head *head; | 518 | struct list_head *head; |
563 | 519 | ||
564 | rcu_read_lock_bh(); | 520 | spin_lock_bh(&queue->lock); |
565 | spin_lock(&queue->lock); | ||
566 | head = &queue->tasks[queue->maxpriority]; | 521 | head = &queue->tasks[queue->maxpriority]; |
567 | for (;;) { | 522 | for (;;) { |
568 | list_for_each_entry_safe(task, next, head, u.tk_wait.list) { | 523 | list_for_each_entry_safe(task, next, head, u.tk_wait.list) { |
569 | task->tk_status = status; | 524 | task->tk_status = status; |
570 | __rpc_wake_up_task(task); | 525 | rpc_wake_up_task_queue_locked(queue, task); |
571 | } | 526 | } |
572 | if (head == &queue->tasks[0]) | 527 | if (head == &queue->tasks[0]) |
573 | break; | 528 | break; |
574 | head--; | 529 | head--; |
575 | } | 530 | } |
576 | spin_unlock(&queue->lock); | 531 | spin_unlock_bh(&queue->lock); |
577 | rcu_read_unlock_bh(); | ||
578 | } | 532 | } |
579 | EXPORT_SYMBOL_GPL(rpc_wake_up_status); | 533 | EXPORT_SYMBOL_GPL(rpc_wake_up_status); |
580 | 534 | ||
535 | static void __rpc_queue_timer_fn(unsigned long ptr) | ||
536 | { | ||
537 | struct rpc_wait_queue *queue = (struct rpc_wait_queue *)ptr; | ||
538 | struct rpc_task *task, *n; | ||
539 | unsigned long expires, now, timeo; | ||
540 | |||
541 | spin_lock(&queue->lock); | ||
542 | expires = now = jiffies; | ||
543 | list_for_each_entry_safe(task, n, &queue->timer_list.list, u.tk_wait.timer_list) { | ||
544 | timeo = task->u.tk_wait.expires; | ||
545 | if (time_after_eq(now, timeo)) { | ||
546 | dprintk("RPC: %5u timeout\n", task->tk_pid); | ||
547 | task->tk_status = -ETIMEDOUT; | ||
548 | rpc_wake_up_task_queue_locked(queue, task); | ||
549 | continue; | ||
550 | } | ||
551 | if (expires == now || time_after(expires, timeo)) | ||
552 | expires = timeo; | ||
553 | } | ||
554 | if (!list_empty(&queue->timer_list.list)) | ||
555 | rpc_set_queue_timer(queue, expires); | ||
556 | spin_unlock(&queue->lock); | ||
557 | } | ||
558 | |||
581 | static void __rpc_atrun(struct rpc_task *task) | 559 | static void __rpc_atrun(struct rpc_task *task) |
582 | { | 560 | { |
583 | rpc_wake_up_task(task); | 561 | task->tk_status = 0; |
584 | } | 562 | } |
585 | 563 | ||
586 | /* | 564 | /* |
@@ -589,7 +567,7 @@ static void __rpc_atrun(struct rpc_task *task) | |||
589 | void rpc_delay(struct rpc_task *task, unsigned long delay) | 567 | void rpc_delay(struct rpc_task *task, unsigned long delay) |
590 | { | 568 | { |
591 | task->tk_timeout = delay; | 569 | task->tk_timeout = delay; |
592 | rpc_sleep_on(&delay_queue, task, NULL, __rpc_atrun); | 570 | rpc_sleep_on(&delay_queue, task, __rpc_atrun); |
593 | } | 571 | } |
594 | EXPORT_SYMBOL_GPL(rpc_delay); | 572 | EXPORT_SYMBOL_GPL(rpc_delay); |
595 | 573 | ||
@@ -644,10 +622,6 @@ static void __rpc_execute(struct rpc_task *task) | |||
644 | BUG_ON(RPC_IS_QUEUED(task)); | 622 | BUG_ON(RPC_IS_QUEUED(task)); |
645 | 623 | ||
646 | for (;;) { | 624 | for (;;) { |
647 | /* | ||
648 | * Garbage collection of pending timers... | ||
649 | */ | ||
650 | rpc_delete_timer(task); | ||
651 | 625 | ||
652 | /* | 626 | /* |
653 | * Execute any pending callback. | 627 | * Execute any pending callback. |
@@ -816,8 +790,6 @@ EXPORT_SYMBOL_GPL(rpc_free); | |||
816 | static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *task_setup_data) | 790 | static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *task_setup_data) |
817 | { | 791 | { |
818 | memset(task, 0, sizeof(*task)); | 792 | memset(task, 0, sizeof(*task)); |
819 | setup_timer(&task->tk_timer, (void (*)(unsigned long))rpc_run_timer, | ||
820 | (unsigned long)task); | ||
821 | atomic_set(&task->tk_count, 1); | 793 | atomic_set(&task->tk_count, 1); |
822 | task->tk_flags = task_setup_data->flags; | 794 | task->tk_flags = task_setup_data->flags; |
823 | task->tk_ops = task_setup_data->callback_ops; | 795 | task->tk_ops = task_setup_data->callback_ops; |
@@ -832,7 +804,7 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta | |||
832 | task->tk_owner = current->tgid; | 804 | task->tk_owner = current->tgid; |
833 | 805 | ||
834 | /* Initialize workqueue for async tasks */ | 806 | /* Initialize workqueue for async tasks */ |
835 | task->tk_workqueue = rpciod_workqueue; | 807 | task->tk_workqueue = task_setup_data->workqueue; |
836 | 808 | ||
837 | task->tk_client = task_setup_data->rpc_client; | 809 | task->tk_client = task_setup_data->rpc_client; |
838 | if (task->tk_client != NULL) { | 810 | if (task->tk_client != NULL) { |
@@ -868,13 +840,6 @@ rpc_alloc_task(void) | |||
868 | return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS); | 840 | return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS); |
869 | } | 841 | } |
870 | 842 | ||
871 | static void rpc_free_task(struct rcu_head *rcu) | ||
872 | { | ||
873 | struct rpc_task *task = container_of(rcu, struct rpc_task, u.tk_rcu); | ||
874 | dprintk("RPC: %5u freeing task\n", task->tk_pid); | ||
875 | mempool_free(task, rpc_task_mempool); | ||
876 | } | ||
877 | |||
878 | /* | 843 | /* |
879 | * Create a new task for the specified client. | 844 | * Create a new task for the specified client. |
880 | */ | 845 | */ |
@@ -898,12 +863,25 @@ out: | |||
898 | return task; | 863 | return task; |
899 | } | 864 | } |
900 | 865 | ||
901 | 866 | static void rpc_free_task(struct rpc_task *task) | |
902 | void rpc_put_task(struct rpc_task *task) | ||
903 | { | 867 | { |
904 | const struct rpc_call_ops *tk_ops = task->tk_ops; | 868 | const struct rpc_call_ops *tk_ops = task->tk_ops; |
905 | void *calldata = task->tk_calldata; | 869 | void *calldata = task->tk_calldata; |
906 | 870 | ||
871 | if (task->tk_flags & RPC_TASK_DYNAMIC) { | ||
872 | dprintk("RPC: %5u freeing task\n", task->tk_pid); | ||
873 | mempool_free(task, rpc_task_mempool); | ||
874 | } | ||
875 | rpc_release_calldata(tk_ops, calldata); | ||
876 | } | ||
877 | |||
878 | static void rpc_async_release(struct work_struct *work) | ||
879 | { | ||
880 | rpc_free_task(container_of(work, struct rpc_task, u.tk_work)); | ||
881 | } | ||
882 | |||
883 | void rpc_put_task(struct rpc_task *task) | ||
884 | { | ||
907 | if (!atomic_dec_and_test(&task->tk_count)) | 885 | if (!atomic_dec_and_test(&task->tk_count)) |
908 | return; | 886 | return; |
909 | /* Release resources */ | 887 | /* Release resources */ |
@@ -915,9 +893,11 @@ void rpc_put_task(struct rpc_task *task) | |||
915 | rpc_release_client(task->tk_client); | 893 | rpc_release_client(task->tk_client); |
916 | task->tk_client = NULL; | 894 | task->tk_client = NULL; |
917 | } | 895 | } |
918 | if (task->tk_flags & RPC_TASK_DYNAMIC) | 896 | if (task->tk_workqueue != NULL) { |
919 | call_rcu_bh(&task->u.tk_rcu, rpc_free_task); | 897 | INIT_WORK(&task->u.tk_work, rpc_async_release); |
920 | rpc_release_calldata(tk_ops, calldata); | 898 | queue_work(task->tk_workqueue, &task->u.tk_work); |
899 | } else | ||
900 | rpc_free_task(task); | ||
921 | } | 901 | } |
922 | EXPORT_SYMBOL_GPL(rpc_put_task); | 902 | EXPORT_SYMBOL_GPL(rpc_put_task); |
923 | 903 | ||
@@ -937,9 +917,6 @@ static void rpc_release_task(struct rpc_task *task) | |||
937 | } | 917 | } |
938 | BUG_ON (RPC_IS_QUEUED(task)); | 918 | BUG_ON (RPC_IS_QUEUED(task)); |
939 | 919 | ||
940 | /* Synchronously delete any running timer */ | ||
941 | rpc_delete_timer(task); | ||
942 | |||
943 | #ifdef RPC_DEBUG | 920 | #ifdef RPC_DEBUG |
944 | task->tk_magic = 0; | 921 | task->tk_magic = 0; |
945 | #endif | 922 | #endif |
@@ -1029,11 +1006,20 @@ rpc_destroy_mempool(void) | |||
1029 | kmem_cache_destroy(rpc_task_slabp); | 1006 | kmem_cache_destroy(rpc_task_slabp); |
1030 | if (rpc_buffer_slabp) | 1007 | if (rpc_buffer_slabp) |
1031 | kmem_cache_destroy(rpc_buffer_slabp); | 1008 | kmem_cache_destroy(rpc_buffer_slabp); |
1009 | rpc_destroy_wait_queue(&delay_queue); | ||
1032 | } | 1010 | } |
1033 | 1011 | ||
1034 | int | 1012 | int |
1035 | rpc_init_mempool(void) | 1013 | rpc_init_mempool(void) |
1036 | { | 1014 | { |
1015 | /* | ||
1016 | * The following is not strictly a mempool initialisation, | ||
1017 | * but there is no harm in doing it here | ||
1018 | */ | ||
1019 | rpc_init_wait_queue(&delay_queue, "delayq"); | ||
1020 | if (!rpciod_start()) | ||
1021 | goto err_nomem; | ||
1022 | |||
1037 | rpc_task_slabp = kmem_cache_create("rpc_tasks", | 1023 | rpc_task_slabp = kmem_cache_create("rpc_tasks", |
1038 | sizeof(struct rpc_task), | 1024 | sizeof(struct rpc_task), |
1039 | 0, SLAB_HWCACHE_ALIGN, | 1025 | 0, SLAB_HWCACHE_ALIGN, |
@@ -1054,13 +1040,6 @@ rpc_init_mempool(void) | |||
1054 | rpc_buffer_slabp); | 1040 | rpc_buffer_slabp); |
1055 | if (!rpc_buffer_mempool) | 1041 | if (!rpc_buffer_mempool) |
1056 | goto err_nomem; | 1042 | goto err_nomem; |
1057 | if (!rpciod_start()) | ||
1058 | goto err_nomem; | ||
1059 | /* | ||
1060 | * The following is not strictly a mempool initialisation, | ||
1061 | * but there is no harm in doing it here | ||
1062 | */ | ||
1063 | rpc_init_wait_queue(&delay_queue, "delayq"); | ||
1064 | return 0; | 1043 | return 0; |
1065 | err_nomem: | 1044 | err_nomem: |
1066 | rpc_destroy_mempool(); | 1045 | rpc_destroy_mempool(); |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 1d3e5fcc2cc4..c475977de05a 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -175,7 +175,7 @@ static int svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) | |||
175 | size_t base = xdr->page_base; | 175 | size_t base = xdr->page_base; |
176 | unsigned int pglen = xdr->page_len; | 176 | unsigned int pglen = xdr->page_len; |
177 | unsigned int flags = MSG_MORE; | 177 | unsigned int flags = MSG_MORE; |
178 | char buf[RPC_MAX_ADDRBUFLEN]; | 178 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); |
179 | 179 | ||
180 | slen = xdr->len; | 180 | slen = xdr->len; |
181 | 181 | ||
@@ -716,7 +716,7 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt) | |||
716 | struct socket *newsock; | 716 | struct socket *newsock; |
717 | struct svc_sock *newsvsk; | 717 | struct svc_sock *newsvsk; |
718 | int err, slen; | 718 | int err, slen; |
719 | char buf[RPC_MAX_ADDRBUFLEN]; | 719 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); |
720 | 720 | ||
721 | dprintk("svc: tcp_accept %p sock %p\n", svsk, sock); | 721 | dprintk("svc: tcp_accept %p sock %p\n", svsk, sock); |
722 | if (!sock) | 722 | if (!sock) |
@@ -1206,10 +1206,10 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv, | |||
1206 | struct socket *sock; | 1206 | struct socket *sock; |
1207 | int error; | 1207 | int error; |
1208 | int type; | 1208 | int type; |
1209 | char buf[RPC_MAX_ADDRBUFLEN]; | ||
1210 | struct sockaddr_storage addr; | 1209 | struct sockaddr_storage addr; |
1211 | struct sockaddr *newsin = (struct sockaddr *)&addr; | 1210 | struct sockaddr *newsin = (struct sockaddr *)&addr; |
1212 | int newlen; | 1211 | int newlen; |
1212 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); | ||
1213 | 1213 | ||
1214 | dprintk("svc: svc_create_socket(%s, %d, %s)\n", | 1214 | dprintk("svc: svc_create_socket(%s, %d, %s)\n", |
1215 | serv->sv_program->pg_name, protocol, | 1215 | serv->sv_program->pg_name, protocol, |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index d5553b8179f9..85199c647022 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -188,9 +188,9 @@ out_sleep: | |||
188 | task->tk_timeout = 0; | 188 | task->tk_timeout = 0; |
189 | task->tk_status = -EAGAIN; | 189 | task->tk_status = -EAGAIN; |
190 | if (req && req->rq_ntrans) | 190 | if (req && req->rq_ntrans) |
191 | rpc_sleep_on(&xprt->resend, task, NULL, NULL); | 191 | rpc_sleep_on(&xprt->resend, task, NULL); |
192 | else | 192 | else |
193 | rpc_sleep_on(&xprt->sending, task, NULL, NULL); | 193 | rpc_sleep_on(&xprt->sending, task, NULL); |
194 | return 0; | 194 | return 0; |
195 | } | 195 | } |
196 | EXPORT_SYMBOL_GPL(xprt_reserve_xprt); | 196 | EXPORT_SYMBOL_GPL(xprt_reserve_xprt); |
@@ -238,9 +238,9 @@ out_sleep: | |||
238 | task->tk_timeout = 0; | 238 | task->tk_timeout = 0; |
239 | task->tk_status = -EAGAIN; | 239 | task->tk_status = -EAGAIN; |
240 | if (req && req->rq_ntrans) | 240 | if (req && req->rq_ntrans) |
241 | rpc_sleep_on(&xprt->resend, task, NULL, NULL); | 241 | rpc_sleep_on(&xprt->resend, task, NULL); |
242 | else | 242 | else |
243 | rpc_sleep_on(&xprt->sending, task, NULL, NULL); | 243 | rpc_sleep_on(&xprt->sending, task, NULL); |
244 | return 0; | 244 | return 0; |
245 | } | 245 | } |
246 | EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong); | 246 | EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong); |
@@ -453,7 +453,7 @@ void xprt_wait_for_buffer_space(struct rpc_task *task) | |||
453 | struct rpc_xprt *xprt = req->rq_xprt; | 453 | struct rpc_xprt *xprt = req->rq_xprt; |
454 | 454 | ||
455 | task->tk_timeout = req->rq_timeout; | 455 | task->tk_timeout = req->rq_timeout; |
456 | rpc_sleep_on(&xprt->pending, task, NULL, NULL); | 456 | rpc_sleep_on(&xprt->pending, task, NULL); |
457 | } | 457 | } |
458 | EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space); | 458 | EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space); |
459 | 459 | ||
@@ -472,7 +472,7 @@ void xprt_write_space(struct rpc_xprt *xprt) | |||
472 | if (xprt->snd_task) { | 472 | if (xprt->snd_task) { |
473 | dprintk("RPC: write space: waking waiting task on " | 473 | dprintk("RPC: write space: waking waiting task on " |
474 | "xprt %p\n", xprt); | 474 | "xprt %p\n", xprt); |
475 | rpc_wake_up_task(xprt->snd_task); | 475 | rpc_wake_up_queued_task(&xprt->pending, xprt->snd_task); |
476 | } | 476 | } |
477 | spin_unlock_bh(&xprt->transport_lock); | 477 | spin_unlock_bh(&xprt->transport_lock); |
478 | } | 478 | } |
@@ -602,8 +602,7 @@ void xprt_force_disconnect(struct rpc_xprt *xprt) | |||
602 | /* Try to schedule an autoclose RPC call */ | 602 | /* Try to schedule an autoclose RPC call */ |
603 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) | 603 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0) |
604 | queue_work(rpciod_workqueue, &xprt->task_cleanup); | 604 | queue_work(rpciod_workqueue, &xprt->task_cleanup); |
605 | else if (xprt->snd_task != NULL) | 605 | xprt_wake_pending_tasks(xprt, -ENOTCONN); |
606 | rpc_wake_up_task(xprt->snd_task); | ||
607 | spin_unlock_bh(&xprt->transport_lock); | 606 | spin_unlock_bh(&xprt->transport_lock); |
608 | } | 607 | } |
609 | EXPORT_SYMBOL_GPL(xprt_force_disconnect); | 608 | EXPORT_SYMBOL_GPL(xprt_force_disconnect); |
@@ -653,7 +652,7 @@ void xprt_connect(struct rpc_task *task) | |||
653 | task->tk_rqstp->rq_bytes_sent = 0; | 652 | task->tk_rqstp->rq_bytes_sent = 0; |
654 | 653 | ||
655 | task->tk_timeout = xprt->connect_timeout; | 654 | task->tk_timeout = xprt->connect_timeout; |
656 | rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL); | 655 | rpc_sleep_on(&xprt->pending, task, xprt_connect_status); |
657 | xprt->stat.connect_start = jiffies; | 656 | xprt->stat.connect_start = jiffies; |
658 | xprt->ops->connect(task); | 657 | xprt->ops->connect(task); |
659 | } | 658 | } |
@@ -749,18 +748,19 @@ EXPORT_SYMBOL_GPL(xprt_update_rtt); | |||
749 | void xprt_complete_rqst(struct rpc_task *task, int copied) | 748 | void xprt_complete_rqst(struct rpc_task *task, int copied) |
750 | { | 749 | { |
751 | struct rpc_rqst *req = task->tk_rqstp; | 750 | struct rpc_rqst *req = task->tk_rqstp; |
751 | struct rpc_xprt *xprt = req->rq_xprt; | ||
752 | 752 | ||
753 | dprintk("RPC: %5u xid %08x complete (%d bytes received)\n", | 753 | dprintk("RPC: %5u xid %08x complete (%d bytes received)\n", |
754 | task->tk_pid, ntohl(req->rq_xid), copied); | 754 | task->tk_pid, ntohl(req->rq_xid), copied); |
755 | 755 | ||
756 | task->tk_xprt->stat.recvs++; | 756 | xprt->stat.recvs++; |
757 | task->tk_rtt = (long)jiffies - req->rq_xtime; | 757 | task->tk_rtt = (long)jiffies - req->rq_xtime; |
758 | 758 | ||
759 | list_del_init(&req->rq_list); | 759 | list_del_init(&req->rq_list); |
760 | /* Ensure all writes are done before we update req->rq_received */ | 760 | /* Ensure all writes are done before we update req->rq_received */ |
761 | smp_wmb(); | 761 | smp_wmb(); |
762 | req->rq_received = req->rq_private_buf.len = copied; | 762 | req->rq_received = req->rq_private_buf.len = copied; |
763 | rpc_wake_up_task(task); | 763 | rpc_wake_up_queued_task(&xprt->pending, task); |
764 | } | 764 | } |
765 | EXPORT_SYMBOL_GPL(xprt_complete_rqst); | 765 | EXPORT_SYMBOL_GPL(xprt_complete_rqst); |
766 | 766 | ||
@@ -769,17 +769,17 @@ static void xprt_timer(struct rpc_task *task) | |||
769 | struct rpc_rqst *req = task->tk_rqstp; | 769 | struct rpc_rqst *req = task->tk_rqstp; |
770 | struct rpc_xprt *xprt = req->rq_xprt; | 770 | struct rpc_xprt *xprt = req->rq_xprt; |
771 | 771 | ||
772 | if (task->tk_status != -ETIMEDOUT) | ||
773 | return; | ||
772 | dprintk("RPC: %5u xprt_timer\n", task->tk_pid); | 774 | dprintk("RPC: %5u xprt_timer\n", task->tk_pid); |
773 | 775 | ||
774 | spin_lock(&xprt->transport_lock); | 776 | spin_lock_bh(&xprt->transport_lock); |
775 | if (!req->rq_received) { | 777 | if (!req->rq_received) { |
776 | if (xprt->ops->timer) | 778 | if (xprt->ops->timer) |
777 | xprt->ops->timer(task); | 779 | xprt->ops->timer(task); |
778 | task->tk_status = -ETIMEDOUT; | 780 | } else |
779 | } | 781 | task->tk_status = 0; |
780 | task->tk_timeout = 0; | 782 | spin_unlock_bh(&xprt->transport_lock); |
781 | rpc_wake_up_task(task); | ||
782 | spin_unlock(&xprt->transport_lock); | ||
783 | } | 783 | } |
784 | 784 | ||
785 | /** | 785 | /** |
@@ -864,7 +864,7 @@ void xprt_transmit(struct rpc_task *task) | |||
864 | if (!xprt_connected(xprt)) | 864 | if (!xprt_connected(xprt)) |
865 | task->tk_status = -ENOTCONN; | 865 | task->tk_status = -ENOTCONN; |
866 | else if (!req->rq_received) | 866 | else if (!req->rq_received) |
867 | rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer); | 867 | rpc_sleep_on(&xprt->pending, task, xprt_timer); |
868 | spin_unlock_bh(&xprt->transport_lock); | 868 | spin_unlock_bh(&xprt->transport_lock); |
869 | return; | 869 | return; |
870 | } | 870 | } |
@@ -875,7 +875,7 @@ void xprt_transmit(struct rpc_task *task) | |||
875 | */ | 875 | */ |
876 | task->tk_status = status; | 876 | task->tk_status = status; |
877 | if (status == -ECONNREFUSED) | 877 | if (status == -ECONNREFUSED) |
878 | rpc_sleep_on(&xprt->sending, task, NULL, NULL); | 878 | rpc_sleep_on(&xprt->sending, task, NULL); |
879 | } | 879 | } |
880 | 880 | ||
881 | static inline void do_xprt_reserve(struct rpc_task *task) | 881 | static inline void do_xprt_reserve(struct rpc_task *task) |
@@ -895,7 +895,7 @@ static inline void do_xprt_reserve(struct rpc_task *task) | |||
895 | dprintk("RPC: waiting for request slot\n"); | 895 | dprintk("RPC: waiting for request slot\n"); |
896 | task->tk_status = -EAGAIN; | 896 | task->tk_status = -EAGAIN; |
897 | task->tk_timeout = 0; | 897 | task->tk_timeout = 0; |
898 | rpc_sleep_on(&xprt->backlog, task, NULL, NULL); | 898 | rpc_sleep_on(&xprt->backlog, task, NULL); |
899 | } | 899 | } |
900 | 900 | ||
901 | /** | 901 | /** |
@@ -1052,6 +1052,11 @@ static void xprt_destroy(struct kref *kref) | |||
1052 | xprt->shutdown = 1; | 1052 | xprt->shutdown = 1; |
1053 | del_timer_sync(&xprt->timer); | 1053 | del_timer_sync(&xprt->timer); |
1054 | 1054 | ||
1055 | rpc_destroy_wait_queue(&xprt->binding); | ||
1056 | rpc_destroy_wait_queue(&xprt->pending); | ||
1057 | rpc_destroy_wait_queue(&xprt->sending); | ||
1058 | rpc_destroy_wait_queue(&xprt->resend); | ||
1059 | rpc_destroy_wait_queue(&xprt->backlog); | ||
1055 | /* | 1060 | /* |
1056 | * Tear down transport state and free the rpc_xprt | 1061 | * Tear down transport state and free the rpc_xprt |
1057 | */ | 1062 | */ |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 30e7ac243a90..8bd3b0f73ac0 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -1073,6 +1073,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes) | |||
1073 | { | 1073 | { |
1074 | struct rpc_xprt *xprt; | 1074 | struct rpc_xprt *xprt; |
1075 | read_descriptor_t rd_desc; | 1075 | read_descriptor_t rd_desc; |
1076 | int read; | ||
1076 | 1077 | ||
1077 | dprintk("RPC: xs_tcp_data_ready...\n"); | 1078 | dprintk("RPC: xs_tcp_data_ready...\n"); |
1078 | 1079 | ||
@@ -1084,8 +1085,10 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes) | |||
1084 | 1085 | ||
1085 | /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */ | 1086 | /* We use rd_desc to pass struct xprt to xs_tcp_data_recv */ |
1086 | rd_desc.arg.data = xprt; | 1087 | rd_desc.arg.data = xprt; |
1087 | rd_desc.count = 65536; | 1088 | do { |
1088 | tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); | 1089 | rd_desc.count = 65536; |
1090 | read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv); | ||
1091 | } while (read > 0); | ||
1089 | out: | 1092 | out: |
1090 | read_unlock(&sk->sk_callback_lock); | 1093 | read_unlock(&sk->sk_callback_lock); |
1091 | } | 1094 | } |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index eea75888805e..b8788fd5e3c6 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -718,16 +718,16 @@ static struct sock *unix_find_other(struct net *net, | |||
718 | goto put_fail; | 718 | goto put_fail; |
719 | 719 | ||
720 | err = -ECONNREFUSED; | 720 | err = -ECONNREFUSED; |
721 | if (!S_ISSOCK(nd.dentry->d_inode->i_mode)) | 721 | if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode)) |
722 | goto put_fail; | 722 | goto put_fail; |
723 | u=unix_find_socket_byinode(net, nd.dentry->d_inode); | 723 | u = unix_find_socket_byinode(net, nd.path.dentry->d_inode); |
724 | if (!u) | 724 | if (!u) |
725 | goto put_fail; | 725 | goto put_fail; |
726 | 726 | ||
727 | if (u->sk_type == type) | 727 | if (u->sk_type == type) |
728 | touch_atime(nd.mnt, nd.dentry); | 728 | touch_atime(nd.path.mnt, nd.path.dentry); |
729 | 729 | ||
730 | path_release(&nd); | 730 | path_put(&nd.path); |
731 | 731 | ||
732 | err=-EPROTOTYPE; | 732 | err=-EPROTOTYPE; |
733 | if (u->sk_type != type) { | 733 | if (u->sk_type != type) { |
@@ -748,7 +748,7 @@ static struct sock *unix_find_other(struct net *net, | |||
748 | return u; | 748 | return u; |
749 | 749 | ||
750 | put_fail: | 750 | put_fail: |
751 | path_release(&nd); | 751 | path_put(&nd.path); |
752 | fail: | 752 | fail: |
753 | *error=err; | 753 | *error=err; |
754 | return NULL; | 754 | return NULL; |
@@ -819,12 +819,12 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
819 | */ | 819 | */ |
820 | mode = S_IFSOCK | | 820 | mode = S_IFSOCK | |
821 | (SOCK_INODE(sock)->i_mode & ~current->fs->umask); | 821 | (SOCK_INODE(sock)->i_mode & ~current->fs->umask); |
822 | err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); | 822 | err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0); |
823 | if (err) | 823 | if (err) |
824 | goto out_mknod_dput; | 824 | goto out_mknod_dput; |
825 | mutex_unlock(&nd.dentry->d_inode->i_mutex); | 825 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
826 | dput(nd.dentry); | 826 | dput(nd.path.dentry); |
827 | nd.dentry = dentry; | 827 | nd.path.dentry = dentry; |
828 | 828 | ||
829 | addr->hash = UNIX_HASH_SIZE; | 829 | addr->hash = UNIX_HASH_SIZE; |
830 | } | 830 | } |
@@ -842,8 +842,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
842 | list = &unix_socket_table[addr->hash]; | 842 | list = &unix_socket_table[addr->hash]; |
843 | } else { | 843 | } else { |
844 | list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; | 844 | list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; |
845 | u->dentry = nd.dentry; | 845 | u->dentry = nd.path.dentry; |
846 | u->mnt = nd.mnt; | 846 | u->mnt = nd.path.mnt; |
847 | } | 847 | } |
848 | 848 | ||
849 | err = 0; | 849 | err = 0; |
@@ -861,8 +861,8 @@ out: | |||
861 | out_mknod_dput: | 861 | out_mknod_dput: |
862 | dput(dentry); | 862 | dput(dentry); |
863 | out_mknod_unlock: | 863 | out_mknod_unlock: |
864 | mutex_unlock(&nd.dentry->d_inode->i_mutex); | 864 | mutex_unlock(&nd.path.dentry->d_inode->i_mutex); |
865 | path_release(&nd); | 865 | path_put(&nd.path); |
866 | out_mknod_parent: | 866 | out_mknod_parent: |
867 | if (err==-EEXIST) | 867 | if (err==-EEXIST) |
868 | err=-EADDRINUSE; | 868 | err=-EADDRINUSE; |
diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig index 8f9dbec319be..9201ef8ad90e 100644 --- a/net/xfrm/Kconfig +++ b/net/xfrm/Kconfig | |||
@@ -38,7 +38,7 @@ config XFRM_MIGRATE | |||
38 | 38 | ||
39 | config XFRM_STATISTICS | 39 | config XFRM_STATISTICS |
40 | bool "Transformation statistics (EXPERIMENTAL)" | 40 | bool "Transformation statistics (EXPERIMENTAL)" |
41 | depends on XFRM && PROC_FS && EXPERIMENTAL | 41 | depends on INET && XFRM && PROC_FS && EXPERIMENTAL |
42 | ---help--- | 42 | ---help--- |
43 | This statistics is not a SNMP/MIB specification but shows | 43 | This statistics is not a SNMP/MIB specification but shows |
44 | statistics about transformation error (or almost error) factor | 44 | statistics about transformation error (or almost error) factor |
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 4d6ebc633a94..62188c6a06dd 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
@@ -109,7 +109,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
109 | if (encap_type < 0) { | 109 | if (encap_type < 0) { |
110 | async = 1; | 110 | async = 1; |
111 | x = xfrm_input_state(skb); | 111 | x = xfrm_input_state(skb); |
112 | seq = XFRM_SKB_CB(skb)->seq; | 112 | seq = XFRM_SKB_CB(skb)->seq.input; |
113 | goto resume; | 113 | goto resume; |
114 | } | 114 | } |
115 | 115 | ||
@@ -175,7 +175,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
175 | 175 | ||
176 | spin_unlock(&x->lock); | 176 | spin_unlock(&x->lock); |
177 | 177 | ||
178 | XFRM_SKB_CB(skb)->seq = seq; | 178 | XFRM_SKB_CB(skb)->seq.input = seq; |
179 | 179 | ||
180 | nexthdr = x->type->input(x, skb); | 180 | nexthdr = x->type->input(x, skb); |
181 | 181 | ||
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index fc690368325f..569d377932c4 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c | |||
@@ -62,7 +62,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err) | |||
62 | } | 62 | } |
63 | 63 | ||
64 | if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { | 64 | if (x->type->flags & XFRM_TYPE_REPLAY_PROT) { |
65 | XFRM_SKB_CB(skb)->seq = ++x->replay.oseq; | 65 | XFRM_SKB_CB(skb)->seq.output = ++x->replay.oseq; |
66 | if (unlikely(x->replay.oseq == 0)) { | 66 | if (unlikely(x->replay.oseq == 0)) { |
67 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATESEQERROR); | 67 | XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATESEQERROR); |
68 | x->replay.oseq--; | 68 | x->replay.oseq--; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 47219f98053f..9fc4c315f6cd 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -331,15 +331,31 @@ static void xfrm_dst_hash_transfer(struct hlist_head *list, | |||
331 | struct hlist_head *ndsttable, | 331 | struct hlist_head *ndsttable, |
332 | unsigned int nhashmask) | 332 | unsigned int nhashmask) |
333 | { | 333 | { |
334 | struct hlist_node *entry, *tmp; | 334 | struct hlist_node *entry, *tmp, *entry0 = NULL; |
335 | struct xfrm_policy *pol; | 335 | struct xfrm_policy *pol; |
336 | unsigned int h0 = 0; | ||
336 | 337 | ||
338 | redo: | ||
337 | hlist_for_each_entry_safe(pol, entry, tmp, list, bydst) { | 339 | hlist_for_each_entry_safe(pol, entry, tmp, list, bydst) { |
338 | unsigned int h; | 340 | unsigned int h; |
339 | 341 | ||
340 | h = __addr_hash(&pol->selector.daddr, &pol->selector.saddr, | 342 | h = __addr_hash(&pol->selector.daddr, &pol->selector.saddr, |
341 | pol->family, nhashmask); | 343 | pol->family, nhashmask); |
342 | hlist_add_head(&pol->bydst, ndsttable+h); | 344 | if (!entry0) { |
345 | hlist_del(entry); | ||
346 | hlist_add_head(&pol->bydst, ndsttable+h); | ||
347 | h0 = h; | ||
348 | } else { | ||
349 | if (h != h0) | ||
350 | continue; | ||
351 | hlist_del(entry); | ||
352 | hlist_add_after(entry0, &pol->bydst); | ||
353 | } | ||
354 | entry0 = entry; | ||
355 | } | ||
356 | if (!hlist_empty(list)) { | ||
357 | entry0 = NULL; | ||
358 | goto redo; | ||
343 | } | 359 | } |
344 | } | 360 | } |
345 | 361 | ||
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 78338079b7f5..f971ca5645f8 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1105,6 +1105,7 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p, | |||
1105 | return xp; | 1105 | return xp; |
1106 | error: | 1106 | error: |
1107 | *errp = err; | 1107 | *errp = err; |
1108 | xp->dead = 1; | ||
1108 | xfrm_policy_destroy(xp); | 1109 | xfrm_policy_destroy(xp); |
1109 | return NULL; | 1110 | return NULL; |
1110 | } | 1111 | } |