Contents of /trunk/kernel-alx/patches-4.1/0114-4.1.15-all-fixes.patch
Parent Directory | Revision Log
Revision 2748 -
(show annotations)
(download)
Mon Jan 11 12:00:45 2016 UTC (8 years, 8 months ago) by niro
File size: 83939 byte(s)
Mon Jan 11 12:00:45 2016 UTC (8 years, 8 months ago) by niro
File size: 83939 byte(s)
-linux-4.1 patches up to 4.1.15
1 | diff --git a/Makefile b/Makefile |
2 | index 091280d66452..cf35f6bcffd8 100644 |
3 | --- a/Makefile |
4 | +++ b/Makefile |
5 | @@ -1,6 +1,6 @@ |
6 | VERSION = 4 |
7 | PATCHLEVEL = 1 |
8 | -SUBLEVEL = 14 |
9 | +SUBLEVEL = 15 |
10 | EXTRAVERSION = |
11 | NAME = Series 4800 |
12 | |
13 | diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c |
14 | index 1ec6441fe2a5..09138ceba046 100644 |
15 | --- a/drivers/block/rbd.c |
16 | +++ b/drivers/block/rbd.c |
17 | @@ -3417,6 +3417,7 @@ static void rbd_queue_workfn(struct work_struct *work) |
18 | goto err_rq; |
19 | } |
20 | img_request->rq = rq; |
21 | + snapc = NULL; /* img_request consumes a ref */ |
22 | |
23 | if (op_type == OBJ_OP_DISCARD) |
24 | result = rbd_img_request_fill(img_request, OBJ_REQUEST_NODATA, |
25 | diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c |
26 | index f51d376d10ba..c2f5117fd8cb 100644 |
27 | --- a/drivers/firewire/ohci.c |
28 | +++ b/drivers/firewire/ohci.c |
29 | @@ -3675,6 +3675,11 @@ static int pci_probe(struct pci_dev *dev, |
30 | |
31 | reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); |
32 | ohci->it_context_support = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); |
33 | + /* JMicron JMB38x often shows 0 at first read, just ignore it */ |
34 | + if (!ohci->it_context_support) { |
35 | + ohci_notice(ohci, "overriding IsoXmitIntMask\n"); |
36 | + ohci->it_context_support = 0xf; |
37 | + } |
38 | reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0); |
39 | ohci->it_context_mask = ohci->it_context_support; |
40 | ohci->n_it = hweight32(ohci->it_context_mask); |
41 | diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c |
42 | index 9c71295f2fef..85e640440bd9 100644 |
43 | --- a/drivers/net/phy/broadcom.c |
44 | +++ b/drivers/net/phy/broadcom.c |
45 | @@ -675,7 +675,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = { |
46 | { PHY_ID_BCM5461, 0xfffffff0 }, |
47 | { PHY_ID_BCM54616S, 0xfffffff0 }, |
48 | { PHY_ID_BCM5464, 0xfffffff0 }, |
49 | - { PHY_ID_BCM5482, 0xfffffff0 }, |
50 | + { PHY_ID_BCM5481, 0xfffffff0 }, |
51 | { PHY_ID_BCM5482, 0xfffffff0 }, |
52 | { PHY_ID_BCM50610, 0xfffffff0 }, |
53 | { PHY_ID_BCM50610M, 0xfffffff0 }, |
54 | diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c |
55 | index 4e0470d396a3..71190dc1eacf 100644 |
56 | --- a/drivers/net/usb/qmi_wwan.c |
57 | +++ b/drivers/net/usb/qmi_wwan.c |
58 | @@ -774,6 +774,7 @@ static const struct usb_device_id products[] = { |
59 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ |
60 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ |
61 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ |
62 | + {QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)}, /* XS Stick W100-2 from 4G Systems */ |
63 | {QMI_FIXED_INTF(0x0b3c, 0xc000, 4)}, /* Olivetti Olicard 100 */ |
64 | {QMI_FIXED_INTF(0x0b3c, 0xc001, 4)}, /* Olivetti Olicard 120 */ |
65 | {QMI_FIXED_INTF(0x0b3c, 0xc002, 4)}, /* Olivetti Olicard 140 */ |
66 | diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c |
67 | index b072e17479aa..2b0d84d32db4 100644 |
68 | --- a/fs/btrfs/file.c |
69 | +++ b/fs/btrfs/file.c |
70 | @@ -756,8 +756,16 @@ next_slot: |
71 | } |
72 | |
73 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); |
74 | - if (key.objectid > ino || |
75 | - key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end) |
76 | + |
77 | + if (key.objectid > ino) |
78 | + break; |
79 | + if (WARN_ON_ONCE(key.objectid < ino) || |
80 | + key.type < BTRFS_EXTENT_DATA_KEY) { |
81 | + ASSERT(del_nr == 0); |
82 | + path->slots[0]++; |
83 | + goto next_slot; |
84 | + } |
85 | + if (key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end) |
86 | break; |
87 | |
88 | fi = btrfs_item_ptr(leaf, path->slots[0], |
89 | @@ -776,8 +784,8 @@ next_slot: |
90 | btrfs_file_extent_inline_len(leaf, |
91 | path->slots[0], fi); |
92 | } else { |
93 | - WARN_ON(1); |
94 | - extent_end = search_start; |
95 | + /* can't happen */ |
96 | + BUG(); |
97 | } |
98 | |
99 | /* |
100 | diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c |
101 | index e3b39f0c4666..5136c73b3dce 100644 |
102 | --- a/fs/btrfs/inode.c |
103 | +++ b/fs/btrfs/inode.c |
104 | @@ -1294,8 +1294,14 @@ next_slot: |
105 | num_bytes = 0; |
106 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
107 | |
108 | - if (found_key.objectid > ino || |
109 | - found_key.type > BTRFS_EXTENT_DATA_KEY || |
110 | + if (found_key.objectid > ino) |
111 | + break; |
112 | + if (WARN_ON_ONCE(found_key.objectid < ino) || |
113 | + found_key.type < BTRFS_EXTENT_DATA_KEY) { |
114 | + path->slots[0]++; |
115 | + goto next_slot; |
116 | + } |
117 | + if (found_key.type > BTRFS_EXTENT_DATA_KEY || |
118 | found_key.offset > end) |
119 | break; |
120 | |
121 | @@ -4184,6 +4190,47 @@ static int truncate_space_check(struct btrfs_trans_handle *trans, |
122 | |
123 | } |
124 | |
125 | +static int truncate_inline_extent(struct inode *inode, |
126 | + struct btrfs_path *path, |
127 | + struct btrfs_key *found_key, |
128 | + const u64 item_end, |
129 | + const u64 new_size) |
130 | +{ |
131 | + struct extent_buffer *leaf = path->nodes[0]; |
132 | + int slot = path->slots[0]; |
133 | + struct btrfs_file_extent_item *fi; |
134 | + u32 size = (u32)(new_size - found_key->offset); |
135 | + struct btrfs_root *root = BTRFS_I(inode)->root; |
136 | + |
137 | + fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); |
138 | + |
139 | + if (btrfs_file_extent_compression(leaf, fi) != BTRFS_COMPRESS_NONE) { |
140 | + loff_t offset = new_size; |
141 | + loff_t page_end = ALIGN(offset, PAGE_CACHE_SIZE); |
142 | + |
143 | + /* |
144 | + * Zero out the remaining of the last page of our inline extent, |
145 | + * instead of directly truncating our inline extent here - that |
146 | + * would be much more complex (decompressing all the data, then |
147 | + * compressing the truncated data, which might be bigger than |
148 | + * the size of the inline extent, resize the extent, etc). |
149 | + * We release the path because to get the page we might need to |
150 | + * read the extent item from disk (data not in the page cache). |
151 | + */ |
152 | + btrfs_release_path(path); |
153 | + return btrfs_truncate_page(inode, offset, page_end - offset, 0); |
154 | + } |
155 | + |
156 | + btrfs_set_file_extent_ram_bytes(leaf, fi, size); |
157 | + size = btrfs_file_extent_calc_inline_size(size); |
158 | + btrfs_truncate_item(root, path, size, 1); |
159 | + |
160 | + if (test_bit(BTRFS_ROOT_REF_COWS, &root->state)) |
161 | + inode_sub_bytes(inode, item_end + 1 - new_size); |
162 | + |
163 | + return 0; |
164 | +} |
165 | + |
166 | /* |
167 | * this can truncate away extent items, csum items and directory items. |
168 | * It starts at a high offset and removes keys until it can't find |
169 | @@ -4378,27 +4425,40 @@ search_again: |
170 | * special encodings |
171 | */ |
172 | if (!del_item && |
173 | - btrfs_file_extent_compression(leaf, fi) == 0 && |
174 | btrfs_file_extent_encryption(leaf, fi) == 0 && |
175 | btrfs_file_extent_other_encoding(leaf, fi) == 0) { |
176 | - u32 size = new_size - found_key.offset; |
177 | - |
178 | - if (test_bit(BTRFS_ROOT_REF_COWS, &root->state)) |
179 | - inode_sub_bytes(inode, item_end + 1 - |
180 | - new_size); |
181 | |
182 | /* |
183 | - * update the ram bytes to properly reflect |
184 | - * the new size of our item |
185 | + * Need to release path in order to truncate a |
186 | + * compressed extent. So delete any accumulated |
187 | + * extent items so far. |
188 | */ |
189 | - btrfs_set_file_extent_ram_bytes(leaf, fi, size); |
190 | - size = |
191 | - btrfs_file_extent_calc_inline_size(size); |
192 | - btrfs_truncate_item(root, path, size, 1); |
193 | + if (btrfs_file_extent_compression(leaf, fi) != |
194 | + BTRFS_COMPRESS_NONE && pending_del_nr) { |
195 | + err = btrfs_del_items(trans, root, path, |
196 | + pending_del_slot, |
197 | + pending_del_nr); |
198 | + if (err) { |
199 | + btrfs_abort_transaction(trans, |
200 | + root, |
201 | + err); |
202 | + goto error; |
203 | + } |
204 | + pending_del_nr = 0; |
205 | + } |
206 | + |
207 | + err = truncate_inline_extent(inode, path, |
208 | + &found_key, |
209 | + item_end, |
210 | + new_size); |
211 | + if (err) { |
212 | + btrfs_abort_transaction(trans, |
213 | + root, err); |
214 | + goto error; |
215 | + } |
216 | } else if (test_bit(BTRFS_ROOT_REF_COWS, |
217 | &root->state)) { |
218 | - inode_sub_bytes(inode, item_end + 1 - |
219 | - found_key.offset); |
220 | + inode_sub_bytes(inode, item_end + 1 - new_size); |
221 | } |
222 | } |
223 | delete: |
224 | diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c |
225 | index 8b2c82ce36b3..87c720865ebf 100644 |
226 | --- a/fs/btrfs/ioctl.c |
227 | +++ b/fs/btrfs/ioctl.c |
228 | @@ -3166,6 +3166,150 @@ static void clone_update_extent_map(struct inode *inode, |
229 | &BTRFS_I(inode)->runtime_flags); |
230 | } |
231 | |
232 | +/* |
233 | + * Make sure we do not end up inserting an inline extent into a file that has |
234 | + * already other (non-inline) extents. If a file has an inline extent it can |
235 | + * not have any other extents and the (single) inline extent must start at the |
236 | + * file offset 0. Failing to respect these rules will lead to file corruption, |
237 | + * resulting in EIO errors on read/write operations, hitting BUG_ON's in mm, etc |
238 | + * |
239 | + * We can have extents that have been already written to disk or we can have |
240 | + * dirty ranges still in delalloc, in which case the extent maps and items are |
241 | + * created only when we run delalloc, and the delalloc ranges might fall outside |
242 | + * the range we are currently locking in the inode's io tree. So we check the |
243 | + * inode's i_size because of that (i_size updates are done while holding the |
244 | + * i_mutex, which we are holding here). |
245 | + * We also check to see if the inode has a size not greater than "datal" but has |
246 | + * extents beyond it, due to an fallocate with FALLOC_FL_KEEP_SIZE (and we are |
247 | + * protected against such concurrent fallocate calls by the i_mutex). |
248 | + * |
249 | + * If the file has no extents but a size greater than datal, do not allow the |
250 | + * copy because we would need turn the inline extent into a non-inline one (even |
251 | + * with NO_HOLES enabled). If we find our destination inode only has one inline |
252 | + * extent, just overwrite it with the source inline extent if its size is less |
253 | + * than the source extent's size, or we could copy the source inline extent's |
254 | + * data into the destination inode's inline extent if the later is greater then |
255 | + * the former. |
256 | + */ |
257 | +static int clone_copy_inline_extent(struct inode *src, |
258 | + struct inode *dst, |
259 | + struct btrfs_trans_handle *trans, |
260 | + struct btrfs_path *path, |
261 | + struct btrfs_key *new_key, |
262 | + const u64 drop_start, |
263 | + const u64 datal, |
264 | + const u64 skip, |
265 | + const u64 size, |
266 | + char *inline_data) |
267 | +{ |
268 | + struct btrfs_root *root = BTRFS_I(dst)->root; |
269 | + const u64 aligned_end = ALIGN(new_key->offset + datal, |
270 | + root->sectorsize); |
271 | + int ret; |
272 | + struct btrfs_key key; |
273 | + |
274 | + if (new_key->offset > 0) |
275 | + return -EOPNOTSUPP; |
276 | + |
277 | + key.objectid = btrfs_ino(dst); |
278 | + key.type = BTRFS_EXTENT_DATA_KEY; |
279 | + key.offset = 0; |
280 | + ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
281 | + if (ret < 0) { |
282 | + return ret; |
283 | + } else if (ret > 0) { |
284 | + if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) { |
285 | + ret = btrfs_next_leaf(root, path); |
286 | + if (ret < 0) |
287 | + return ret; |
288 | + else if (ret > 0) |
289 | + goto copy_inline_extent; |
290 | + } |
291 | + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); |
292 | + if (key.objectid == btrfs_ino(dst) && |
293 | + key.type == BTRFS_EXTENT_DATA_KEY) { |
294 | + ASSERT(key.offset > 0); |
295 | + return -EOPNOTSUPP; |
296 | + } |
297 | + } else if (i_size_read(dst) <= datal) { |
298 | + struct btrfs_file_extent_item *ei; |
299 | + u64 ext_len; |
300 | + |
301 | + /* |
302 | + * If the file size is <= datal, make sure there are no other |
303 | + * extents following (can happen do to an fallocate call with |
304 | + * the flag FALLOC_FL_KEEP_SIZE). |
305 | + */ |
306 | + ei = btrfs_item_ptr(path->nodes[0], path->slots[0], |
307 | + struct btrfs_file_extent_item); |
308 | + /* |
309 | + * If it's an inline extent, it can not have other extents |
310 | + * following it. |
311 | + */ |
312 | + if (btrfs_file_extent_type(path->nodes[0], ei) == |
313 | + BTRFS_FILE_EXTENT_INLINE) |
314 | + goto copy_inline_extent; |
315 | + |
316 | + ext_len = btrfs_file_extent_num_bytes(path->nodes[0], ei); |
317 | + if (ext_len > aligned_end) |
318 | + return -EOPNOTSUPP; |
319 | + |
320 | + ret = btrfs_next_item(root, path); |
321 | + if (ret < 0) { |
322 | + return ret; |
323 | + } else if (ret == 0) { |
324 | + btrfs_item_key_to_cpu(path->nodes[0], &key, |
325 | + path->slots[0]); |
326 | + if (key.objectid == btrfs_ino(dst) && |
327 | + key.type == BTRFS_EXTENT_DATA_KEY) |
328 | + return -EOPNOTSUPP; |
329 | + } |
330 | + } |
331 | + |
332 | +copy_inline_extent: |
333 | + /* |
334 | + * We have no extent items, or we have an extent at offset 0 which may |
335 | + * or may not be inlined. All these cases are dealt the same way. |
336 | + */ |
337 | + if (i_size_read(dst) > datal) { |
338 | + /* |
339 | + * If the destination inode has an inline extent... |
340 | + * This would require copying the data from the source inline |
341 | + * extent into the beginning of the destination's inline extent. |
342 | + * But this is really complex, both extents can be compressed |
343 | + * or just one of them, which would require decompressing and |
344 | + * re-compressing data (which could increase the new compressed |
345 | + * size, not allowing the compressed data to fit anymore in an |
346 | + * inline extent). |
347 | + * So just don't support this case for now (it should be rare, |
348 | + * we are not really saving space when cloning inline extents). |
349 | + */ |
350 | + return -EOPNOTSUPP; |
351 | + } |
352 | + |
353 | + btrfs_release_path(path); |
354 | + ret = btrfs_drop_extents(trans, root, dst, drop_start, aligned_end, 1); |
355 | + if (ret) |
356 | + return ret; |
357 | + ret = btrfs_insert_empty_item(trans, root, path, new_key, size); |
358 | + if (ret) |
359 | + return ret; |
360 | + |
361 | + if (skip) { |
362 | + const u32 start = btrfs_file_extent_calc_inline_size(0); |
363 | + |
364 | + memmove(inline_data + start, inline_data + start + skip, datal); |
365 | + } |
366 | + |
367 | + write_extent_buffer(path->nodes[0], inline_data, |
368 | + btrfs_item_ptr_offset(path->nodes[0], |
369 | + path->slots[0]), |
370 | + size); |
371 | + inode_add_bytes(dst, datal); |
372 | + |
373 | + return 0; |
374 | +} |
375 | + |
376 | /** |
377 | * btrfs_clone() - clone a range from inode file to another |
378 | * |
379 | @@ -3432,21 +3576,6 @@ process_slot: |
380 | } else if (type == BTRFS_FILE_EXTENT_INLINE) { |
381 | u64 skip = 0; |
382 | u64 trim = 0; |
383 | - u64 aligned_end = 0; |
384 | - |
385 | - /* |
386 | - * Don't copy an inline extent into an offset |
387 | - * greater than zero. Having an inline extent |
388 | - * at such an offset results in chaos as btrfs |
389 | - * isn't prepared for such cases. Just skip |
390 | - * this case for the same reasons as commented |
391 | - * at btrfs_ioctl_clone(). |
392 | - */ |
393 | - if (last_dest_end > 0) { |
394 | - ret = -EOPNOTSUPP; |
395 | - btrfs_end_transaction(trans, root); |
396 | - goto out; |
397 | - } |
398 | |
399 | if (off > key.offset) { |
400 | skip = off - key.offset; |
401 | @@ -3464,42 +3593,22 @@ process_slot: |
402 | size -= skip + trim; |
403 | datal -= skip + trim; |
404 | |
405 | - aligned_end = ALIGN(new_key.offset + datal, |
406 | - root->sectorsize); |
407 | - ret = btrfs_drop_extents(trans, root, inode, |
408 | - drop_start, |
409 | - aligned_end, |
410 | - 1); |
411 | + ret = clone_copy_inline_extent(src, inode, |
412 | + trans, path, |
413 | + &new_key, |
414 | + drop_start, |
415 | + datal, |
416 | + skip, size, buf); |
417 | if (ret) { |
418 | if (ret != -EOPNOTSUPP) |
419 | btrfs_abort_transaction(trans, |
420 | - root, ret); |
421 | - btrfs_end_transaction(trans, root); |
422 | - goto out; |
423 | - } |
424 | - |
425 | - ret = btrfs_insert_empty_item(trans, root, path, |
426 | - &new_key, size); |
427 | - if (ret) { |
428 | - btrfs_abort_transaction(trans, root, |
429 | - ret); |
430 | + root, |
431 | + ret); |
432 | btrfs_end_transaction(trans, root); |
433 | goto out; |
434 | } |
435 | - |
436 | - if (skip) { |
437 | - u32 start = |
438 | - btrfs_file_extent_calc_inline_size(0); |
439 | - memmove(buf+start, buf+start+skip, |
440 | - datal); |
441 | - } |
442 | - |
443 | leaf = path->nodes[0]; |
444 | slot = path->slots[0]; |
445 | - write_extent_buffer(leaf, buf, |
446 | - btrfs_item_ptr_offset(leaf, slot), |
447 | - size); |
448 | - inode_add_bytes(inode, datal); |
449 | } |
450 | |
451 | /* If we have an implicit hole (NO_HOLES feature). */ |
452 | diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c |
453 | index 6f518c90e1c1..1fcd7b6e7564 100644 |
454 | --- a/fs/btrfs/xattr.c |
455 | +++ b/fs/btrfs/xattr.c |
456 | @@ -313,8 +313,10 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) |
457 | /* check to make sure this item is what we want */ |
458 | if (found_key.objectid != key.objectid) |
459 | break; |
460 | - if (found_key.type != BTRFS_XATTR_ITEM_KEY) |
461 | + if (found_key.type > BTRFS_XATTR_ITEM_KEY) |
462 | break; |
463 | + if (found_key.type < BTRFS_XATTR_ITEM_KEY) |
464 | + goto next; |
465 | |
466 | di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); |
467 | if (verify_dir_item(root, leaf, di)) |
468 | diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c |
469 | index 84f37f34f9aa..1e99b29650a9 100644 |
470 | --- a/fs/ceph/mds_client.c |
471 | +++ b/fs/ceph/mds_client.c |
472 | @@ -1905,7 +1905,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc, |
473 | |
474 | len = sizeof(*head) + |
475 | pathlen1 + pathlen2 + 2*(1 + sizeof(u32) + sizeof(u64)) + |
476 | - sizeof(struct timespec); |
477 | + sizeof(struct ceph_timespec); |
478 | |
479 | /* calculate (max) length for cap releases */ |
480 | len += sizeof(struct ceph_mds_request_release) * |
481 | diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c |
482 | index 12756040ca20..8bec8f1e4b31 100644 |
483 | --- a/fs/debugfs/inode.c |
484 | +++ b/fs/debugfs/inode.c |
485 | @@ -276,8 +276,12 @@ static struct dentry *start_creating(const char *name, struct dentry *parent) |
486 | dput(dentry); |
487 | dentry = ERR_PTR(-EEXIST); |
488 | } |
489 | - if (IS_ERR(dentry)) |
490 | + |
491 | + if (IS_ERR(dentry)) { |
492 | mutex_unlock(&d_inode(parent)->i_mutex); |
493 | + simple_release_fs(&debugfs_mount, &debugfs_mount_count); |
494 | + } |
495 | + |
496 | return dentry; |
497 | } |
498 | |
499 | diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c |
500 | index d41843181818..e770c1ee4613 100644 |
501 | --- a/fs/ext4/ext4_jbd2.c |
502 | +++ b/fs/ext4/ext4_jbd2.c |
503 | @@ -88,13 +88,13 @@ int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) |
504 | return 0; |
505 | } |
506 | |
507 | + err = handle->h_err; |
508 | if (!handle->h_transaction) { |
509 | - err = jbd2_journal_stop(handle); |
510 | - return handle->h_err ? handle->h_err : err; |
511 | + rc = jbd2_journal_stop(handle); |
512 | + return err ? err : rc; |
513 | } |
514 | |
515 | sb = handle->h_transaction->t_journal->j_private; |
516 | - err = handle->h_err; |
517 | rc = jbd2_journal_stop(handle); |
518 | |
519 | if (!err) |
520 | diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c |
521 | index 5765f88b3904..8082565c59a9 100644 |
522 | --- a/fs/ext4/page-io.c |
523 | +++ b/fs/ext4/page-io.c |
524 | @@ -426,6 +426,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, |
525 | struct buffer_head *bh, *head; |
526 | int ret = 0; |
527 | int nr_submitted = 0; |
528 | + int nr_to_submit = 0; |
529 | |
530 | blocksize = 1 << inode->i_blkbits; |
531 | |
532 | @@ -478,11 +479,13 @@ int ext4_bio_write_page(struct ext4_io_submit *io, |
533 | unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr); |
534 | } |
535 | set_buffer_async_write(bh); |
536 | + nr_to_submit++; |
537 | } while ((bh = bh->b_this_page) != head); |
538 | |
539 | bh = head = page_buffers(page); |
540 | |
541 | - if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode)) { |
542 | + if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode) && |
543 | + nr_to_submit) { |
544 | data_page = ext4_encrypt(inode, page); |
545 | if (IS_ERR(data_page)) { |
546 | ret = PTR_ERR(data_page); |
547 | diff --git a/fs/ext4/super.c b/fs/ext4/super.c |
548 | index ff89971e3ee0..8a3b9f14d198 100644 |
549 | --- a/fs/ext4/super.c |
550 | +++ b/fs/ext4/super.c |
551 | @@ -396,9 +396,13 @@ static void ext4_handle_error(struct super_block *sb) |
552 | smp_wmb(); |
553 | sb->s_flags |= MS_RDONLY; |
554 | } |
555 | - if (test_opt(sb, ERRORS_PANIC)) |
556 | + if (test_opt(sb, ERRORS_PANIC)) { |
557 | + if (EXT4_SB(sb)->s_journal && |
558 | + !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR)) |
559 | + return; |
560 | panic("EXT4-fs (device %s): panic forced after error\n", |
561 | sb->s_id); |
562 | + } |
563 | } |
564 | |
565 | #define ext4_error_ratelimit(sb) \ |
566 | @@ -587,8 +591,12 @@ void __ext4_abort(struct super_block *sb, const char *function, |
567 | jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); |
568 | save_error_info(sb, function, line); |
569 | } |
570 | - if (test_opt(sb, ERRORS_PANIC)) |
571 | + if (test_opt(sb, ERRORS_PANIC)) { |
572 | + if (EXT4_SB(sb)->s_journal && |
573 | + !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR)) |
574 | + return; |
575 | panic("EXT4-fs panic from previous error\n"); |
576 | + } |
577 | } |
578 | |
579 | void __ext4_msg(struct super_block *sb, |
580 | diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c |
581 | index 7003c0925760..0469f32918a5 100644 |
582 | --- a/fs/jbd2/journal.c |
583 | +++ b/fs/jbd2/journal.c |
584 | @@ -2086,8 +2086,12 @@ static void __journal_abort_soft (journal_t *journal, int errno) |
585 | |
586 | __jbd2_journal_abort_hard(journal); |
587 | |
588 | - if (errno) |
589 | + if (errno) { |
590 | jbd2_journal_update_sb_errno(journal); |
591 | + write_lock(&journal->j_state_lock); |
592 | + journal->j_flags |= JBD2_REC_ERR; |
593 | + write_unlock(&journal->j_state_lock); |
594 | + } |
595 | } |
596 | |
597 | /** |
598 | diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c |
599 | index 976ba792fbc6..7f22b6c6fb50 100644 |
600 | --- a/fs/nfs/inode.c |
601 | +++ b/fs/nfs/inode.c |
602 | @@ -1813,7 +1813,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) |
603 | if ((long)fattr->gencount - (long)nfsi->attr_gencount > 0) |
604 | nfsi->attr_gencount = fattr->gencount; |
605 | } |
606 | - invalid &= ~NFS_INO_INVALID_ATTR; |
607 | + |
608 | + /* Don't declare attrcache up to date if there were no attrs! */ |
609 | + if (fattr->valid != 0) |
610 | + invalid &= ~NFS_INO_INVALID_ATTR; |
611 | + |
612 | /* Don't invalidate the data if we were to blame */ |
613 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) |
614 | || S_ISLNK(inode->i_mode))) |
615 | diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c |
616 | index e42be52a8c18..5dea913baf46 100644 |
617 | --- a/fs/nfs/nfs4client.c |
618 | +++ b/fs/nfs/nfs4client.c |
619 | @@ -33,7 +33,7 @@ static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion) |
620 | return ret; |
621 | idr_preload(GFP_KERNEL); |
622 | spin_lock(&nn->nfs_client_lock); |
623 | - ret = idr_alloc(&nn->cb_ident_idr, clp, 0, 0, GFP_NOWAIT); |
624 | + ret = idr_alloc(&nn->cb_ident_idr, clp, 1, 0, GFP_NOWAIT); |
625 | if (ret >= 0) |
626 | clp->cl_cb_ident = ret; |
627 | spin_unlock(&nn->nfs_client_lock); |
628 | diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c |
629 | index 397798368b1a..bb6c324f1f3d 100644 |
630 | --- a/fs/nfsd/nfs4state.c |
631 | +++ b/fs/nfsd/nfs4state.c |
632 | @@ -765,16 +765,68 @@ void nfs4_unhash_stid(struct nfs4_stid *s) |
633 | s->sc_type = 0; |
634 | } |
635 | |
636 | -static void |
637 | +/** |
638 | + * nfs4_get_existing_delegation - Discover if this delegation already exists |
639 | + * @clp: a pointer to the nfs4_client we're granting a delegation to |
640 | + * @fp: a pointer to the nfs4_file we're granting a delegation on |
641 | + * |
642 | + * Return: |
643 | + * On success: NULL if an existing delegation was not found. |
644 | + * |
645 | + * On error: -EAGAIN if one was previously granted to this nfs4_client |
646 | + * for this nfs4_file. |
647 | + * |
648 | + */ |
649 | + |
650 | +static int |
651 | +nfs4_get_existing_delegation(struct nfs4_client *clp, struct nfs4_file *fp) |
652 | +{ |
653 | + struct nfs4_delegation *searchdp = NULL; |
654 | + struct nfs4_client *searchclp = NULL; |
655 | + |
656 | + lockdep_assert_held(&state_lock); |
657 | + lockdep_assert_held(&fp->fi_lock); |
658 | + |
659 | + list_for_each_entry(searchdp, &fp->fi_delegations, dl_perfile) { |
660 | + searchclp = searchdp->dl_stid.sc_client; |
661 | + if (clp == searchclp) { |
662 | + return -EAGAIN; |
663 | + } |
664 | + } |
665 | + return 0; |
666 | +} |
667 | + |
668 | +/** |
669 | + * hash_delegation_locked - Add a delegation to the appropriate lists |
670 | + * @dp: a pointer to the nfs4_delegation we are adding. |
671 | + * @fp: a pointer to the nfs4_file we're granting a delegation on |
672 | + * |
673 | + * Return: |
674 | + * On success: NULL if the delegation was successfully hashed. |
675 | + * |
676 | + * On error: -EAGAIN if one was previously granted to this |
677 | + * nfs4_client for this nfs4_file. Delegation is not hashed. |
678 | + * |
679 | + */ |
680 | + |
681 | +static int |
682 | hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp) |
683 | { |
684 | + int status; |
685 | + struct nfs4_client *clp = dp->dl_stid.sc_client; |
686 | + |
687 | lockdep_assert_held(&state_lock); |
688 | lockdep_assert_held(&fp->fi_lock); |
689 | |
690 | + status = nfs4_get_existing_delegation(clp, fp); |
691 | + if (status) |
692 | + return status; |
693 | + ++fp->fi_delegees; |
694 | atomic_inc(&dp->dl_stid.sc_count); |
695 | dp->dl_stid.sc_type = NFS4_DELEG_STID; |
696 | list_add(&dp->dl_perfile, &fp->fi_delegations); |
697 | - list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations); |
698 | + list_add(&dp->dl_perclnt, &clp->cl_delegations); |
699 | + return 0; |
700 | } |
701 | |
702 | static bool |
703 | @@ -3351,6 +3403,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp, |
704 | stp->st_access_bmap = 0; |
705 | stp->st_deny_bmap = 0; |
706 | stp->st_openstp = NULL; |
707 | + init_rwsem(&stp->st_rwsem); |
708 | spin_lock(&oo->oo_owner.so_client->cl_lock); |
709 | list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids); |
710 | spin_lock(&fp->fi_lock); |
711 | @@ -3940,6 +3993,18 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag) |
712 | return fl; |
713 | } |
714 | |
715 | +/** |
716 | + * nfs4_setlease - Obtain a delegation by requesting lease from vfs layer |
717 | + * @dp: a pointer to the nfs4_delegation we're adding. |
718 | + * |
719 | + * Return: |
720 | + * On success: Return code will be 0 on success. |
721 | + * |
722 | + * On error: -EAGAIN if there was an existing delegation. |
723 | + * nonzero if there is an error in other cases. |
724 | + * |
725 | + */ |
726 | + |
727 | static int nfs4_setlease(struct nfs4_delegation *dp) |
728 | { |
729 | struct nfs4_file *fp = dp->dl_stid.sc_file; |
730 | @@ -3971,16 +4036,19 @@ static int nfs4_setlease(struct nfs4_delegation *dp) |
731 | goto out_unlock; |
732 | /* Race breaker */ |
733 | if (fp->fi_deleg_file) { |
734 | - status = 0; |
735 | - ++fp->fi_delegees; |
736 | - hash_delegation_locked(dp, fp); |
737 | + status = hash_delegation_locked(dp, fp); |
738 | goto out_unlock; |
739 | } |
740 | fp->fi_deleg_file = filp; |
741 | - fp->fi_delegees = 1; |
742 | - hash_delegation_locked(dp, fp); |
743 | + fp->fi_delegees = 0; |
744 | + status = hash_delegation_locked(dp, fp); |
745 | spin_unlock(&fp->fi_lock); |
746 | spin_unlock(&state_lock); |
747 | + if (status) { |
748 | + /* Should never happen, this is a new fi_deleg_file */ |
749 | + WARN_ON_ONCE(1); |
750 | + goto out_fput; |
751 | + } |
752 | return 0; |
753 | out_unlock: |
754 | spin_unlock(&fp->fi_lock); |
755 | @@ -4000,6 +4068,15 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, |
756 | if (fp->fi_had_conflict) |
757 | return ERR_PTR(-EAGAIN); |
758 | |
759 | + spin_lock(&state_lock); |
760 | + spin_lock(&fp->fi_lock); |
761 | + status = nfs4_get_existing_delegation(clp, fp); |
762 | + spin_unlock(&fp->fi_lock); |
763 | + spin_unlock(&state_lock); |
764 | + |
765 | + if (status) |
766 | + return ERR_PTR(status); |
767 | + |
768 | dp = alloc_init_deleg(clp, fh, odstate); |
769 | if (!dp) |
770 | return ERR_PTR(-ENOMEM); |
771 | @@ -4018,9 +4095,7 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, |
772 | status = -EAGAIN; |
773 | goto out_unlock; |
774 | } |
775 | - ++fp->fi_delegees; |
776 | - hash_delegation_locked(dp, fp); |
777 | - status = 0; |
778 | + status = hash_delegation_locked(dp, fp); |
779 | out_unlock: |
780 | spin_unlock(&fp->fi_lock); |
781 | spin_unlock(&state_lock); |
782 | @@ -4181,15 +4256,20 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf |
783 | */ |
784 | if (stp) { |
785 | /* Stateid was found, this is an OPEN upgrade */ |
786 | + down_read(&stp->st_rwsem); |
787 | status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open); |
788 | - if (status) |
789 | + if (status) { |
790 | + up_read(&stp->st_rwsem); |
791 | goto out; |
792 | + } |
793 | } else { |
794 | stp = open->op_stp; |
795 | open->op_stp = NULL; |
796 | init_open_stateid(stp, fp, open); |
797 | + down_read(&stp->st_rwsem); |
798 | status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open); |
799 | if (status) { |
800 | + up_read(&stp->st_rwsem); |
801 | release_open_stateid(stp); |
802 | goto out; |
803 | } |
804 | @@ -4201,6 +4281,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf |
805 | } |
806 | update_stateid(&stp->st_stid.sc_stateid); |
807 | memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); |
808 | + up_read(&stp->st_rwsem); |
809 | |
810 | if (nfsd4_has_session(&resp->cstate)) { |
811 | if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) { |
812 | @@ -4777,10 +4858,13 @@ static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_ |
813 | * revoked delegations are kept only for free_stateid. |
814 | */ |
815 | return nfserr_bad_stateid; |
816 | + down_write(&stp->st_rwsem); |
817 | status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate)); |
818 | - if (status) |
819 | - return status; |
820 | - return nfs4_check_fh(current_fh, &stp->st_stid); |
821 | + if (status == nfs_ok) |
822 | + status = nfs4_check_fh(current_fh, &stp->st_stid); |
823 | + if (status != nfs_ok) |
824 | + up_write(&stp->st_rwsem); |
825 | + return status; |
826 | } |
827 | |
828 | /* |
829 | @@ -4827,6 +4911,7 @@ static __be32 nfs4_preprocess_confirmed_seqid_op(struct nfsd4_compound_state *cs |
830 | return status; |
831 | oo = openowner(stp->st_stateowner); |
832 | if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) { |
833 | + up_write(&stp->st_rwsem); |
834 | nfs4_put_stid(&stp->st_stid); |
835 | return nfserr_bad_stateid; |
836 | } |
837 | @@ -4857,11 +4942,14 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
838 | goto out; |
839 | oo = openowner(stp->st_stateowner); |
840 | status = nfserr_bad_stateid; |
841 | - if (oo->oo_flags & NFS4_OO_CONFIRMED) |
842 | + if (oo->oo_flags & NFS4_OO_CONFIRMED) { |
843 | + up_write(&stp->st_rwsem); |
844 | goto put_stateid; |
845 | + } |
846 | oo->oo_flags |= NFS4_OO_CONFIRMED; |
847 | update_stateid(&stp->st_stid.sc_stateid); |
848 | memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); |
849 | + up_write(&stp->st_rwsem); |
850 | dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n", |
851 | __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid)); |
852 | |
853 | @@ -4940,6 +5028,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, |
854 | memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); |
855 | status = nfs_ok; |
856 | put_stateid: |
857 | + up_write(&stp->st_rwsem); |
858 | nfs4_put_stid(&stp->st_stid); |
859 | out: |
860 | nfsd4_bump_seqid(cstate, status); |
861 | @@ -4993,6 +5082,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
862 | goto out; |
863 | update_stateid(&stp->st_stid.sc_stateid); |
864 | memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t)); |
865 | + up_write(&stp->st_rwsem); |
866 | |
867 | nfsd4_close_open_stateid(stp); |
868 | |
869 | @@ -5223,6 +5313,7 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo, |
870 | stp->st_access_bmap = 0; |
871 | stp->st_deny_bmap = open_stp->st_deny_bmap; |
872 | stp->st_openstp = open_stp; |
873 | + init_rwsem(&stp->st_rwsem); |
874 | list_add(&stp->st_locks, &open_stp->st_locks); |
875 | list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids); |
876 | spin_lock(&fp->fi_lock); |
877 | @@ -5391,6 +5482,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
878 | &open_stp, nn); |
879 | if (status) |
880 | goto out; |
881 | + up_write(&open_stp->st_rwsem); |
882 | open_sop = openowner(open_stp->st_stateowner); |
883 | status = nfserr_bad_stateid; |
884 | if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid, |
885 | @@ -5398,6 +5490,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
886 | goto out; |
887 | status = lookup_or_create_lock_state(cstate, open_stp, lock, |
888 | &lock_stp, &new); |
889 | + if (status == nfs_ok) |
890 | + down_write(&lock_stp->st_rwsem); |
891 | } else { |
892 | status = nfs4_preprocess_seqid_op(cstate, |
893 | lock->lk_old_lock_seqid, |
894 | @@ -5503,6 +5597,8 @@ out: |
895 | seqid_mutating_err(ntohl(status))) |
896 | lock_sop->lo_owner.so_seqid++; |
897 | |
898 | + up_write(&lock_stp->st_rwsem); |
899 | + |
900 | /* |
901 | * If this is a new, never-before-used stateid, and we are |
902 | * returning an error, then just go ahead and release it. |
903 | @@ -5673,6 +5769,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, |
904 | fput: |
905 | fput(filp); |
906 | put_stateid: |
907 | + up_write(&stp->st_rwsem); |
908 | nfs4_put_stid(&stp->st_stid); |
909 | out: |
910 | nfsd4_bump_seqid(cstate, status); |
911 | diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h |
912 | index dbc4f85a5008..67685b6cfef3 100644 |
913 | --- a/fs/nfsd/state.h |
914 | +++ b/fs/nfsd/state.h |
915 | @@ -533,15 +533,16 @@ struct nfs4_file { |
916 | * Better suggestions welcome. |
917 | */ |
918 | struct nfs4_ol_stateid { |
919 | - struct nfs4_stid st_stid; /* must be first field */ |
920 | - struct list_head st_perfile; |
921 | - struct list_head st_perstateowner; |
922 | - struct list_head st_locks; |
923 | - struct nfs4_stateowner * st_stateowner; |
924 | - struct nfs4_clnt_odstate * st_clnt_odstate; |
925 | - unsigned char st_access_bmap; |
926 | - unsigned char st_deny_bmap; |
927 | - struct nfs4_ol_stateid * st_openstp; |
928 | + struct nfs4_stid st_stid; |
929 | + struct list_head st_perfile; |
930 | + struct list_head st_perstateowner; |
931 | + struct list_head st_locks; |
932 | + struct nfs4_stateowner *st_stateowner; |
933 | + struct nfs4_clnt_odstate *st_clnt_odstate; |
934 | + unsigned char st_access_bmap; |
935 | + unsigned char st_deny_bmap; |
936 | + struct nfs4_ol_stateid *st_openstp; |
937 | + struct rw_semaphore st_rwsem; |
938 | }; |
939 | |
940 | static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s) |
941 | diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c |
942 | index 176fe6afd94e..4d5e0a573f4f 100644 |
943 | --- a/fs/ocfs2/namei.c |
944 | +++ b/fs/ocfs2/namei.c |
945 | @@ -365,6 +365,8 @@ static int ocfs2_mknod(struct inode *dir, |
946 | mlog_errno(status); |
947 | goto leave; |
948 | } |
949 | + /* update inode->i_mode after mask with "umask". */ |
950 | + inode->i_mode = mode; |
951 | |
952 | handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb, |
953 | S_ISDIR(mode), |
954 | diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h |
955 | index 82806c60aa42..e4b464983322 100644 |
956 | --- a/include/linux/ipv6.h |
957 | +++ b/include/linux/ipv6.h |
958 | @@ -224,7 +224,7 @@ struct ipv6_pinfo { |
959 | struct ipv6_ac_socklist *ipv6_ac_list; |
960 | struct ipv6_fl_socklist __rcu *ipv6_fl_list; |
961 | |
962 | - struct ipv6_txoptions *opt; |
963 | + struct ipv6_txoptions __rcu *opt; |
964 | struct sk_buff *pktoptions; |
965 | struct sk_buff *rxpmtu; |
966 | struct inet6_cork cork; |
967 | diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h |
968 | index eb1cebed3f36..c90c9b70e568 100644 |
969 | --- a/include/linux/jbd2.h |
970 | +++ b/include/linux/jbd2.h |
971 | @@ -1007,6 +1007,7 @@ struct journal_s |
972 | #define JBD2_ABORT_ON_SYNCDATA_ERR 0x040 /* Abort the journal on file |
973 | * data write error in ordered |
974 | * mode */ |
975 | +#define JBD2_REC_ERR 0x080 /* The errno in the sb has been recorded */ |
976 | |
977 | /* |
978 | * Function declarations for the journaling transaction and buffer |
979 | diff --git a/include/net/af_unix.h b/include/net/af_unix.h |
980 | index dfe4ddfbb43c..e830c3dff61a 100644 |
981 | --- a/include/net/af_unix.h |
982 | +++ b/include/net/af_unix.h |
983 | @@ -63,6 +63,7 @@ struct unix_sock { |
984 | #define UNIX_GC_CANDIDATE 0 |
985 | #define UNIX_GC_MAYBE_CYCLE 1 |
986 | struct socket_wq peer_wq; |
987 | + wait_queue_t peer_wake; |
988 | }; |
989 | |
990 | static inline struct unix_sock *unix_sk(struct sock *sk) |
991 | diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h |
992 | index b8529aa1dae7..b0f7445c0fdc 100644 |
993 | --- a/include/net/ip6_tunnel.h |
994 | +++ b/include/net/ip6_tunnel.h |
995 | @@ -83,11 +83,12 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb, |
996 | err = ip6_local_out_sk(sk, skb); |
997 | |
998 | if (net_xmit_eval(err) == 0) { |
999 | - struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); |
1000 | + struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats); |
1001 | u64_stats_update_begin(&tstats->syncp); |
1002 | tstats->tx_bytes += pkt_len; |
1003 | tstats->tx_packets++; |
1004 | u64_stats_update_end(&tstats->syncp); |
1005 | + put_cpu_ptr(tstats); |
1006 | } else { |
1007 | stats->tx_errors++; |
1008 | stats->tx_aborted_errors++; |
1009 | diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h |
1010 | index d8214cb88bbc..9c2897e56ee1 100644 |
1011 | --- a/include/net/ip_tunnels.h |
1012 | +++ b/include/net/ip_tunnels.h |
1013 | @@ -207,12 +207,13 @@ static inline void iptunnel_xmit_stats(int err, |
1014 | struct pcpu_sw_netstats __percpu *stats) |
1015 | { |
1016 | if (err > 0) { |
1017 | - struct pcpu_sw_netstats *tstats = this_cpu_ptr(stats); |
1018 | + struct pcpu_sw_netstats *tstats = get_cpu_ptr(stats); |
1019 | |
1020 | u64_stats_update_begin(&tstats->syncp); |
1021 | tstats->tx_bytes += err; |
1022 | tstats->tx_packets++; |
1023 | u64_stats_update_end(&tstats->syncp); |
1024 | + put_cpu_ptr(tstats); |
1025 | } else if (err < 0) { |
1026 | err_stats->tx_errors++; |
1027 | err_stats->tx_aborted_errors++; |
1028 | diff --git a/include/net/ipv6.h b/include/net/ipv6.h |
1029 | index eec8ad3c9843..df555ecd4002 100644 |
1030 | --- a/include/net/ipv6.h |
1031 | +++ b/include/net/ipv6.h |
1032 | @@ -205,6 +205,7 @@ extern rwlock_t ip6_ra_lock; |
1033 | */ |
1034 | |
1035 | struct ipv6_txoptions { |
1036 | + atomic_t refcnt; |
1037 | /* Length of this structure */ |
1038 | int tot_len; |
1039 | |
1040 | @@ -217,7 +218,7 @@ struct ipv6_txoptions { |
1041 | struct ipv6_opt_hdr *dst0opt; |
1042 | struct ipv6_rt_hdr *srcrt; /* Routing Header */ |
1043 | struct ipv6_opt_hdr *dst1opt; |
1044 | - |
1045 | + struct rcu_head rcu; |
1046 | /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ |
1047 | }; |
1048 | |
1049 | @@ -250,6 +251,24 @@ struct ipv6_fl_socklist { |
1050 | struct rcu_head rcu; |
1051 | }; |
1052 | |
1053 | +static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np) |
1054 | +{ |
1055 | + struct ipv6_txoptions *opt; |
1056 | + |
1057 | + rcu_read_lock(); |
1058 | + opt = rcu_dereference(np->opt); |
1059 | + if (opt && !atomic_inc_not_zero(&opt->refcnt)) |
1060 | + opt = NULL; |
1061 | + rcu_read_unlock(); |
1062 | + return opt; |
1063 | +} |
1064 | + |
1065 | +static inline void txopt_put(struct ipv6_txoptions *opt) |
1066 | +{ |
1067 | + if (opt && atomic_dec_and_test(&opt->refcnt)) |
1068 | + kfree_rcu(opt, rcu); |
1069 | +} |
1070 | + |
1071 | struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, __be32 label); |
1072 | struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space, |
1073 | struct ip6_flowlabel *fl, |
1074 | @@ -488,6 +507,7 @@ struct ip6_create_arg { |
1075 | u32 user; |
1076 | const struct in6_addr *src; |
1077 | const struct in6_addr *dst; |
1078 | + int iif; |
1079 | u8 ecn; |
1080 | }; |
1081 | |
1082 | diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h |
1083 | index 6d778efcfdfd..080b657ef8fb 100644 |
1084 | --- a/include/net/sch_generic.h |
1085 | +++ b/include/net/sch_generic.h |
1086 | @@ -61,6 +61,9 @@ struct Qdisc { |
1087 | */ |
1088 | #define TCQ_F_WARN_NONWC (1 << 16) |
1089 | #define TCQ_F_CPUSTATS 0x20 /* run using percpu statistics */ |
1090 | +#define TCQ_F_NOPARENT 0x40 /* root of its hierarchy : |
1091 | + * qdisc_tree_decrease_qlen() should stop. |
1092 | + */ |
1093 | u32 limit; |
1094 | const struct Qdisc_ops *ops; |
1095 | struct qdisc_size_table __rcu *stab; |
1096 | diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c |
1097 | index 8a6616583f38..1c1b8ab34037 100644 |
1098 | --- a/kernel/bpf/arraymap.c |
1099 | +++ b/kernel/bpf/arraymap.c |
1100 | @@ -109,7 +109,7 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value, |
1101 | /* all elements already exist */ |
1102 | return -EEXIST; |
1103 | |
1104 | - memcpy(array->value + array->elem_size * index, value, array->elem_size); |
1105 | + memcpy(array->value + array->elem_size * index, value, map->value_size); |
1106 | return 0; |
1107 | } |
1108 | |
1109 | diff --git a/net/core/neighbour.c b/net/core/neighbour.c |
1110 | index 2237c1b3cdd2..d6e8cfcb6f7c 100644 |
1111 | --- a/net/core/neighbour.c |
1112 | +++ b/net/core/neighbour.c |
1113 | @@ -2207,7 +2207,7 @@ static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn, |
1114 | ndm->ndm_pad2 = 0; |
1115 | ndm->ndm_flags = pn->flags | NTF_PROXY; |
1116 | ndm->ndm_type = RTN_UNICAST; |
1117 | - ndm->ndm_ifindex = pn->dev->ifindex; |
1118 | + ndm->ndm_ifindex = pn->dev ? pn->dev->ifindex : 0; |
1119 | ndm->ndm_state = NUD_NONE; |
1120 | |
1121 | if (nla_put(skb, NDA_DST, tbl->key_len, pn->key)) |
1122 | @@ -2282,7 +2282,7 @@ static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, |
1123 | if (h > s_h) |
1124 | s_idx = 0; |
1125 | for (n = tbl->phash_buckets[h], idx = 0; n; n = n->next) { |
1126 | - if (dev_net(n->dev) != net) |
1127 | + if (pneigh_net(n) != net) |
1128 | continue; |
1129 | if (idx < s_idx) |
1130 | goto next; |
1131 | diff --git a/net/core/scm.c b/net/core/scm.c |
1132 | index 3b6899b7d810..8a1741b14302 100644 |
1133 | --- a/net/core/scm.c |
1134 | +++ b/net/core/scm.c |
1135 | @@ -305,6 +305,8 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) |
1136 | err = put_user(cmlen, &cm->cmsg_len); |
1137 | if (!err) { |
1138 | cmlen = CMSG_SPACE(i*sizeof(int)); |
1139 | + if (msg->msg_controllen < cmlen) |
1140 | + cmlen = msg->msg_controllen; |
1141 | msg->msg_control += cmlen; |
1142 | msg->msg_controllen -= cmlen; |
1143 | } |
1144 | diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c |
1145 | index 5165571f397a..a0490508d213 100644 |
1146 | --- a/net/dccp/ipv6.c |
1147 | +++ b/net/dccp/ipv6.c |
1148 | @@ -202,7 +202,9 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req) |
1149 | security_req_classify_flow(req, flowi6_to_flowi(&fl6)); |
1150 | |
1151 | |
1152 | - final_p = fl6_update_dst(&fl6, np->opt, &final); |
1153 | + rcu_read_lock(); |
1154 | + final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); |
1155 | + rcu_read_unlock(); |
1156 | |
1157 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); |
1158 | if (IS_ERR(dst)) { |
1159 | @@ -219,7 +221,10 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req) |
1160 | &ireq->ir_v6_loc_addr, |
1161 | &ireq->ir_v6_rmt_addr); |
1162 | fl6.daddr = ireq->ir_v6_rmt_addr; |
1163 | - err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); |
1164 | + rcu_read_lock(); |
1165 | + err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt), |
1166 | + np->tclass); |
1167 | + rcu_read_unlock(); |
1168 | err = net_xmit_eval(err); |
1169 | } |
1170 | |
1171 | @@ -415,6 +420,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, |
1172 | { |
1173 | struct inet_request_sock *ireq = inet_rsk(req); |
1174 | struct ipv6_pinfo *newnp, *np = inet6_sk(sk); |
1175 | + struct ipv6_txoptions *opt; |
1176 | struct inet_sock *newinet; |
1177 | struct dccp6_sock *newdp6; |
1178 | struct sock *newsk; |
1179 | @@ -534,13 +540,15 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, |
1180 | * Yes, keeping reference count would be much more clever, but we make |
1181 | * one more one thing there: reattach optmem to newsk. |
1182 | */ |
1183 | - if (np->opt != NULL) |
1184 | - newnp->opt = ipv6_dup_options(newsk, np->opt); |
1185 | - |
1186 | + opt = rcu_dereference(np->opt); |
1187 | + if (opt) { |
1188 | + opt = ipv6_dup_options(newsk, opt); |
1189 | + RCU_INIT_POINTER(newnp->opt, opt); |
1190 | + } |
1191 | inet_csk(newsk)->icsk_ext_hdr_len = 0; |
1192 | - if (newnp->opt != NULL) |
1193 | - inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + |
1194 | - newnp->opt->opt_flen); |
1195 | + if (opt) |
1196 | + inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + |
1197 | + opt->opt_flen; |
1198 | |
1199 | dccp_sync_mss(newsk, dst_mtu(dst)); |
1200 | |
1201 | @@ -793,6 +801,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, |
1202 | struct ipv6_pinfo *np = inet6_sk(sk); |
1203 | struct dccp_sock *dp = dccp_sk(sk); |
1204 | struct in6_addr *saddr = NULL, *final_p, final; |
1205 | + struct ipv6_txoptions *opt; |
1206 | struct flowi6 fl6; |
1207 | struct dst_entry *dst; |
1208 | int addr_type; |
1209 | @@ -892,7 +901,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, |
1210 | fl6.fl6_sport = inet->inet_sport; |
1211 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
1212 | |
1213 | - final_p = fl6_update_dst(&fl6, np->opt, &final); |
1214 | + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); |
1215 | + final_p = fl6_update_dst(&fl6, opt, &final); |
1216 | |
1217 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); |
1218 | if (IS_ERR(dst)) { |
1219 | @@ -912,9 +922,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, |
1220 | __ip6_dst_store(sk, dst, NULL, NULL); |
1221 | |
1222 | icsk->icsk_ext_hdr_len = 0; |
1223 | - if (np->opt != NULL) |
1224 | - icsk->icsk_ext_hdr_len = (np->opt->opt_flen + |
1225 | - np->opt->opt_nflen); |
1226 | + if (opt) |
1227 | + icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen; |
1228 | |
1229 | inet->inet_dport = usin->sin6_port; |
1230 | |
1231 | diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c |
1232 | index df28693f32e1..c3bfebd501ed 100644 |
1233 | --- a/net/ipv4/ipmr.c |
1234 | +++ b/net/ipv4/ipmr.c |
1235 | @@ -134,7 +134,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, |
1236 | struct mfc_cache *c, struct rtmsg *rtm); |
1237 | static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc, |
1238 | int cmd); |
1239 | -static void mroute_clean_tables(struct mr_table *mrt); |
1240 | +static void mroute_clean_tables(struct mr_table *mrt, bool all); |
1241 | static void ipmr_expire_process(unsigned long arg); |
1242 | |
1243 | #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES |
1244 | @@ -351,7 +351,7 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id) |
1245 | static void ipmr_free_table(struct mr_table *mrt) |
1246 | { |
1247 | del_timer_sync(&mrt->ipmr_expire_timer); |
1248 | - mroute_clean_tables(mrt); |
1249 | + mroute_clean_tables(mrt, true); |
1250 | kfree(mrt); |
1251 | } |
1252 | |
1253 | @@ -1209,7 +1209,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt, |
1254 | * Close the multicast socket, and clear the vif tables etc |
1255 | */ |
1256 | |
1257 | -static void mroute_clean_tables(struct mr_table *mrt) |
1258 | +static void mroute_clean_tables(struct mr_table *mrt, bool all) |
1259 | { |
1260 | int i; |
1261 | LIST_HEAD(list); |
1262 | @@ -1218,8 +1218,9 @@ static void mroute_clean_tables(struct mr_table *mrt) |
1263 | /* Shut down all active vif entries */ |
1264 | |
1265 | for (i = 0; i < mrt->maxvif; i++) { |
1266 | - if (!(mrt->vif_table[i].flags & VIFF_STATIC)) |
1267 | - vif_delete(mrt, i, 0, &list); |
1268 | + if (!all && (mrt->vif_table[i].flags & VIFF_STATIC)) |
1269 | + continue; |
1270 | + vif_delete(mrt, i, 0, &list); |
1271 | } |
1272 | unregister_netdevice_many(&list); |
1273 | |
1274 | @@ -1227,7 +1228,7 @@ static void mroute_clean_tables(struct mr_table *mrt) |
1275 | |
1276 | for (i = 0; i < MFC_LINES; i++) { |
1277 | list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) { |
1278 | - if (c->mfc_flags & MFC_STATIC) |
1279 | + if (!all && (c->mfc_flags & MFC_STATIC)) |
1280 | continue; |
1281 | list_del_rcu(&c->list); |
1282 | mroute_netlink_event(mrt, c, RTM_DELROUTE); |
1283 | @@ -1262,7 +1263,7 @@ static void mrtsock_destruct(struct sock *sk) |
1284 | NETCONFA_IFINDEX_ALL, |
1285 | net->ipv4.devconf_all); |
1286 | RCU_INIT_POINTER(mrt->mroute_sk, NULL); |
1287 | - mroute_clean_tables(mrt); |
1288 | + mroute_clean_tables(mrt, false); |
1289 | } |
1290 | } |
1291 | rtnl_unlock(); |
1292 | diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c |
1293 | index c9ab964189a0..87463c814896 100644 |
1294 | --- a/net/ipv4/tcp_input.c |
1295 | +++ b/net/ipv4/tcp_input.c |
1296 | @@ -4438,19 +4438,34 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int |
1297 | int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) |
1298 | { |
1299 | struct sk_buff *skb; |
1300 | + int err = -ENOMEM; |
1301 | + int data_len = 0; |
1302 | bool fragstolen; |
1303 | |
1304 | if (size == 0) |
1305 | return 0; |
1306 | |
1307 | - skb = alloc_skb(size, sk->sk_allocation); |
1308 | + if (size > PAGE_SIZE) { |
1309 | + int npages = min_t(size_t, size >> PAGE_SHIFT, MAX_SKB_FRAGS); |
1310 | + |
1311 | + data_len = npages << PAGE_SHIFT; |
1312 | + size = data_len + (size & ~PAGE_MASK); |
1313 | + } |
1314 | + skb = alloc_skb_with_frags(size - data_len, data_len, |
1315 | + PAGE_ALLOC_COSTLY_ORDER, |
1316 | + &err, sk->sk_allocation); |
1317 | if (!skb) |
1318 | goto err; |
1319 | |
1320 | + skb_put(skb, size - data_len); |
1321 | + skb->data_len = data_len; |
1322 | + skb->len = size; |
1323 | + |
1324 | if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) |
1325 | goto err_free; |
1326 | |
1327 | - if (memcpy_from_msg(skb_put(skb, size), msg, size)) |
1328 | + err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size); |
1329 | + if (err) |
1330 | goto err_free; |
1331 | |
1332 | TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt; |
1333 | @@ -4466,7 +4481,8 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) |
1334 | err_free: |
1335 | kfree_skb(skb); |
1336 | err: |
1337 | - return -ENOMEM; |
1338 | + return err; |
1339 | + |
1340 | } |
1341 | |
1342 | static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) |
1343 | @@ -5622,6 +5638,7 @@ discard: |
1344 | } |
1345 | |
1346 | tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1; |
1347 | + tp->copied_seq = tp->rcv_nxt; |
1348 | tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1; |
1349 | |
1350 | /* RFC1323: The window in SYN & SYN/ACK segments is |
1351 | diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c |
1352 | index 441ca6f38981..88203e755af8 100644 |
1353 | --- a/net/ipv4/tcp_ipv4.c |
1354 | +++ b/net/ipv4/tcp_ipv4.c |
1355 | @@ -922,7 +922,8 @@ int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, |
1356 | } |
1357 | |
1358 | md5sig = rcu_dereference_protected(tp->md5sig_info, |
1359 | - sock_owned_by_user(sk)); |
1360 | + sock_owned_by_user(sk) || |
1361 | + lockdep_is_held(&sk->sk_lock.slock)); |
1362 | if (!md5sig) { |
1363 | md5sig = kmalloc(sizeof(*md5sig), gfp); |
1364 | if (!md5sig) |
1365 | diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c |
1366 | index 8c65dc147d8b..c8f97858d6f6 100644 |
1367 | --- a/net/ipv4/tcp_timer.c |
1368 | +++ b/net/ipv4/tcp_timer.c |
1369 | @@ -176,6 +176,18 @@ static int tcp_write_timeout(struct sock *sk) |
1370 | syn_set = true; |
1371 | } else { |
1372 | if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0, 0)) { |
1373 | + /* Some middle-boxes may black-hole Fast Open _after_ |
1374 | + * the handshake. Therefore we conservatively disable |
1375 | + * Fast Open on this path on recurring timeouts with |
1376 | + * few or zero bytes acked after Fast Open. |
1377 | + */ |
1378 | + if (tp->syn_data_acked && |
1379 | + tp->bytes_acked <= tp->rx_opt.mss_clamp) { |
1380 | + tcp_fastopen_cache_set(sk, 0, NULL, true, 0); |
1381 | + if (icsk->icsk_retransmits == sysctl_tcp_retries1) |
1382 | + NET_INC_STATS_BH(sock_net(sk), |
1383 | + LINUX_MIB_TCPFASTOPENACTIVEFAIL); |
1384 | + } |
1385 | /* Black hole detection */ |
1386 | tcp_mtu_probing(icsk, sk); |
1387 | |
1388 | diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c |
1389 | index eef63b394c5a..2d044d2a2ccf 100644 |
1390 | --- a/net/ipv6/af_inet6.c |
1391 | +++ b/net/ipv6/af_inet6.c |
1392 | @@ -425,9 +425,11 @@ void inet6_destroy_sock(struct sock *sk) |
1393 | |
1394 | /* Free tx options */ |
1395 | |
1396 | - opt = xchg(&np->opt, NULL); |
1397 | - if (opt) |
1398 | - sock_kfree_s(sk, opt, opt->tot_len); |
1399 | + opt = xchg((__force struct ipv6_txoptions **)&np->opt, NULL); |
1400 | + if (opt) { |
1401 | + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); |
1402 | + txopt_put(opt); |
1403 | + } |
1404 | } |
1405 | EXPORT_SYMBOL_GPL(inet6_destroy_sock); |
1406 | |
1407 | @@ -656,7 +658,10 @@ int inet6_sk_rebuild_header(struct sock *sk) |
1408 | fl6.fl6_sport = inet->inet_sport; |
1409 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
1410 | |
1411 | - final_p = fl6_update_dst(&fl6, np->opt, &final); |
1412 | + rcu_read_lock(); |
1413 | + final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), |
1414 | + &final); |
1415 | + rcu_read_unlock(); |
1416 | |
1417 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); |
1418 | if (IS_ERR(dst)) { |
1419 | diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c |
1420 | index b10a88986a98..13ca4cf5616f 100644 |
1421 | --- a/net/ipv6/datagram.c |
1422 | +++ b/net/ipv6/datagram.c |
1423 | @@ -167,8 +167,10 @@ ipv4_connected: |
1424 | |
1425 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
1426 | |
1427 | - opt = flowlabel ? flowlabel->opt : np->opt; |
1428 | + rcu_read_lock(); |
1429 | + opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt); |
1430 | final_p = fl6_update_dst(&fl6, opt, &final); |
1431 | + rcu_read_unlock(); |
1432 | |
1433 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p); |
1434 | err = 0; |
1435 | diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c |
1436 | index a7bbbe45570b..adbd6958c398 100644 |
1437 | --- a/net/ipv6/exthdrs.c |
1438 | +++ b/net/ipv6/exthdrs.c |
1439 | @@ -727,6 +727,7 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt) |
1440 | *((char **)&opt2->dst1opt) += dif; |
1441 | if (opt2->srcrt) |
1442 | *((char **)&opt2->srcrt) += dif; |
1443 | + atomic_set(&opt2->refcnt, 1); |
1444 | } |
1445 | return opt2; |
1446 | } |
1447 | @@ -790,7 +791,7 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, |
1448 | return ERR_PTR(-ENOBUFS); |
1449 | |
1450 | memset(opt2, 0, tot_len); |
1451 | - |
1452 | + atomic_set(&opt2->refcnt, 1); |
1453 | opt2->tot_len = tot_len; |
1454 | p = (char *)(opt2 + 1); |
1455 | |
1456 | diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c |
1457 | index 6927f3fb5597..9beed302eb36 100644 |
1458 | --- a/net/ipv6/inet6_connection_sock.c |
1459 | +++ b/net/ipv6/inet6_connection_sock.c |
1460 | @@ -77,7 +77,9 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk, |
1461 | memset(fl6, 0, sizeof(*fl6)); |
1462 | fl6->flowi6_proto = IPPROTO_TCP; |
1463 | fl6->daddr = ireq->ir_v6_rmt_addr; |
1464 | - final_p = fl6_update_dst(fl6, np->opt, &final); |
1465 | + rcu_read_lock(); |
1466 | + final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); |
1467 | + rcu_read_unlock(); |
1468 | fl6->saddr = ireq->ir_v6_loc_addr; |
1469 | fl6->flowi6_oif = ireq->ir_iif; |
1470 | fl6->flowi6_mark = ireq->ir_mark; |
1471 | @@ -207,7 +209,9 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk, |
1472 | fl6->fl6_dport = inet->inet_dport; |
1473 | security_sk_classify_flow(sk, flowi6_to_flowi(fl6)); |
1474 | |
1475 | - final_p = fl6_update_dst(fl6, np->opt, &final); |
1476 | + rcu_read_lock(); |
1477 | + final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); |
1478 | + rcu_read_unlock(); |
1479 | |
1480 | dst = __inet6_csk_dst_check(sk, np->dst_cookie); |
1481 | if (!dst) { |
1482 | @@ -240,7 +244,8 @@ int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused |
1483 | /* Restore final destination back after routing done */ |
1484 | fl6.daddr = sk->sk_v6_daddr; |
1485 | |
1486 | - res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass); |
1487 | + res = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt), |
1488 | + np->tclass); |
1489 | rcu_read_unlock(); |
1490 | return res; |
1491 | } |
1492 | diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c |
1493 | index 5f36266b1f5e..a7aef4b52d65 100644 |
1494 | --- a/net/ipv6/ip6mr.c |
1495 | +++ b/net/ipv6/ip6mr.c |
1496 | @@ -118,7 +118,7 @@ static void mr6_netlink_event(struct mr6_table *mrt, struct mfc6_cache *mfc, |
1497 | int cmd); |
1498 | static int ip6mr_rtm_dumproute(struct sk_buff *skb, |
1499 | struct netlink_callback *cb); |
1500 | -static void mroute_clean_tables(struct mr6_table *mrt); |
1501 | +static void mroute_clean_tables(struct mr6_table *mrt, bool all); |
1502 | static void ipmr_expire_process(unsigned long arg); |
1503 | |
1504 | #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES |
1505 | @@ -335,7 +335,7 @@ static struct mr6_table *ip6mr_new_table(struct net *net, u32 id) |
1506 | static void ip6mr_free_table(struct mr6_table *mrt) |
1507 | { |
1508 | del_timer_sync(&mrt->ipmr_expire_timer); |
1509 | - mroute_clean_tables(mrt); |
1510 | + mroute_clean_tables(mrt, true); |
1511 | kfree(mrt); |
1512 | } |
1513 | |
1514 | @@ -1543,7 +1543,7 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt, |
1515 | * Close the multicast socket, and clear the vif tables etc |
1516 | */ |
1517 | |
1518 | -static void mroute_clean_tables(struct mr6_table *mrt) |
1519 | +static void mroute_clean_tables(struct mr6_table *mrt, bool all) |
1520 | { |
1521 | int i; |
1522 | LIST_HEAD(list); |
1523 | @@ -1553,8 +1553,9 @@ static void mroute_clean_tables(struct mr6_table *mrt) |
1524 | * Shut down all active vif entries |
1525 | */ |
1526 | for (i = 0; i < mrt->maxvif; i++) { |
1527 | - if (!(mrt->vif6_table[i].flags & VIFF_STATIC)) |
1528 | - mif6_delete(mrt, i, &list); |
1529 | + if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC)) |
1530 | + continue; |
1531 | + mif6_delete(mrt, i, &list); |
1532 | } |
1533 | unregister_netdevice_many(&list); |
1534 | |
1535 | @@ -1563,7 +1564,7 @@ static void mroute_clean_tables(struct mr6_table *mrt) |
1536 | */ |
1537 | for (i = 0; i < MFC6_LINES; i++) { |
1538 | list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) { |
1539 | - if (c->mfc_flags & MFC_STATIC) |
1540 | + if (!all && (c->mfc_flags & MFC_STATIC)) |
1541 | continue; |
1542 | write_lock_bh(&mrt_lock); |
1543 | list_del(&c->list); |
1544 | @@ -1626,7 +1627,7 @@ int ip6mr_sk_done(struct sock *sk) |
1545 | net->ipv6.devconf_all); |
1546 | write_unlock_bh(&mrt_lock); |
1547 | |
1548 | - mroute_clean_tables(mrt); |
1549 | + mroute_clean_tables(mrt, false); |
1550 | err = 0; |
1551 | break; |
1552 | } |
1553 | diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c |
1554 | index 63e6956917c9..4449ad1f8114 100644 |
1555 | --- a/net/ipv6/ipv6_sockglue.c |
1556 | +++ b/net/ipv6/ipv6_sockglue.c |
1557 | @@ -111,7 +111,8 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk, |
1558 | icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); |
1559 | } |
1560 | } |
1561 | - opt = xchg(&inet6_sk(sk)->opt, opt); |
1562 | + opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt, |
1563 | + opt); |
1564 | sk_dst_reset(sk); |
1565 | |
1566 | return opt; |
1567 | @@ -231,9 +232,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, |
1568 | sk->sk_socket->ops = &inet_dgram_ops; |
1569 | sk->sk_family = PF_INET; |
1570 | } |
1571 | - opt = xchg(&np->opt, NULL); |
1572 | - if (opt) |
1573 | - sock_kfree_s(sk, opt, opt->tot_len); |
1574 | + opt = xchg((__force struct ipv6_txoptions **)&np->opt, |
1575 | + NULL); |
1576 | + if (opt) { |
1577 | + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); |
1578 | + txopt_put(opt); |
1579 | + } |
1580 | pktopt = xchg(&np->pktoptions, NULL); |
1581 | kfree_skb(pktopt); |
1582 | |
1583 | @@ -403,7 +407,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, |
1584 | if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW)) |
1585 | break; |
1586 | |
1587 | - opt = ipv6_renew_options(sk, np->opt, optname, |
1588 | + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); |
1589 | + opt = ipv6_renew_options(sk, opt, optname, |
1590 | (struct ipv6_opt_hdr __user *)optval, |
1591 | optlen); |
1592 | if (IS_ERR(opt)) { |
1593 | @@ -432,8 +437,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, |
1594 | retv = 0; |
1595 | opt = ipv6_update_options(sk, opt); |
1596 | sticky_done: |
1597 | - if (opt) |
1598 | - sock_kfree_s(sk, opt, opt->tot_len); |
1599 | + if (opt) { |
1600 | + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); |
1601 | + txopt_put(opt); |
1602 | + } |
1603 | break; |
1604 | } |
1605 | |
1606 | @@ -486,6 +493,7 @@ sticky_done: |
1607 | break; |
1608 | |
1609 | memset(opt, 0, sizeof(*opt)); |
1610 | + atomic_set(&opt->refcnt, 1); |
1611 | opt->tot_len = sizeof(*opt) + optlen; |
1612 | retv = -EFAULT; |
1613 | if (copy_from_user(opt+1, optval, optlen)) |
1614 | @@ -502,8 +510,10 @@ update: |
1615 | retv = 0; |
1616 | opt = ipv6_update_options(sk, opt); |
1617 | done: |
1618 | - if (opt) |
1619 | - sock_kfree_s(sk, opt, opt->tot_len); |
1620 | + if (opt) { |
1621 | + atomic_sub(opt->tot_len, &sk->sk_omem_alloc); |
1622 | + txopt_put(opt); |
1623 | + } |
1624 | break; |
1625 | } |
1626 | case IPV6_UNICAST_HOPS: |
1627 | @@ -1110,10 +1120,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, |
1628 | case IPV6_RTHDR: |
1629 | case IPV6_DSTOPTS: |
1630 | { |
1631 | + struct ipv6_txoptions *opt; |
1632 | |
1633 | lock_sock(sk); |
1634 | - len = ipv6_getsockopt_sticky(sk, np->opt, |
1635 | - optname, optval, len); |
1636 | + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); |
1637 | + len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len); |
1638 | release_sock(sk); |
1639 | /* check if ipv6_getsockopt_sticky() returns err code */ |
1640 | if (len < 0) |
1641 | diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c |
1642 | index 083b2927fc67..41e3b5ee8d0b 100644 |
1643 | --- a/net/ipv6/mcast.c |
1644 | +++ b/net/ipv6/mcast.c |
1645 | @@ -1651,7 +1651,6 @@ out: |
1646 | if (!err) { |
1647 | ICMP6MSGOUT_INC_STATS(net, idev, ICMPV6_MLD2_REPORT); |
1648 | ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); |
1649 | - IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, payload_len); |
1650 | } else { |
1651 | IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); |
1652 | } |
1653 | @@ -2014,7 +2013,6 @@ out: |
1654 | if (!err) { |
1655 | ICMP6MSGOUT_INC_STATS(net, idev, type); |
1656 | ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); |
1657 | - IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len); |
1658 | } else |
1659 | IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); |
1660 | |
1661 | diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c |
1662 | index 6f187c8d8a1b..d235ed7f47ab 100644 |
1663 | --- a/net/ipv6/netfilter/nf_conntrack_reasm.c |
1664 | +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c |
1665 | @@ -190,7 +190,7 @@ static void nf_ct_frag6_expire(unsigned long data) |
1666 | /* Creation primitives. */ |
1667 | static inline struct frag_queue *fq_find(struct net *net, __be32 id, |
1668 | u32 user, struct in6_addr *src, |
1669 | - struct in6_addr *dst, u8 ecn) |
1670 | + struct in6_addr *dst, int iif, u8 ecn) |
1671 | { |
1672 | struct inet_frag_queue *q; |
1673 | struct ip6_create_arg arg; |
1674 | @@ -200,6 +200,7 @@ static inline struct frag_queue *fq_find(struct net *net, __be32 id, |
1675 | arg.user = user; |
1676 | arg.src = src; |
1677 | arg.dst = dst; |
1678 | + arg.iif = iif; |
1679 | arg.ecn = ecn; |
1680 | |
1681 | local_bh_disable(); |
1682 | @@ -603,7 +604,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user) |
1683 | fhdr = (struct frag_hdr *)skb_transport_header(clone); |
1684 | |
1685 | fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr, |
1686 | - ip6_frag_ecn(hdr)); |
1687 | + skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr)); |
1688 | if (fq == NULL) { |
1689 | pr_debug("Can't find and can't create new queue\n"); |
1690 | goto ret_orig; |
1691 | diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c |
1692 | index 8072bd4139b7..2c639aee12cb 100644 |
1693 | --- a/net/ipv6/raw.c |
1694 | +++ b/net/ipv6/raw.c |
1695 | @@ -731,6 +731,7 @@ static int raw6_getfrag(void *from, char *to, int offset, int len, int odd, |
1696 | |
1697 | static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) |
1698 | { |
1699 | + struct ipv6_txoptions *opt_to_free = NULL; |
1700 | struct ipv6_txoptions opt_space; |
1701 | DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); |
1702 | struct in6_addr *daddr, *final_p, final; |
1703 | @@ -837,8 +838,10 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) |
1704 | if (!(opt->opt_nflen|opt->opt_flen)) |
1705 | opt = NULL; |
1706 | } |
1707 | - if (!opt) |
1708 | - opt = np->opt; |
1709 | + if (!opt) { |
1710 | + opt = txopt_get(np); |
1711 | + opt_to_free = opt; |
1712 | + } |
1713 | if (flowlabel) |
1714 | opt = fl6_merge_options(&opt_space, flowlabel, opt); |
1715 | opt = ipv6_fixup_options(&opt_space, opt); |
1716 | @@ -901,6 +904,7 @@ done: |
1717 | dst_release(dst); |
1718 | out: |
1719 | fl6_sock_release(flowlabel); |
1720 | + txopt_put(opt_to_free); |
1721 | return err < 0 ? err : len; |
1722 | do_confirm: |
1723 | dst_confirm(dst); |
1724 | diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c |
1725 | index 8ffa2c8cce77..9d1f6a28b284 100644 |
1726 | --- a/net/ipv6/reassembly.c |
1727 | +++ b/net/ipv6/reassembly.c |
1728 | @@ -108,7 +108,10 @@ bool ip6_frag_match(const struct inet_frag_queue *q, const void *a) |
1729 | return fq->id == arg->id && |
1730 | fq->user == arg->user && |
1731 | ipv6_addr_equal(&fq->saddr, arg->src) && |
1732 | - ipv6_addr_equal(&fq->daddr, arg->dst); |
1733 | + ipv6_addr_equal(&fq->daddr, arg->dst) && |
1734 | + (arg->iif == fq->iif || |
1735 | + !(ipv6_addr_type(arg->dst) & (IPV6_ADDR_MULTICAST | |
1736 | + IPV6_ADDR_LINKLOCAL))); |
1737 | } |
1738 | EXPORT_SYMBOL(ip6_frag_match); |
1739 | |
1740 | @@ -180,7 +183,7 @@ static void ip6_frag_expire(unsigned long data) |
1741 | |
1742 | static struct frag_queue * |
1743 | fq_find(struct net *net, __be32 id, const struct in6_addr *src, |
1744 | - const struct in6_addr *dst, u8 ecn) |
1745 | + const struct in6_addr *dst, int iif, u8 ecn) |
1746 | { |
1747 | struct inet_frag_queue *q; |
1748 | struct ip6_create_arg arg; |
1749 | @@ -190,6 +193,7 @@ fq_find(struct net *net, __be32 id, const struct in6_addr *src, |
1750 | arg.user = IP6_DEFRAG_LOCAL_DELIVER; |
1751 | arg.src = src; |
1752 | arg.dst = dst; |
1753 | + arg.iif = iif; |
1754 | arg.ecn = ecn; |
1755 | |
1756 | hash = inet6_hash_frag(id, src, dst); |
1757 | @@ -551,7 +555,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb) |
1758 | } |
1759 | |
1760 | fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr, |
1761 | - ip6_frag_ecn(hdr)); |
1762 | + skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr)); |
1763 | if (fq) { |
1764 | int ret; |
1765 | |
1766 | diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c |
1767 | index 21bc2eb53c57..a4cf004f44d0 100644 |
1768 | --- a/net/ipv6/syncookies.c |
1769 | +++ b/net/ipv6/syncookies.c |
1770 | @@ -242,7 +242,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) |
1771 | memset(&fl6, 0, sizeof(fl6)); |
1772 | fl6.flowi6_proto = IPPROTO_TCP; |
1773 | fl6.daddr = ireq->ir_v6_rmt_addr; |
1774 | - final_p = fl6_update_dst(&fl6, np->opt, &final); |
1775 | + final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final); |
1776 | fl6.saddr = ireq->ir_v6_loc_addr; |
1777 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
1778 | fl6.flowi6_mark = ireq->ir_mark; |
1779 | diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c |
1780 | index e541d68dba8b..cfb27f56c62f 100644 |
1781 | --- a/net/ipv6/tcp_ipv6.c |
1782 | +++ b/net/ipv6/tcp_ipv6.c |
1783 | @@ -121,6 +121,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, |
1784 | struct ipv6_pinfo *np = inet6_sk(sk); |
1785 | struct tcp_sock *tp = tcp_sk(sk); |
1786 | struct in6_addr *saddr = NULL, *final_p, final; |
1787 | + struct ipv6_txoptions *opt; |
1788 | struct rt6_info *rt; |
1789 | struct flowi6 fl6; |
1790 | struct dst_entry *dst; |
1791 | @@ -237,7 +238,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, |
1792 | fl6.fl6_dport = usin->sin6_port; |
1793 | fl6.fl6_sport = inet->inet_sport; |
1794 | |
1795 | - final_p = fl6_update_dst(&fl6, np->opt, &final); |
1796 | + opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk)); |
1797 | + final_p = fl6_update_dst(&fl6, opt, &final); |
1798 | |
1799 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
1800 | |
1801 | @@ -266,9 +268,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, |
1802 | tcp_fetch_timewait_stamp(sk, dst); |
1803 | |
1804 | icsk->icsk_ext_hdr_len = 0; |
1805 | - if (np->opt) |
1806 | - icsk->icsk_ext_hdr_len = (np->opt->opt_flen + |
1807 | - np->opt->opt_nflen); |
1808 | + if (opt) |
1809 | + icsk->icsk_ext_hdr_len = opt->opt_flen + |
1810 | + opt->opt_nflen; |
1811 | |
1812 | tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); |
1813 | |
1814 | @@ -464,7 +466,8 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst, |
1815 | fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts)); |
1816 | |
1817 | skb_set_queue_mapping(skb, queue_mapping); |
1818 | - err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass); |
1819 | + err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt), |
1820 | + np->tclass); |
1821 | err = net_xmit_eval(err); |
1822 | } |
1823 | |
1824 | @@ -994,6 +997,7 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, |
1825 | struct inet_request_sock *ireq; |
1826 | struct ipv6_pinfo *newnp, *np = inet6_sk(sk); |
1827 | struct tcp6_sock *newtcp6sk; |
1828 | + struct ipv6_txoptions *opt; |
1829 | struct inet_sock *newinet; |
1830 | struct tcp_sock *newtp; |
1831 | struct sock *newsk; |
1832 | @@ -1129,13 +1133,15 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, |
1833 | but we make one more one thing there: reattach optmem |
1834 | to newsk. |
1835 | */ |
1836 | - if (np->opt) |
1837 | - newnp->opt = ipv6_dup_options(newsk, np->opt); |
1838 | - |
1839 | + opt = rcu_dereference(np->opt); |
1840 | + if (opt) { |
1841 | + opt = ipv6_dup_options(newsk, opt); |
1842 | + RCU_INIT_POINTER(newnp->opt, opt); |
1843 | + } |
1844 | inet_csk(newsk)->icsk_ext_hdr_len = 0; |
1845 | - if (newnp->opt) |
1846 | - inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen + |
1847 | - newnp->opt->opt_flen); |
1848 | + if (opt) |
1849 | + inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen + |
1850 | + opt->opt_flen; |
1851 | |
1852 | tcp_ca_openreq_child(newsk, dst); |
1853 | |
1854 | diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c |
1855 | index e51fc3eee6db..7333f3575fc5 100644 |
1856 | --- a/net/ipv6/udp.c |
1857 | +++ b/net/ipv6/udp.c |
1858 | @@ -1107,6 +1107,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) |
1859 | DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); |
1860 | struct in6_addr *daddr, *final_p, final; |
1861 | struct ipv6_txoptions *opt = NULL; |
1862 | + struct ipv6_txoptions *opt_to_free = NULL; |
1863 | struct ip6_flowlabel *flowlabel = NULL; |
1864 | struct flowi6 fl6; |
1865 | struct dst_entry *dst; |
1866 | @@ -1260,8 +1261,10 @@ do_udp_sendmsg: |
1867 | opt = NULL; |
1868 | connected = 0; |
1869 | } |
1870 | - if (!opt) |
1871 | - opt = np->opt; |
1872 | + if (!opt) { |
1873 | + opt = txopt_get(np); |
1874 | + opt_to_free = opt; |
1875 | + } |
1876 | if (flowlabel) |
1877 | opt = fl6_merge_options(&opt_space, flowlabel, opt); |
1878 | opt = ipv6_fixup_options(&opt_space, opt); |
1879 | @@ -1370,6 +1373,7 @@ release_dst: |
1880 | out: |
1881 | dst_release(dst); |
1882 | fl6_sock_release(flowlabel); |
1883 | + txopt_put(opt_to_free); |
1884 | if (!err) |
1885 | return len; |
1886 | /* |
1887 | diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c |
1888 | index d1ded3777815..0ce9da948ad7 100644 |
1889 | --- a/net/l2tp/l2tp_ip6.c |
1890 | +++ b/net/l2tp/l2tp_ip6.c |
1891 | @@ -486,6 +486,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) |
1892 | DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name); |
1893 | struct in6_addr *daddr, *final_p, final; |
1894 | struct ipv6_pinfo *np = inet6_sk(sk); |
1895 | + struct ipv6_txoptions *opt_to_free = NULL; |
1896 | struct ipv6_txoptions *opt = NULL; |
1897 | struct ip6_flowlabel *flowlabel = NULL; |
1898 | struct dst_entry *dst = NULL; |
1899 | @@ -575,8 +576,10 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) |
1900 | opt = NULL; |
1901 | } |
1902 | |
1903 | - if (opt == NULL) |
1904 | - opt = np->opt; |
1905 | + if (!opt) { |
1906 | + opt = txopt_get(np); |
1907 | + opt_to_free = opt; |
1908 | + } |
1909 | if (flowlabel) |
1910 | opt = fl6_merge_options(&opt_space, flowlabel, opt); |
1911 | opt = ipv6_fixup_options(&opt_space, opt); |
1912 | @@ -631,6 +634,7 @@ done: |
1913 | dst_release(dst); |
1914 | out: |
1915 | fl6_sock_release(flowlabel); |
1916 | + txopt_put(opt_to_free); |
1917 | |
1918 | return err < 0 ? err : len; |
1919 | |
1920 | diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c |
1921 | index 686e60187401..ebc39e66d704 100644 |
1922 | --- a/net/packet/af_packet.c |
1923 | +++ b/net/packet/af_packet.c |
1924 | @@ -1524,6 +1524,20 @@ static void fanout_release(struct sock *sk) |
1925 | mutex_unlock(&fanout_mutex); |
1926 | } |
1927 | |
1928 | +static bool packet_extra_vlan_len_allowed(const struct net_device *dev, |
1929 | + struct sk_buff *skb) |
1930 | +{ |
1931 | + /* Earlier code assumed this would be a VLAN pkt, double-check |
1932 | + * this now that we have the actual packet in hand. We can only |
1933 | + * do this check on Ethernet devices. |
1934 | + */ |
1935 | + if (unlikely(dev->type != ARPHRD_ETHER)) |
1936 | + return false; |
1937 | + |
1938 | + skb_reset_mac_header(skb); |
1939 | + return likely(eth_hdr(skb)->h_proto == htons(ETH_P_8021Q)); |
1940 | +} |
1941 | + |
1942 | static const struct proto_ops packet_ops; |
1943 | |
1944 | static const struct proto_ops packet_ops_spkt; |
1945 | @@ -1685,18 +1699,10 @@ retry: |
1946 | goto retry; |
1947 | } |
1948 | |
1949 | - if (len > (dev->mtu + dev->hard_header_len + extra_len)) { |
1950 | - /* Earlier code assumed this would be a VLAN pkt, |
1951 | - * double-check this now that we have the actual |
1952 | - * packet in hand. |
1953 | - */ |
1954 | - struct ethhdr *ehdr; |
1955 | - skb_reset_mac_header(skb); |
1956 | - ehdr = eth_hdr(skb); |
1957 | - if (ehdr->h_proto != htons(ETH_P_8021Q)) { |
1958 | - err = -EMSGSIZE; |
1959 | - goto out_unlock; |
1960 | - } |
1961 | + if (len > (dev->mtu + dev->hard_header_len + extra_len) && |
1962 | + !packet_extra_vlan_len_allowed(dev, skb)) { |
1963 | + err = -EMSGSIZE; |
1964 | + goto out_unlock; |
1965 | } |
1966 | |
1967 | skb->protocol = proto; |
1968 | @@ -2115,6 +2121,15 @@ static bool ll_header_truncated(const struct net_device *dev, int len) |
1969 | return false; |
1970 | } |
1971 | |
1972 | +static void tpacket_set_protocol(const struct net_device *dev, |
1973 | + struct sk_buff *skb) |
1974 | +{ |
1975 | + if (dev->type == ARPHRD_ETHER) { |
1976 | + skb_reset_mac_header(skb); |
1977 | + skb->protocol = eth_hdr(skb)->h_proto; |
1978 | + } |
1979 | +} |
1980 | + |
1981 | static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, |
1982 | void *frame, struct net_device *dev, int size_max, |
1983 | __be16 proto, unsigned char *addr, int hlen) |
1984 | @@ -2151,8 +2166,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, |
1985 | skb_reserve(skb, hlen); |
1986 | skb_reset_network_header(skb); |
1987 | |
1988 | - if (!packet_use_direct_xmit(po)) |
1989 | - skb_probe_transport_header(skb, 0); |
1990 | if (unlikely(po->tp_tx_has_off)) { |
1991 | int off_min, off_max, off; |
1992 | off_min = po->tp_hdrlen - sizeof(struct sockaddr_ll); |
1993 | @@ -2198,6 +2211,8 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, |
1994 | dev->hard_header_len); |
1995 | if (unlikely(err)) |
1996 | return err; |
1997 | + if (!skb->protocol) |
1998 | + tpacket_set_protocol(dev, skb); |
1999 | |
2000 | data += dev->hard_header_len; |
2001 | to_write -= dev->hard_header_len; |
2002 | @@ -2232,6 +2247,8 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, |
2003 | len = ((to_write > len_max) ? len_max : to_write); |
2004 | } |
2005 | |
2006 | + skb_probe_transport_header(skb, 0); |
2007 | + |
2008 | return tp_len; |
2009 | } |
2010 | |
2011 | @@ -2276,12 +2293,13 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) |
2012 | if (unlikely(!(dev->flags & IFF_UP))) |
2013 | goto out_put; |
2014 | |
2015 | - reserve = dev->hard_header_len + VLAN_HLEN; |
2016 | + if (po->sk.sk_socket->type == SOCK_RAW) |
2017 | + reserve = dev->hard_header_len; |
2018 | size_max = po->tx_ring.frame_size |
2019 | - (po->tp_hdrlen - sizeof(struct sockaddr_ll)); |
2020 | |
2021 | - if (size_max > dev->mtu + reserve) |
2022 | - size_max = dev->mtu + reserve; |
2023 | + if (size_max > dev->mtu + reserve + VLAN_HLEN) |
2024 | + size_max = dev->mtu + reserve + VLAN_HLEN; |
2025 | |
2026 | do { |
2027 | ph = packet_current_frame(po, &po->tx_ring, |
2028 | @@ -2308,18 +2326,10 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) |
2029 | tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto, |
2030 | addr, hlen); |
2031 | if (likely(tp_len >= 0) && |
2032 | - tp_len > dev->mtu + dev->hard_header_len) { |
2033 | - struct ethhdr *ehdr; |
2034 | - /* Earlier code assumed this would be a VLAN pkt, |
2035 | - * double-check this now that we have the actual |
2036 | - * packet in hand. |
2037 | - */ |
2038 | + tp_len > dev->mtu + reserve && |
2039 | + !packet_extra_vlan_len_allowed(dev, skb)) |
2040 | + tp_len = -EMSGSIZE; |
2041 | |
2042 | - skb_reset_mac_header(skb); |
2043 | - ehdr = eth_hdr(skb); |
2044 | - if (ehdr->h_proto != htons(ETH_P_8021Q)) |
2045 | - tp_len = -EMSGSIZE; |
2046 | - } |
2047 | if (unlikely(tp_len < 0)) { |
2048 | if (po->tp_loss) { |
2049 | __packet_set_status(po, ph, |
2050 | @@ -2540,18 +2550,10 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) |
2051 | |
2052 | sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); |
2053 | |
2054 | - if (!gso_type && (len > dev->mtu + reserve + extra_len)) { |
2055 | - /* Earlier code assumed this would be a VLAN pkt, |
2056 | - * double-check this now that we have the actual |
2057 | - * packet in hand. |
2058 | - */ |
2059 | - struct ethhdr *ehdr; |
2060 | - skb_reset_mac_header(skb); |
2061 | - ehdr = eth_hdr(skb); |
2062 | - if (ehdr->h_proto != htons(ETH_P_8021Q)) { |
2063 | - err = -EMSGSIZE; |
2064 | - goto out_free; |
2065 | - } |
2066 | + if (!gso_type && (len > dev->mtu + reserve + extra_len) && |
2067 | + !packet_extra_vlan_len_allowed(dev, skb)) { |
2068 | + err = -EMSGSIZE; |
2069 | + goto out_free; |
2070 | } |
2071 | |
2072 | skb->protocol = proto; |
2073 | @@ -2582,8 +2584,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) |
2074 | len += vnet_hdr_len; |
2075 | } |
2076 | |
2077 | - if (!packet_use_direct_xmit(po)) |
2078 | - skb_probe_transport_header(skb, reserve); |
2079 | + skb_probe_transport_header(skb, reserve); |
2080 | + |
2081 | if (unlikely(extra_len == 4)) |
2082 | skb->no_fcs = 1; |
2083 | |
2084 | diff --git a/net/rds/connection.c b/net/rds/connection.c |
2085 | index 9d66705f9d41..da6da57e5f36 100644 |
2086 | --- a/net/rds/connection.c |
2087 | +++ b/net/rds/connection.c |
2088 | @@ -187,12 +187,6 @@ new_conn: |
2089 | } |
2090 | } |
2091 | |
2092 | - if (trans == NULL) { |
2093 | - kmem_cache_free(rds_conn_slab, conn); |
2094 | - conn = ERR_PTR(-ENODEV); |
2095 | - goto out; |
2096 | - } |
2097 | - |
2098 | conn->c_trans = trans; |
2099 | |
2100 | ret = trans->conn_alloc(conn, gfp); |
2101 | diff --git a/net/rds/send.c b/net/rds/send.c |
2102 | index e9430f537f9c..7b30c0f3180d 100644 |
2103 | --- a/net/rds/send.c |
2104 | +++ b/net/rds/send.c |
2105 | @@ -986,11 +986,13 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) |
2106 | release_sock(sk); |
2107 | } |
2108 | |
2109 | - /* racing with another thread binding seems ok here */ |
2110 | + lock_sock(sk); |
2111 | if (daddr == 0 || rs->rs_bound_addr == 0) { |
2112 | + release_sock(sk); |
2113 | ret = -ENOTCONN; /* XXX not a great errno */ |
2114 | goto out; |
2115 | } |
2116 | + release_sock(sk); |
2117 | |
2118 | /* size of rm including all sgs */ |
2119 | ret = rds_rm_size(msg, payload_len); |
2120 | diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c |
2121 | index 1e1c89e51a11..d4b6f3682c14 100644 |
2122 | --- a/net/sched/sch_api.c |
2123 | +++ b/net/sched/sch_api.c |
2124 | @@ -253,7 +253,8 @@ int qdisc_set_default(const char *name) |
2125 | } |
2126 | |
2127 | /* We know handle. Find qdisc among all qdisc's attached to device |
2128 | - (root qdisc, all its children, children of children etc.) |
2129 | + * (root qdisc, all its children, children of children etc.) |
2130 | + * Note: caller either uses rtnl or rcu_read_lock() |
2131 | */ |
2132 | |
2133 | static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle) |
2134 | @@ -264,7 +265,7 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle) |
2135 | root->handle == handle) |
2136 | return root; |
2137 | |
2138 | - list_for_each_entry(q, &root->list, list) { |
2139 | + list_for_each_entry_rcu(q, &root->list, list) { |
2140 | if (q->handle == handle) |
2141 | return q; |
2142 | } |
2143 | @@ -277,15 +278,18 @@ void qdisc_list_add(struct Qdisc *q) |
2144 | struct Qdisc *root = qdisc_dev(q)->qdisc; |
2145 | |
2146 | WARN_ON_ONCE(root == &noop_qdisc); |
2147 | - list_add_tail(&q->list, &root->list); |
2148 | + ASSERT_RTNL(); |
2149 | + list_add_tail_rcu(&q->list, &root->list); |
2150 | } |
2151 | } |
2152 | EXPORT_SYMBOL(qdisc_list_add); |
2153 | |
2154 | void qdisc_list_del(struct Qdisc *q) |
2155 | { |
2156 | - if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) |
2157 | - list_del(&q->list); |
2158 | + if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) { |
2159 | + ASSERT_RTNL(); |
2160 | + list_del_rcu(&q->list); |
2161 | + } |
2162 | } |
2163 | EXPORT_SYMBOL(qdisc_list_del); |
2164 | |
2165 | @@ -750,14 +754,18 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n) |
2166 | if (n == 0) |
2167 | return; |
2168 | drops = max_t(int, n, 0); |
2169 | + rcu_read_lock(); |
2170 | while ((parentid = sch->parent)) { |
2171 | if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS)) |
2172 | - return; |
2173 | + break; |
2174 | |
2175 | + if (sch->flags & TCQ_F_NOPARENT) |
2176 | + break; |
2177 | + /* TODO: perform the search on a per txq basis */ |
2178 | sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid)); |
2179 | if (sch == NULL) { |
2180 | - WARN_ON(parentid != TC_H_ROOT); |
2181 | - return; |
2182 | + WARN_ON_ONCE(parentid != TC_H_ROOT); |
2183 | + break; |
2184 | } |
2185 | cops = sch->ops->cl_ops; |
2186 | if (cops->qlen_notify) { |
2187 | @@ -768,6 +776,7 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n) |
2188 | sch->q.qlen -= n; |
2189 | __qdisc_qstats_drop(sch, drops); |
2190 | } |
2191 | + rcu_read_unlock(); |
2192 | } |
2193 | EXPORT_SYMBOL(qdisc_tree_decrease_qlen); |
2194 | |
2195 | @@ -941,7 +950,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue, |
2196 | } |
2197 | lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock); |
2198 | if (!netif_is_multiqueue(dev)) |
2199 | - sch->flags |= TCQ_F_ONETXQUEUE; |
2200 | + sch->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; |
2201 | } |
2202 | |
2203 | sch->handle = handle; |
2204 | diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c |
2205 | index 6efca30894aa..b453270be3fd 100644 |
2206 | --- a/net/sched/sch_generic.c |
2207 | +++ b/net/sched/sch_generic.c |
2208 | @@ -743,7 +743,7 @@ static void attach_one_default_qdisc(struct net_device *dev, |
2209 | return; |
2210 | } |
2211 | if (!netif_is_multiqueue(dev)) |
2212 | - qdisc->flags |= TCQ_F_ONETXQUEUE; |
2213 | + qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; |
2214 | } |
2215 | dev_queue->qdisc_sleeping = qdisc; |
2216 | } |
2217 | diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c |
2218 | index f3cbaecd283a..3e82f047caaf 100644 |
2219 | --- a/net/sched/sch_mq.c |
2220 | +++ b/net/sched/sch_mq.c |
2221 | @@ -63,7 +63,7 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt) |
2222 | if (qdisc == NULL) |
2223 | goto err; |
2224 | priv->qdiscs[ntx] = qdisc; |
2225 | - qdisc->flags |= TCQ_F_ONETXQUEUE; |
2226 | + qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; |
2227 | } |
2228 | |
2229 | sch->flags |= TCQ_F_MQROOT; |
2230 | @@ -156,7 +156,7 @@ static int mq_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new, |
2231 | |
2232 | *old = dev_graft_qdisc(dev_queue, new); |
2233 | if (new) |
2234 | - new->flags |= TCQ_F_ONETXQUEUE; |
2235 | + new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; |
2236 | if (dev->flags & IFF_UP) |
2237 | dev_activate(dev); |
2238 | return 0; |
2239 | diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c |
2240 | index 3811a745452c..ad70ecf57ce7 100644 |
2241 | --- a/net/sched/sch_mqprio.c |
2242 | +++ b/net/sched/sch_mqprio.c |
2243 | @@ -132,7 +132,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt) |
2244 | goto err; |
2245 | } |
2246 | priv->qdiscs[i] = qdisc; |
2247 | - qdisc->flags |= TCQ_F_ONETXQUEUE; |
2248 | + qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; |
2249 | } |
2250 | |
2251 | /* If the mqprio options indicate that hardware should own |
2252 | @@ -209,7 +209,7 @@ static int mqprio_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new, |
2253 | *old = dev_graft_qdisc(dev_queue, new); |
2254 | |
2255 | if (new) |
2256 | - new->flags |= TCQ_F_ONETXQUEUE; |
2257 | + new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT; |
2258 | |
2259 | if (dev->flags & IFF_UP) |
2260 | dev_activate(dev); |
2261 | diff --git a/net/sctp/auth.c b/net/sctp/auth.c |
2262 | index 4f15b7d730e1..1543e39f47c3 100644 |
2263 | --- a/net/sctp/auth.c |
2264 | +++ b/net/sctp/auth.c |
2265 | @@ -809,8 +809,8 @@ int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep, |
2266 | if (!has_sha1) |
2267 | return -EINVAL; |
2268 | |
2269 | - memcpy(ep->auth_hmacs_list->hmac_ids, &hmacs->shmac_idents[0], |
2270 | - hmacs->shmac_num_idents * sizeof(__u16)); |
2271 | + for (i = 0; i < hmacs->shmac_num_idents; i++) |
2272 | + ep->auth_hmacs_list->hmac_ids[i] = htons(hmacs->shmac_idents[i]); |
2273 | ep->auth_hmacs_list->param_hdr.length = htons(sizeof(sctp_paramhdr_t) + |
2274 | hmacs->shmac_num_idents * sizeof(__u16)); |
2275 | return 0; |
2276 | diff --git a/net/sctp/socket.c b/net/sctp/socket.c |
2277 | index 5f6c4e61325b..66d796075050 100644 |
2278 | --- a/net/sctp/socket.c |
2279 | +++ b/net/sctp/socket.c |
2280 | @@ -7387,6 +7387,13 @@ struct proto sctp_prot = { |
2281 | |
2282 | #if IS_ENABLED(CONFIG_IPV6) |
2283 | |
2284 | +#include <net/transp_v6.h> |
2285 | +static void sctp_v6_destroy_sock(struct sock *sk) |
2286 | +{ |
2287 | + sctp_destroy_sock(sk); |
2288 | + inet6_destroy_sock(sk); |
2289 | +} |
2290 | + |
2291 | struct proto sctpv6_prot = { |
2292 | .name = "SCTPv6", |
2293 | .owner = THIS_MODULE, |
2294 | @@ -7396,7 +7403,7 @@ struct proto sctpv6_prot = { |
2295 | .accept = sctp_accept, |
2296 | .ioctl = sctp_ioctl, |
2297 | .init = sctp_init_sock, |
2298 | - .destroy = sctp_destroy_sock, |
2299 | + .destroy = sctp_v6_destroy_sock, |
2300 | .shutdown = sctp_shutdown, |
2301 | .setsockopt = sctp_setsockopt, |
2302 | .getsockopt = sctp_getsockopt, |
2303 | diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c |
2304 | index 76e66695621c..1975fd8d1c10 100644 |
2305 | --- a/net/unix/af_unix.c |
2306 | +++ b/net/unix/af_unix.c |
2307 | @@ -316,6 +316,118 @@ found: |
2308 | return s; |
2309 | } |
2310 | |
2311 | +/* Support code for asymmetrically connected dgram sockets |
2312 | + * |
2313 | + * If a datagram socket is connected to a socket not itself connected |
2314 | + * to the first socket (eg, /dev/log), clients may only enqueue more |
2315 | + * messages if the present receive queue of the server socket is not |
2316 | + * "too large". This means there's a second writeability condition |
2317 | + * poll and sendmsg need to test. The dgram recv code will do a wake |
2318 | + * up on the peer_wait wait queue of a socket upon reception of a |
2319 | + * datagram which needs to be propagated to sleeping would-be writers |
2320 | + * since these might not have sent anything so far. This can't be |
2321 | + * accomplished via poll_wait because the lifetime of the server |
2322 | + * socket might be less than that of its clients if these break their |
2323 | + * association with it or if the server socket is closed while clients |
2324 | + * are still connected to it and there's no way to inform "a polling |
2325 | + * implementation" that it should let go of a certain wait queue |
2326 | + * |
2327 | + * In order to propagate a wake up, a wait_queue_t of the client |
2328 | + * socket is enqueued on the peer_wait queue of the server socket |
2329 | + * whose wake function does a wake_up on the ordinary client socket |
2330 | + * wait queue. This connection is established whenever a write (or |
2331 | + * poll for write) hit the flow control condition and broken when the |
2332 | + * association to the server socket is dissolved or after a wake up |
2333 | + * was relayed. |
2334 | + */ |
2335 | + |
2336 | +static int unix_dgram_peer_wake_relay(wait_queue_t *q, unsigned mode, int flags, |
2337 | + void *key) |
2338 | +{ |
2339 | + struct unix_sock *u; |
2340 | + wait_queue_head_t *u_sleep; |
2341 | + |
2342 | + u = container_of(q, struct unix_sock, peer_wake); |
2343 | + |
2344 | + __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait, |
2345 | + q); |
2346 | + u->peer_wake.private = NULL; |
2347 | + |
2348 | + /* relaying can only happen while the wq still exists */ |
2349 | + u_sleep = sk_sleep(&u->sk); |
2350 | + if (u_sleep) |
2351 | + wake_up_interruptible_poll(u_sleep, key); |
2352 | + |
2353 | + return 0; |
2354 | +} |
2355 | + |
2356 | +static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other) |
2357 | +{ |
2358 | + struct unix_sock *u, *u_other; |
2359 | + int rc; |
2360 | + |
2361 | + u = unix_sk(sk); |
2362 | + u_other = unix_sk(other); |
2363 | + rc = 0; |
2364 | + spin_lock(&u_other->peer_wait.lock); |
2365 | + |
2366 | + if (!u->peer_wake.private) { |
2367 | + u->peer_wake.private = other; |
2368 | + __add_wait_queue(&u_other->peer_wait, &u->peer_wake); |
2369 | + |
2370 | + rc = 1; |
2371 | + } |
2372 | + |
2373 | + spin_unlock(&u_other->peer_wait.lock); |
2374 | + return rc; |
2375 | +} |
2376 | + |
2377 | +static void unix_dgram_peer_wake_disconnect(struct sock *sk, |
2378 | + struct sock *other) |
2379 | +{ |
2380 | + struct unix_sock *u, *u_other; |
2381 | + |
2382 | + u = unix_sk(sk); |
2383 | + u_other = unix_sk(other); |
2384 | + spin_lock(&u_other->peer_wait.lock); |
2385 | + |
2386 | + if (u->peer_wake.private == other) { |
2387 | + __remove_wait_queue(&u_other->peer_wait, &u->peer_wake); |
2388 | + u->peer_wake.private = NULL; |
2389 | + } |
2390 | + |
2391 | + spin_unlock(&u_other->peer_wait.lock); |
2392 | +} |
2393 | + |
2394 | +static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk, |
2395 | + struct sock *other) |
2396 | +{ |
2397 | + unix_dgram_peer_wake_disconnect(sk, other); |
2398 | + wake_up_interruptible_poll(sk_sleep(sk), |
2399 | + POLLOUT | |
2400 | + POLLWRNORM | |
2401 | + POLLWRBAND); |
2402 | +} |
2403 | + |
2404 | +/* preconditions: |
2405 | + * - unix_peer(sk) == other |
2406 | + * - association is stable |
2407 | + */ |
2408 | +static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other) |
2409 | +{ |
2410 | + int connected; |
2411 | + |
2412 | + connected = unix_dgram_peer_wake_connect(sk, other); |
2413 | + |
2414 | + if (unix_recvq_full(other)) |
2415 | + return 1; |
2416 | + |
2417 | + if (connected) |
2418 | + unix_dgram_peer_wake_disconnect(sk, other); |
2419 | + |
2420 | + return 0; |
2421 | +} |
2422 | + |
2423 | static inline int unix_writable(struct sock *sk) |
2424 | { |
2425 | return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf; |
2426 | @@ -420,6 +532,8 @@ static void unix_release_sock(struct sock *sk, int embrion) |
2427 | skpair->sk_state_change(skpair); |
2428 | sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP); |
2429 | } |
2430 | + |
2431 | + unix_dgram_peer_wake_disconnect(sk, skpair); |
2432 | sock_put(skpair); /* It may now die */ |
2433 | unix_peer(sk) = NULL; |
2434 | } |
2435 | @@ -648,6 +762,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock) |
2436 | INIT_LIST_HEAD(&u->link); |
2437 | mutex_init(&u->readlock); /* single task reading lock */ |
2438 | init_waitqueue_head(&u->peer_wait); |
2439 | + init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay); |
2440 | unix_insert_socket(unix_sockets_unbound(sk), sk); |
2441 | out: |
2442 | if (sk == NULL) |
2443 | @@ -1015,6 +1130,8 @@ restart: |
2444 | if (unix_peer(sk)) { |
2445 | struct sock *old_peer = unix_peer(sk); |
2446 | unix_peer(sk) = other; |
2447 | + unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer); |
2448 | + |
2449 | unix_state_double_unlock(sk, other); |
2450 | |
2451 | if (other != old_peer) |
2452 | @@ -1453,6 +1570,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, |
2453 | struct scm_cookie scm; |
2454 | int max_level; |
2455 | int data_len = 0; |
2456 | + int sk_locked; |
2457 | |
2458 | wait_for_unix_gc(); |
2459 | err = scm_send(sock, msg, &scm, false); |
2460 | @@ -1532,12 +1650,14 @@ restart: |
2461 | goto out_free; |
2462 | } |
2463 | |
2464 | + sk_locked = 0; |
2465 | unix_state_lock(other); |
2466 | +restart_locked: |
2467 | err = -EPERM; |
2468 | if (!unix_may_send(sk, other)) |
2469 | goto out_unlock; |
2470 | |
2471 | - if (sock_flag(other, SOCK_DEAD)) { |
2472 | + if (unlikely(sock_flag(other, SOCK_DEAD))) { |
2473 | /* |
2474 | * Check with 1003.1g - what should |
2475 | * datagram error |
2476 | @@ -1545,10 +1665,14 @@ restart: |
2477 | unix_state_unlock(other); |
2478 | sock_put(other); |
2479 | |
2480 | + if (!sk_locked) |
2481 | + unix_state_lock(sk); |
2482 | + |
2483 | err = 0; |
2484 | - unix_state_lock(sk); |
2485 | if (unix_peer(sk) == other) { |
2486 | unix_peer(sk) = NULL; |
2487 | + unix_dgram_peer_wake_disconnect_wakeup(sk, other); |
2488 | + |
2489 | unix_state_unlock(sk); |
2490 | |
2491 | unix_dgram_disconnected(sk, other); |
2492 | @@ -1574,21 +1698,38 @@ restart: |
2493 | goto out_unlock; |
2494 | } |
2495 | |
2496 | - if (unix_peer(other) != sk && unix_recvq_full(other)) { |
2497 | - if (!timeo) { |
2498 | - err = -EAGAIN; |
2499 | - goto out_unlock; |
2500 | + if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) { |
2501 | + if (timeo) { |
2502 | + timeo = unix_wait_for_peer(other, timeo); |
2503 | + |
2504 | + err = sock_intr_errno(timeo); |
2505 | + if (signal_pending(current)) |
2506 | + goto out_free; |
2507 | + |
2508 | + goto restart; |
2509 | } |
2510 | |
2511 | - timeo = unix_wait_for_peer(other, timeo); |
2512 | + if (!sk_locked) { |
2513 | + unix_state_unlock(other); |
2514 | + unix_state_double_lock(sk, other); |
2515 | + } |
2516 | |
2517 | - err = sock_intr_errno(timeo); |
2518 | - if (signal_pending(current)) |
2519 | - goto out_free; |
2520 | + if (unix_peer(sk) != other || |
2521 | + unix_dgram_peer_wake_me(sk, other)) { |
2522 | + err = -EAGAIN; |
2523 | + sk_locked = 1; |
2524 | + goto out_unlock; |
2525 | + } |
2526 | |
2527 | - goto restart; |
2528 | + if (!sk_locked) { |
2529 | + sk_locked = 1; |
2530 | + goto restart_locked; |
2531 | + } |
2532 | } |
2533 | |
2534 | + if (unlikely(sk_locked)) |
2535 | + unix_state_unlock(sk); |
2536 | + |
2537 | if (sock_flag(other, SOCK_RCVTSTAMP)) |
2538 | __net_timestamp(skb); |
2539 | maybe_add_creds(skb, sock, other); |
2540 | @@ -1602,6 +1743,8 @@ restart: |
2541 | return len; |
2542 | |
2543 | out_unlock: |
2544 | + if (sk_locked) |
2545 | + unix_state_unlock(sk); |
2546 | unix_state_unlock(other); |
2547 | out_free: |
2548 | kfree_skb(skb); |
2549 | @@ -2245,14 +2388,16 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, |
2550 | return mask; |
2551 | |
2552 | writable = unix_writable(sk); |
2553 | - other = unix_peer_get(sk); |
2554 | - if (other) { |
2555 | - if (unix_peer(other) != sk) { |
2556 | - sock_poll_wait(file, &unix_sk(other)->peer_wait, wait); |
2557 | - if (unix_recvq_full(other)) |
2558 | - writable = 0; |
2559 | - } |
2560 | - sock_put(other); |
2561 | + if (writable) { |
2562 | + unix_state_lock(sk); |
2563 | + |
2564 | + other = unix_peer(sk); |
2565 | + if (other && unix_peer(other) != sk && |
2566 | + unix_recvq_full(other) && |
2567 | + unix_dgram_peer_wake_me(sk, other)) |
2568 | + writable = 0; |
2569 | + |
2570 | + unix_state_unlock(sk); |
2571 | } |
2572 | |
2573 | if (writable) |
2574 | diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c |
2575 | index 225b78b4ef12..d02eccd51f6e 100644 |
2576 | --- a/sound/pci/hda/patch_hdmi.c |
2577 | +++ b/sound/pci/hda/patch_hdmi.c |
2578 | @@ -48,8 +48,9 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); |
2579 | #define is_haswell(codec) ((codec)->core.vendor_id == 0x80862807) |
2580 | #define is_broadwell(codec) ((codec)->core.vendor_id == 0x80862808) |
2581 | #define is_skylake(codec) ((codec)->core.vendor_id == 0x80862809) |
2582 | +#define is_broxton(codec) ((codec)->core.vendor_id == 0x8086280a) |
2583 | #define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \ |
2584 | - || is_skylake(codec)) |
2585 | + || is_skylake(codec) || is_broxton(codec)) |
2586 | |
2587 | #define is_valleyview(codec) ((codec)->core.vendor_id == 0x80862882) |
2588 | #define is_cherryview(codec) ((codec)->core.vendor_id == 0x80862883) |
2589 | diff --git a/tools/net/Makefile b/tools/net/Makefile |
2590 | index ee577ea03ba5..ddf888010652 100644 |
2591 | --- a/tools/net/Makefile |
2592 | +++ b/tools/net/Makefile |
2593 | @@ -4,6 +4,9 @@ CC = gcc |
2594 | LEX = flex |
2595 | YACC = bison |
2596 | |
2597 | +CFLAGS += -Wall -O2 |
2598 | +CFLAGS += -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include |
2599 | + |
2600 | %.yacc.c: %.y |
2601 | $(YACC) -o $@ -d $< |
2602 | |
2603 | @@ -12,15 +15,13 @@ YACC = bison |
2604 | |
2605 | all : bpf_jit_disasm bpf_dbg bpf_asm |
2606 | |
2607 | -bpf_jit_disasm : CFLAGS = -Wall -O2 -DPACKAGE='bpf_jit_disasm' |
2608 | +bpf_jit_disasm : CFLAGS += -DPACKAGE='bpf_jit_disasm' |
2609 | bpf_jit_disasm : LDLIBS = -lopcodes -lbfd -ldl |
2610 | bpf_jit_disasm : bpf_jit_disasm.o |
2611 | |
2612 | -bpf_dbg : CFLAGS = -Wall -O2 |
2613 | bpf_dbg : LDLIBS = -lreadline |
2614 | bpf_dbg : bpf_dbg.o |
2615 | |
2616 | -bpf_asm : CFLAGS = -Wall -O2 -I. |
2617 | bpf_asm : LDLIBS = |
2618 | bpf_asm : bpf_asm.o bpf_exp.yacc.o bpf_exp.lex.o |
2619 | bpf_exp.lex.o : bpf_exp.yacc.c |