1 |
commit: 76c5fbb16e325e55281e54aa20ceca47629ecada |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon May 8 10:40:25 2017 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon May 8 10:40:25 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=76c5fbb1 |
7 |
|
8 |
Linux patch 4.4.67 |
9 |
|
10 |
0000_README | 4 + |
11 |
1066_linux-4.4.67.patch | 948 ++++++++++++++++++++++++++++++++++++++++++++++++ |
12 |
2 files changed, 952 insertions(+) |
13 |
|
14 |
diff --git a/0000_README b/0000_README |
15 |
index d08d290..dd02f06 100644 |
16 |
--- a/0000_README |
17 |
+++ b/0000_README |
18 |
@@ -307,6 +307,10 @@ Patch: 1065_linux-4.4.66.patch |
19 |
From: http://www.kernel.org |
20 |
Desc: Linux 4.4.66 |
21 |
|
22 |
+Patch: 1066_linux-4.4.67.patch |
23 |
+From: http://www.kernel.org |
24 |
+Desc: Linux 4.4.67 |
25 |
+ |
26 |
Patch: 1500_XATTR_USER_PREFIX.patch |
27 |
From: https://bugs.gentoo.org/show_bug.cgi?id=470644 |
28 |
Desc: Support for namespace user.pax.* on tmpfs. |
29 |
|
30 |
diff --git a/1066_linux-4.4.67.patch b/1066_linux-4.4.67.patch |
31 |
new file mode 100644 |
32 |
index 0000000..aafd894 |
33 |
--- /dev/null |
34 |
+++ b/1066_linux-4.4.67.patch |
35 |
@@ -0,0 +1,948 @@ |
36 |
+diff --git a/Makefile b/Makefile |
37 |
+index 1cd052823c03..c987902ae1ee 100644 |
38 |
+--- a/Makefile |
39 |
++++ b/Makefile |
40 |
+@@ -1,6 +1,6 @@ |
41 |
+ VERSION = 4 |
42 |
+ PATCHLEVEL = 4 |
43 |
+-SUBLEVEL = 66 |
44 |
++SUBLEVEL = 67 |
45 |
+ EXTRAVERSION = |
46 |
+ NAME = Blurry Fish Butt |
47 |
+ |
48 |
+diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c |
49 |
+index 9462d2752850..8bdc34dbaedf 100644 |
50 |
+--- a/drivers/block/drbd/drbd_bitmap.c |
51 |
++++ b/drivers/block/drbd/drbd_bitmap.c |
52 |
+@@ -479,8 +479,14 @@ void drbd_bm_cleanup(struct drbd_device *device) |
53 |
+ * this masks out the remaining bits. |
54 |
+ * Returns the number of bits cleared. |
55 |
+ */ |
56 |
++#ifndef BITS_PER_PAGE |
57 |
+ #define BITS_PER_PAGE (1UL << (PAGE_SHIFT + 3)) |
58 |
+ #define BITS_PER_PAGE_MASK (BITS_PER_PAGE - 1) |
59 |
++#else |
60 |
++# if BITS_PER_PAGE != (1UL << (PAGE_SHIFT + 3)) |
61 |
++# error "ambiguous BITS_PER_PAGE" |
62 |
++# endif |
63 |
++#endif |
64 |
+ #define BITS_PER_LONG_MASK (BITS_PER_LONG - 1) |
65 |
+ static int bm_clear_surplus(struct drbd_bitmap *b) |
66 |
+ { |
67 |
+diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c |
68 |
+index 3eff35c2d453..2684605fe67f 100644 |
69 |
+--- a/drivers/infiniband/hw/qib/qib_qp.c |
70 |
++++ b/drivers/infiniband/hw/qib/qib_qp.c |
71 |
+@@ -41,13 +41,13 @@ |
72 |
+ |
73 |
+ #include "qib.h" |
74 |
+ |
75 |
+-#define BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE) |
76 |
+-#define BITS_PER_PAGE_MASK (BITS_PER_PAGE-1) |
77 |
++#define RVT_BITS_PER_PAGE (PAGE_SIZE*BITS_PER_BYTE) |
78 |
++#define RVT_BITS_PER_PAGE_MASK (RVT_BITS_PER_PAGE-1) |
79 |
+ |
80 |
+ static inline unsigned mk_qpn(struct qib_qpn_table *qpt, |
81 |
+ struct qpn_map *map, unsigned off) |
82 |
+ { |
83 |
+- return (map - qpt->map) * BITS_PER_PAGE + off; |
84 |
++ return (map - qpt->map) * RVT_BITS_PER_PAGE + off; |
85 |
+ } |
86 |
+ |
87 |
+ static inline unsigned find_next_offset(struct qib_qpn_table *qpt, |
88 |
+@@ -59,7 +59,7 @@ static inline unsigned find_next_offset(struct qib_qpn_table *qpt, |
89 |
+ if (((off & qpt->mask) >> 1) >= n) |
90 |
+ off = (off | qpt->mask) + 2; |
91 |
+ } else |
92 |
+- off = find_next_zero_bit(map->page, BITS_PER_PAGE, off); |
93 |
++ off = find_next_zero_bit(map->page, RVT_BITS_PER_PAGE, off); |
94 |
+ return off; |
95 |
+ } |
96 |
+ |
97 |
+@@ -147,8 +147,8 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt, |
98 |
+ qpn = 2; |
99 |
+ if (qpt->mask && ((qpn & qpt->mask) >> 1) >= dd->n_krcv_queues) |
100 |
+ qpn = (qpn | qpt->mask) + 2; |
101 |
+- offset = qpn & BITS_PER_PAGE_MASK; |
102 |
+- map = &qpt->map[qpn / BITS_PER_PAGE]; |
103 |
++ offset = qpn & RVT_BITS_PER_PAGE_MASK; |
104 |
++ map = &qpt->map[qpn / RVT_BITS_PER_PAGE]; |
105 |
+ max_scan = qpt->nmaps - !offset; |
106 |
+ for (i = 0;;) { |
107 |
+ if (unlikely(!map->page)) { |
108 |
+@@ -173,7 +173,7 @@ static int alloc_qpn(struct qib_devdata *dd, struct qib_qpn_table *qpt, |
109 |
+ * We just need to be sure we don't loop |
110 |
+ * forever. |
111 |
+ */ |
112 |
+- } while (offset < BITS_PER_PAGE && qpn < QPN_MAX); |
113 |
++ } while (offset < RVT_BITS_PER_PAGE && qpn < QPN_MAX); |
114 |
+ /* |
115 |
+ * In order to keep the number of pages allocated to a |
116 |
+ * minimum, we scan the all existing pages before increasing |
117 |
+@@ -204,9 +204,9 @@ static void free_qpn(struct qib_qpn_table *qpt, u32 qpn) |
118 |
+ { |
119 |
+ struct qpn_map *map; |
120 |
+ |
121 |
+- map = qpt->map + qpn / BITS_PER_PAGE; |
122 |
++ map = qpt->map + qpn / RVT_BITS_PER_PAGE; |
123 |
+ if (map->page) |
124 |
+- clear_bit(qpn & BITS_PER_PAGE_MASK, map->page); |
125 |
++ clear_bit(qpn & RVT_BITS_PER_PAGE_MASK, map->page); |
126 |
+ } |
127 |
+ |
128 |
+ static inline unsigned qpn_hash(struct qib_ibdev *dev, u32 qpn) |
129 |
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c |
130 |
+index 80a439543259..e503279c34fc 100644 |
131 |
+--- a/drivers/md/dm-ioctl.c |
132 |
++++ b/drivers/md/dm-ioctl.c |
133 |
+@@ -1843,7 +1843,7 @@ static int ctl_ioctl(uint command, struct dm_ioctl __user *user) |
134 |
+ if (r) |
135 |
+ goto out; |
136 |
+ |
137 |
+- param->data_size = sizeof(*param); |
138 |
++ param->data_size = offsetof(struct dm_ioctl, data); |
139 |
+ r = fn(param, input_param_size); |
140 |
+ |
141 |
+ if (unlikely(param->flags & DM_BUFFER_FULL_FLAG) && |
142 |
+diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig |
143 |
+index 54479c481a7a..8a25adced79f 100644 |
144 |
+--- a/drivers/mtd/chips/Kconfig |
145 |
++++ b/drivers/mtd/chips/Kconfig |
146 |
+@@ -111,6 +111,7 @@ config MTD_MAP_BANK_WIDTH_16 |
147 |
+ |
148 |
+ config MTD_MAP_BANK_WIDTH_32 |
149 |
+ bool "Support 256-bit buswidth" if MTD_CFI_GEOMETRY |
150 |
++ select MTD_COMPLEX_MAPPINGS if HAS_IOMEM |
151 |
+ default n |
152 |
+ help |
153 |
+ If you wish to support CFI devices on a physical bus which is |
154 |
+diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c |
155 |
+index 49056c33be74..21e5b9ed1ead 100644 |
156 |
+--- a/drivers/net/ethernet/broadcom/tg3.c |
157 |
++++ b/drivers/net/ethernet/broadcom/tg3.c |
158 |
+@@ -12031,7 +12031,7 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, |
159 |
+ int ret; |
160 |
+ u32 offset, len, b_offset, odd_len; |
161 |
+ u8 *buf; |
162 |
+- __be32 start, end; |
163 |
++ __be32 start = 0, end; |
164 |
+ |
165 |
+ if (tg3_flag(tp, NO_NVRAM) || |
166 |
+ eeprom->magic != TG3_EEPROM_MAGIC) |
167 |
+diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c |
168 |
+index 2882bcac918a..0b096730c72a 100644 |
169 |
+--- a/drivers/scsi/cxlflash/main.c |
170 |
++++ b/drivers/scsi/cxlflash/main.c |
171 |
+@@ -996,6 +996,8 @@ static int wait_port_online(__be64 __iomem *fc_regs, u32 delay_us, u32 nretry) |
172 |
+ do { |
173 |
+ msleep(delay_us / 1000); |
174 |
+ status = readq_be(&fc_regs[FC_MTIP_STATUS / 8]); |
175 |
++ if (status == U64_MAX) |
176 |
++ nretry /= 2; |
177 |
+ } while ((status & FC_MTIP_STATUS_MASK) != FC_MTIP_STATUS_ONLINE && |
178 |
+ nretry--); |
179 |
+ |
180 |
+@@ -1027,6 +1029,8 @@ static int wait_port_offline(__be64 __iomem *fc_regs, u32 delay_us, u32 nretry) |
181 |
+ do { |
182 |
+ msleep(delay_us / 1000); |
183 |
+ status = readq_be(&fc_regs[FC_MTIP_STATUS / 8]); |
184 |
++ if (status == U64_MAX) |
185 |
++ nretry /= 2; |
186 |
+ } while ((status & FC_MTIP_STATUS_MASK) != FC_MTIP_STATUS_OFFLINE && |
187 |
+ nretry--); |
188 |
+ |
189 |
+@@ -1137,7 +1141,7 @@ static const struct asyc_intr_info ainfo[] = { |
190 |
+ {SISL_ASTATUS_FC0_LOGI_F, "login failed", 0, CLR_FC_ERROR}, |
191 |
+ {SISL_ASTATUS_FC0_LOGI_S, "login succeeded", 0, SCAN_HOST}, |
192 |
+ {SISL_ASTATUS_FC0_LINK_DN, "link down", 0, 0}, |
193 |
+- {SISL_ASTATUS_FC0_LINK_UP, "link up", 0, SCAN_HOST}, |
194 |
++ {SISL_ASTATUS_FC0_LINK_UP, "link up", 0, 0}, |
195 |
+ {SISL_ASTATUS_FC1_OTHER, "other error", 1, CLR_FC_ERROR | LINK_RESET}, |
196 |
+ {SISL_ASTATUS_FC1_LOGO, "target initiated LOGO", 1, 0}, |
197 |
+ {SISL_ASTATUS_FC1_CRC_T, "CRC threshold exceeded", 1, LINK_RESET}, |
198 |
+@@ -1145,7 +1149,7 @@ static const struct asyc_intr_info ainfo[] = { |
199 |
+ {SISL_ASTATUS_FC1_LOGI_F, "login failed", 1, CLR_FC_ERROR}, |
200 |
+ {SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, SCAN_HOST}, |
201 |
+ {SISL_ASTATUS_FC1_LINK_DN, "link down", 1, 0}, |
202 |
+- {SISL_ASTATUS_FC1_LINK_UP, "link up", 1, SCAN_HOST}, |
203 |
++ {SISL_ASTATUS_FC1_LINK_UP, "link up", 1, 0}, |
204 |
+ {0x0, "", 0, 0} /* terminator */ |
205 |
+ }; |
206 |
+ |
207 |
+@@ -1962,6 +1966,11 @@ retry: |
208 |
+ * cxlflash_eh_host_reset_handler() - reset the host adapter |
209 |
+ * @scp: SCSI command from stack identifying host. |
210 |
+ * |
211 |
++ * Following a reset, the state is evaluated again in case an EEH occurred |
212 |
++ * during the reset. In such a scenario, the host reset will either yield |
213 |
++ * until the EEH recovery is complete or return success or failure based |
214 |
++ * upon the current device state. |
215 |
++ * |
216 |
+ * Return: |
217 |
+ * SUCCESS as defined in scsi/scsi.h |
218 |
+ * FAILED as defined in scsi/scsi.h |
219 |
+@@ -1993,7 +2002,8 @@ static int cxlflash_eh_host_reset_handler(struct scsi_cmnd *scp) |
220 |
+ } else |
221 |
+ cfg->state = STATE_NORMAL; |
222 |
+ wake_up_all(&cfg->reset_waitq); |
223 |
+- break; |
224 |
++ ssleep(1); |
225 |
++ /* fall through */ |
226 |
+ case STATE_RESET: |
227 |
+ wait_event(cfg->reset_waitq, cfg->state != STATE_RESET); |
228 |
+ if (cfg->state == STATE_NORMAL) |
229 |
+@@ -2534,6 +2544,9 @@ static void drain_ioctls(struct cxlflash_cfg *cfg) |
230 |
+ * @pdev: PCI device struct. |
231 |
+ * @state: PCI channel state. |
232 |
+ * |
233 |
++ * When an EEH occurs during an active reset, wait until the reset is |
234 |
++ * complete and then take action based upon the device state. |
235 |
++ * |
236 |
+ * Return: PCI_ERS_RESULT_NEED_RESET or PCI_ERS_RESULT_DISCONNECT |
237 |
+ */ |
238 |
+ static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev, |
239 |
+@@ -2547,6 +2560,10 @@ static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev, |
240 |
+ |
241 |
+ switch (state) { |
242 |
+ case pci_channel_io_frozen: |
243 |
++ wait_event(cfg->reset_waitq, cfg->state != STATE_RESET); |
244 |
++ if (cfg->state == STATE_FAILTERM) |
245 |
++ return PCI_ERS_RESULT_DISCONNECT; |
246 |
++ |
247 |
+ cfg->state = STATE_RESET; |
248 |
+ scsi_block_requests(cfg->host); |
249 |
+ drain_ioctls(cfg); |
250 |
+diff --git a/drivers/staging/rdma/ehca/ehca_mrmw.c b/drivers/staging/rdma/ehca/ehca_mrmw.c |
251 |
+index f914b30999f8..4d52ca42644a 100644 |
252 |
+--- a/drivers/staging/rdma/ehca/ehca_mrmw.c |
253 |
++++ b/drivers/staging/rdma/ehca/ehca_mrmw.c |
254 |
+@@ -1921,7 +1921,7 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo, |
255 |
+ u64 *kpage) |
256 |
+ { |
257 |
+ int ret = 0; |
258 |
+- u64 pgaddr, prev_pgaddr; |
259 |
++ u64 pgaddr, prev_pgaddr = 0; |
260 |
+ u32 j = 0; |
261 |
+ int kpages_per_hwpage = pginfo->hwpage_size / PAGE_SIZE; |
262 |
+ int nr_kpages = kpages_per_hwpage; |
263 |
+@@ -2417,6 +2417,7 @@ static int ehca_reg_bmap_mr_rpages(struct ehca_shca *shca, |
264 |
+ ehca_err(&shca->ib_device, "kpage alloc failed"); |
265 |
+ return -ENOMEM; |
266 |
+ } |
267 |
++ hret = H_SUCCESS; |
268 |
+ for (top = 0; top < EHCA_MAP_ENTRIES; top++) { |
269 |
+ if (!ehca_bmap_valid(ehca_bmap->top[top])) |
270 |
+ continue; |
271 |
+diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c |
272 |
+index 83ff1724ec79..cf3da51a3536 100644 |
273 |
+--- a/drivers/tty/serial/8250/8250_pci.c |
274 |
++++ b/drivers/tty/serial/8250/8250_pci.c |
275 |
+@@ -5850,17 +5850,15 @@ static pci_ers_result_t serial8250_io_slot_reset(struct pci_dev *dev) |
276 |
+ static void serial8250_io_resume(struct pci_dev *dev) |
277 |
+ { |
278 |
+ struct serial_private *priv = pci_get_drvdata(dev); |
279 |
+- const struct pciserial_board *board; |
280 |
++ struct serial_private *new; |
281 |
+ |
282 |
+ if (!priv) |
283 |
+ return; |
284 |
+ |
285 |
+- board = priv->board; |
286 |
+- kfree(priv); |
287 |
+- priv = pciserial_init_ports(dev, board); |
288 |
+- |
289 |
+- if (!IS_ERR(priv)) { |
290 |
+- pci_set_drvdata(dev, priv); |
291 |
++ new = pciserial_init_ports(dev, priv->board); |
292 |
++ if (!IS_ERR(new)) { |
293 |
++ pci_set_drvdata(dev, new); |
294 |
++ kfree(priv); |
295 |
+ } |
296 |
+ } |
297 |
+ |
298 |
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h |
299 |
+index 94906aaa9b7c..e2f6a79e9b01 100644 |
300 |
+--- a/fs/cifs/cifsglob.h |
301 |
++++ b/fs/cifs/cifsglob.h |
302 |
+@@ -227,6 +227,7 @@ struct smb_version_operations { |
303 |
+ /* verify the message */ |
304 |
+ int (*check_message)(char *, unsigned int); |
305 |
+ bool (*is_oplock_break)(char *, struct TCP_Server_Info *); |
306 |
++ int (*handle_cancelled_mid)(char *, struct TCP_Server_Info *); |
307 |
+ void (*downgrade_oplock)(struct TCP_Server_Info *, |
308 |
+ struct cifsInodeInfo *, bool); |
309 |
+ /* process transaction2 response */ |
310 |
+@@ -1289,12 +1290,19 @@ struct mid_q_entry { |
311 |
+ void *callback_data; /* general purpose pointer for callback */ |
312 |
+ void *resp_buf; /* pointer to received SMB header */ |
313 |
+ int mid_state; /* wish this were enum but can not pass to wait_event */ |
314 |
++ unsigned int mid_flags; |
315 |
+ __le16 command; /* smb command code */ |
316 |
+ bool large_buf:1; /* if valid response, is pointer to large buf */ |
317 |
+ bool multiRsp:1; /* multiple trans2 responses for one request */ |
318 |
+ bool multiEnd:1; /* both received */ |
319 |
+ }; |
320 |
+ |
321 |
++struct close_cancelled_open { |
322 |
++ struct cifs_fid fid; |
323 |
++ struct cifs_tcon *tcon; |
324 |
++ struct work_struct work; |
325 |
++}; |
326 |
++ |
327 |
+ /* Make code in transport.c a little cleaner by moving |
328 |
+ update of optional stats into function below */ |
329 |
+ #ifdef CONFIG_CIFS_STATS2 |
330 |
+@@ -1426,6 +1434,9 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, |
331 |
+ #define MID_RESPONSE_MALFORMED 0x10 |
332 |
+ #define MID_SHUTDOWN 0x20 |
333 |
+ |
334 |
++/* Flags */ |
335 |
++#define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ |
336 |
++ |
337 |
+ /* Types of response buffer returned from SendReceive2 */ |
338 |
+ #define CIFS_NO_BUFFER 0 /* Response buffer not returned */ |
339 |
+ #define CIFS_SMALL_BUFFER 1 |
340 |
+diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c |
341 |
+index b1104ed8f54c..5e2f8b8ca08a 100644 |
342 |
+--- a/fs/cifs/cifssmb.c |
343 |
++++ b/fs/cifs/cifssmb.c |
344 |
+@@ -1424,6 +1424,8 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) |
345 |
+ |
346 |
+ length = discard_remaining_data(server); |
347 |
+ dequeue_mid(mid, rdata->result); |
348 |
++ mid->resp_buf = server->smallbuf; |
349 |
++ server->smallbuf = NULL; |
350 |
+ return length; |
351 |
+ } |
352 |
+ |
353 |
+@@ -1538,6 +1540,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) |
354 |
+ return cifs_readv_discard(server, mid); |
355 |
+ |
356 |
+ dequeue_mid(mid, false); |
357 |
++ mid->resp_buf = server->smallbuf; |
358 |
++ server->smallbuf = NULL; |
359 |
+ return length; |
360 |
+ } |
361 |
+ |
362 |
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c |
363 |
+index 5d59f25521ce..156bc18eac69 100644 |
364 |
+--- a/fs/cifs/connect.c |
365 |
++++ b/fs/cifs/connect.c |
366 |
+@@ -924,10 +924,19 @@ cifs_demultiplex_thread(void *p) |
367 |
+ |
368 |
+ server->lstrp = jiffies; |
369 |
+ if (mid_entry != NULL) { |
370 |
++ if ((mid_entry->mid_flags & MID_WAIT_CANCELLED) && |
371 |
++ mid_entry->mid_state == MID_RESPONSE_RECEIVED && |
372 |
++ server->ops->handle_cancelled_mid) |
373 |
++ server->ops->handle_cancelled_mid( |
374 |
++ mid_entry->resp_buf, |
375 |
++ server); |
376 |
++ |
377 |
+ if (!mid_entry->multiRsp || mid_entry->multiEnd) |
378 |
+ mid_entry->callback(mid_entry); |
379 |
+- } else if (!server->ops->is_oplock_break || |
380 |
+- !server->ops->is_oplock_break(buf, server)) { |
381 |
++ } else if (server->ops->is_oplock_break && |
382 |
++ server->ops->is_oplock_break(buf, server)) { |
383 |
++ cifs_dbg(FYI, "Received oplock break\n"); |
384 |
++ } else { |
385 |
+ cifs_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n", |
386 |
+ atomic_read(&midCount)); |
387 |
+ cifs_dump_mem("Received Data is: ", buf, |
388 |
+diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c |
389 |
+index e5bc85e49be7..76ccf20fbfb7 100644 |
390 |
+--- a/fs/cifs/smb2misc.c |
391 |
++++ b/fs/cifs/smb2misc.c |
392 |
+@@ -630,3 +630,47 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) |
393 |
+ cifs_dbg(FYI, "Can not process oplock break for non-existent connection\n"); |
394 |
+ return false; |
395 |
+ } |
396 |
++ |
397 |
++void |
398 |
++smb2_cancelled_close_fid(struct work_struct *work) |
399 |
++{ |
400 |
++ struct close_cancelled_open *cancelled = container_of(work, |
401 |
++ struct close_cancelled_open, work); |
402 |
++ |
403 |
++ cifs_dbg(VFS, "Close unmatched open\n"); |
404 |
++ |
405 |
++ SMB2_close(0, cancelled->tcon, cancelled->fid.persistent_fid, |
406 |
++ cancelled->fid.volatile_fid); |
407 |
++ cifs_put_tcon(cancelled->tcon); |
408 |
++ kfree(cancelled); |
409 |
++} |
410 |
++ |
411 |
++int |
412 |
++smb2_handle_cancelled_mid(char *buffer, struct TCP_Server_Info *server) |
413 |
++{ |
414 |
++ struct smb2_hdr *hdr = (struct smb2_hdr *)buffer; |
415 |
++ struct smb2_create_rsp *rsp = (struct smb2_create_rsp *)buffer; |
416 |
++ struct cifs_tcon *tcon; |
417 |
++ struct close_cancelled_open *cancelled; |
418 |
++ |
419 |
++ if (hdr->Command != SMB2_CREATE || hdr->Status != STATUS_SUCCESS) |
420 |
++ return 0; |
421 |
++ |
422 |
++ cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL); |
423 |
++ if (!cancelled) |
424 |
++ return -ENOMEM; |
425 |
++ |
426 |
++ tcon = smb2_find_smb_tcon(server, hdr->SessionId, hdr->TreeId); |
427 |
++ if (!tcon) { |
428 |
++ kfree(cancelled); |
429 |
++ return -ENOENT; |
430 |
++ } |
431 |
++ |
432 |
++ cancelled->fid.persistent_fid = rsp->PersistentFileId; |
433 |
++ cancelled->fid.volatile_fid = rsp->VolatileFileId; |
434 |
++ cancelled->tcon = tcon; |
435 |
++ INIT_WORK(&cancelled->work, smb2_cancelled_close_fid); |
436 |
++ queue_work(cifsiod_wq, &cancelled->work); |
437 |
++ |
438 |
++ return 0; |
439 |
++} |
440 |
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c |
441 |
+index be34b4860675..087918c4612a 100644 |
442 |
+--- a/fs/cifs/smb2ops.c |
443 |
++++ b/fs/cifs/smb2ops.c |
444 |
+@@ -1511,6 +1511,7 @@ struct smb_version_operations smb20_operations = { |
445 |
+ .clear_stats = smb2_clear_stats, |
446 |
+ .print_stats = smb2_print_stats, |
447 |
+ .is_oplock_break = smb2_is_valid_oplock_break, |
448 |
++ .handle_cancelled_mid = smb2_handle_cancelled_mid, |
449 |
+ .downgrade_oplock = smb2_downgrade_oplock, |
450 |
+ .need_neg = smb2_need_neg, |
451 |
+ .negotiate = smb2_negotiate, |
452 |
+@@ -1589,6 +1590,7 @@ struct smb_version_operations smb21_operations = { |
453 |
+ .clear_stats = smb2_clear_stats, |
454 |
+ .print_stats = smb2_print_stats, |
455 |
+ .is_oplock_break = smb2_is_valid_oplock_break, |
456 |
++ .handle_cancelled_mid = smb2_handle_cancelled_mid, |
457 |
+ .downgrade_oplock = smb2_downgrade_oplock, |
458 |
+ .need_neg = smb2_need_neg, |
459 |
+ .negotiate = smb2_negotiate, |
460 |
+@@ -1670,6 +1672,7 @@ struct smb_version_operations smb30_operations = { |
461 |
+ .print_stats = smb2_print_stats, |
462 |
+ .dump_share_caps = smb2_dump_share_caps, |
463 |
+ .is_oplock_break = smb2_is_valid_oplock_break, |
464 |
++ .handle_cancelled_mid = smb2_handle_cancelled_mid, |
465 |
+ .downgrade_oplock = smb2_downgrade_oplock, |
466 |
+ .need_neg = smb2_need_neg, |
467 |
+ .negotiate = smb2_negotiate, |
468 |
+@@ -1757,6 +1760,7 @@ struct smb_version_operations smb311_operations = { |
469 |
+ .print_stats = smb2_print_stats, |
470 |
+ .dump_share_caps = smb2_dump_share_caps, |
471 |
+ .is_oplock_break = smb2_is_valid_oplock_break, |
472 |
++ .handle_cancelled_mid = smb2_handle_cancelled_mid, |
473 |
+ .downgrade_oplock = smb2_downgrade_oplock, |
474 |
+ .need_neg = smb2_need_neg, |
475 |
+ .negotiate = smb2_negotiate, |
476 |
+diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h |
477 |
+index 0a406ae78129..adc5234486c3 100644 |
478 |
+--- a/fs/cifs/smb2proto.h |
479 |
++++ b/fs/cifs/smb2proto.h |
480 |
+@@ -47,6 +47,10 @@ extern struct mid_q_entry *smb2_setup_request(struct cifs_ses *ses, |
481 |
+ struct smb_rqst *rqst); |
482 |
+ extern struct mid_q_entry *smb2_setup_async_request( |
483 |
+ struct TCP_Server_Info *server, struct smb_rqst *rqst); |
484 |
++extern struct cifs_ses *smb2_find_smb_ses(struct TCP_Server_Info *server, |
485 |
++ __u64 ses_id); |
486 |
++extern struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server, |
487 |
++ __u64 ses_id, __u32 tid); |
488 |
+ extern int smb2_calc_signature(struct smb_rqst *rqst, |
489 |
+ struct TCP_Server_Info *server); |
490 |
+ extern int smb3_calc_signature(struct smb_rqst *rqst, |
491 |
+@@ -157,6 +161,9 @@ extern int SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, |
492 |
+ extern int SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, |
493 |
+ const u64 persistent_fid, const u64 volatile_fid, |
494 |
+ const __u8 oplock_level); |
495 |
++extern int smb2_handle_cancelled_mid(char *buffer, |
496 |
++ struct TCP_Server_Info *server); |
497 |
++void smb2_cancelled_close_fid(struct work_struct *work); |
498 |
+ extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, |
499 |
+ u64 persistent_file_id, u64 volatile_file_id, |
500 |
+ struct kstatfs *FSData); |
501 |
+diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c |
502 |
+index d4c5b6f109a7..69e3b322bbfe 100644 |
503 |
+--- a/fs/cifs/smb2transport.c |
504 |
++++ b/fs/cifs/smb2transport.c |
505 |
+@@ -115,22 +115,68 @@ smb3_crypto_shash_allocate(struct TCP_Server_Info *server) |
506 |
+ } |
507 |
+ |
508 |
+ static struct cifs_ses * |
509 |
+-smb2_find_smb_ses(struct smb2_hdr *smb2hdr, struct TCP_Server_Info *server) |
510 |
++smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id) |
511 |
+ { |
512 |
+ struct cifs_ses *ses; |
513 |
+ |
514 |
+- spin_lock(&cifs_tcp_ses_lock); |
515 |
+ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { |
516 |
+- if (ses->Suid != smb2hdr->SessionId) |
517 |
++ if (ses->Suid != ses_id) |
518 |
+ continue; |
519 |
+- spin_unlock(&cifs_tcp_ses_lock); |
520 |
+ return ses; |
521 |
+ } |
522 |
++ |
523 |
++ return NULL; |
524 |
++} |
525 |
++ |
526 |
++struct cifs_ses * |
527 |
++smb2_find_smb_ses(struct TCP_Server_Info *server, __u64 ses_id) |
528 |
++{ |
529 |
++ struct cifs_ses *ses; |
530 |
++ |
531 |
++ spin_lock(&cifs_tcp_ses_lock); |
532 |
++ ses = smb2_find_smb_ses_unlocked(server, ses_id); |
533 |
+ spin_unlock(&cifs_tcp_ses_lock); |
534 |
+ |
535 |
++ return ses; |
536 |
++} |
537 |
++ |
538 |
++static struct cifs_tcon * |
539 |
++smb2_find_smb_sess_tcon_unlocked(struct cifs_ses *ses, __u32 tid) |
540 |
++{ |
541 |
++ struct cifs_tcon *tcon; |
542 |
++ |
543 |
++ list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { |
544 |
++ if (tcon->tid != tid) |
545 |
++ continue; |
546 |
++ ++tcon->tc_count; |
547 |
++ return tcon; |
548 |
++ } |
549 |
++ |
550 |
+ return NULL; |
551 |
+ } |
552 |
+ |
553 |
++/* |
554 |
++ * Obtain tcon corresponding to the tid in the given |
555 |
++ * cifs_ses |
556 |
++ */ |
557 |
++ |
558 |
++struct cifs_tcon * |
559 |
++smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid) |
560 |
++{ |
561 |
++ struct cifs_ses *ses; |
562 |
++ struct cifs_tcon *tcon; |
563 |
++ |
564 |
++ spin_lock(&cifs_tcp_ses_lock); |
565 |
++ ses = smb2_find_smb_ses_unlocked(server, ses_id); |
566 |
++ if (!ses) { |
567 |
++ spin_unlock(&cifs_tcp_ses_lock); |
568 |
++ return NULL; |
569 |
++ } |
570 |
++ tcon = smb2_find_smb_sess_tcon_unlocked(ses, tid); |
571 |
++ spin_unlock(&cifs_tcp_ses_lock); |
572 |
++ |
573 |
++ return tcon; |
574 |
++} |
575 |
+ |
576 |
+ int |
577 |
+ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) |
578 |
+@@ -143,7 +189,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) |
579 |
+ struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base; |
580 |
+ struct cifs_ses *ses; |
581 |
+ |
582 |
+- ses = smb2_find_smb_ses(smb2_pdu, server); |
583 |
++ ses = smb2_find_smb_ses(server, smb2_pdu->SessionId); |
584 |
+ if (!ses) { |
585 |
+ cifs_dbg(VFS, "%s: Could not find session\n", __func__); |
586 |
+ return 0; |
587 |
+@@ -314,7 +360,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) |
588 |
+ struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base; |
589 |
+ struct cifs_ses *ses; |
590 |
+ |
591 |
+- ses = smb2_find_smb_ses(smb2_pdu, server); |
592 |
++ ses = smb2_find_smb_ses(server, smb2_pdu->SessionId); |
593 |
+ if (!ses) { |
594 |
+ cifs_dbg(VFS, "%s: Could not find session\n", __func__); |
595 |
+ return 0; |
596 |
+diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c |
597 |
+index 87abe8ed074c..54af10204e83 100644 |
598 |
+--- a/fs/cifs/transport.c |
599 |
++++ b/fs/cifs/transport.c |
600 |
+@@ -786,9 +786,11 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses, |
601 |
+ |
602 |
+ rc = wait_for_response(ses->server, midQ); |
603 |
+ if (rc != 0) { |
604 |
++ cifs_dbg(FYI, "Cancelling wait for mid %llu\n", midQ->mid); |
605 |
+ send_cancel(ses->server, buf, midQ); |
606 |
+ spin_lock(&GlobalMid_Lock); |
607 |
+ if (midQ->mid_state == MID_REQUEST_SUBMITTED) { |
608 |
++ midQ->mid_flags |= MID_WAIT_CANCELLED; |
609 |
+ midQ->callback = DeleteMidQEntry; |
610 |
+ spin_unlock(&GlobalMid_Lock); |
611 |
+ cifs_small_buf_release(buf); |
612 |
+diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c |
613 |
+index 1a0835073663..9d6c2dcf1bd0 100644 |
614 |
+--- a/fs/ext4/crypto.c |
615 |
++++ b/fs/ext4/crypto.c |
616 |
+@@ -34,6 +34,7 @@ |
617 |
+ #include <linux/random.h> |
618 |
+ #include <linux/scatterlist.h> |
619 |
+ #include <linux/spinlock_types.h> |
620 |
++#include <linux/namei.h> |
621 |
+ |
622 |
+ #include "ext4_extents.h" |
623 |
+ #include "xattr.h" |
624 |
+@@ -469,3 +470,61 @@ uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size) |
625 |
+ return size; |
626 |
+ return 0; |
627 |
+ } |
628 |
++ |
629 |
++/* |
630 |
++ * Validate dentries for encrypted directories to make sure we aren't |
631 |
++ * potentially caching stale data after a key has been added or |
632 |
++ * removed. |
633 |
++ */ |
634 |
++static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags) |
635 |
++{ |
636 |
++ struct dentry *dir; |
637 |
++ struct ext4_crypt_info *ci; |
638 |
++ int dir_has_key, cached_with_key; |
639 |
++ |
640 |
++ if (flags & LOOKUP_RCU) |
641 |
++ return -ECHILD; |
642 |
++ |
643 |
++ dir = dget_parent(dentry); |
644 |
++ if (!ext4_encrypted_inode(d_inode(dir))) { |
645 |
++ dput(dir); |
646 |
++ return 0; |
647 |
++ } |
648 |
++ ci = EXT4_I(d_inode(dir))->i_crypt_info; |
649 |
++ |
650 |
++ /* this should eventually be an flag in d_flags */ |
651 |
++ cached_with_key = dentry->d_fsdata != NULL; |
652 |
++ dir_has_key = (ci != NULL); |
653 |
++ dput(dir); |
654 |
++ |
655 |
++ /* |
656 |
++ * If the dentry was cached without the key, and it is a |
657 |
++ * negative dentry, it might be a valid name. We can't check |
658 |
++ * if the key has since been made available due to locking |
659 |
++ * reasons, so we fail the validation so ext4_lookup() can do |
660 |
++ * this check. |
661 |
++ * |
662 |
++ * We also fail the validation if the dentry was created with |
663 |
++ * the key present, but we no longer have the key, or vice versa. |
664 |
++ */ |
665 |
++ if ((!cached_with_key && d_is_negative(dentry)) || |
666 |
++ (!cached_with_key && dir_has_key) || |
667 |
++ (cached_with_key && !dir_has_key)) { |
668 |
++#if 0 /* Revalidation debug */ |
669 |
++ char buf[80]; |
670 |
++ char *cp = simple_dname(dentry, buf, sizeof(buf)); |
671 |
++ |
672 |
++ if (IS_ERR(cp)) |
673 |
++ cp = (char *) "???"; |
674 |
++ pr_err("revalidate: %s %p %d %d %d\n", cp, dentry->d_fsdata, |
675 |
++ cached_with_key, d_is_negative(dentry), |
676 |
++ dir_has_key); |
677 |
++#endif |
678 |
++ return 0; |
679 |
++ } |
680 |
++ return 1; |
681 |
++} |
682 |
++ |
683 |
++const struct dentry_operations ext4_encrypted_d_ops = { |
684 |
++ .d_revalidate = ext4_d_revalidate, |
685 |
++}; |
686 |
+diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c |
687 |
+index 1d1bca74f844..6d17f31a31d7 100644 |
688 |
+--- a/fs/ext4/dir.c |
689 |
++++ b/fs/ext4/dir.c |
690 |
+@@ -111,6 +111,12 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx) |
691 |
+ int dir_has_error = 0; |
692 |
+ struct ext4_str fname_crypto_str = {.name = NULL, .len = 0}; |
693 |
+ |
694 |
++ if (ext4_encrypted_inode(inode)) { |
695 |
++ err = ext4_get_encryption_info(inode); |
696 |
++ if (err && err != -ENOKEY) |
697 |
++ return err; |
698 |
++ } |
699 |
++ |
700 |
+ if (is_dx_dir(inode)) { |
701 |
+ err = ext4_dx_readdir(file, ctx); |
702 |
+ if (err != ERR_BAD_DX_DIR) { |
703 |
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h |
704 |
+index 362d59b24f1d..3de9bb357b4f 100644 |
705 |
+--- a/fs/ext4/ext4.h |
706 |
++++ b/fs/ext4/ext4.h |
707 |
+@@ -2268,6 +2268,7 @@ struct page *ext4_encrypt(struct inode *inode, |
708 |
+ struct page *plaintext_page); |
709 |
+ int ext4_decrypt(struct page *page); |
710 |
+ int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex); |
711 |
++extern const struct dentry_operations ext4_encrypted_d_ops; |
712 |
+ |
713 |
+ #ifdef CONFIG_EXT4_FS_ENCRYPTION |
714 |
+ int ext4_init_crypto(void); |
715 |
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c |
716 |
+index 789e2d6724a9..bcd7c4788903 100644 |
717 |
+--- a/fs/ext4/ioctl.c |
718 |
++++ b/fs/ext4/ioctl.c |
719 |
+@@ -622,6 +622,9 @@ resizefs_out: |
720 |
+ struct ext4_encryption_policy policy; |
721 |
+ int err = 0; |
722 |
+ |
723 |
++ if (!ext4_has_feature_encrypt(sb)) |
724 |
++ return -EOPNOTSUPP; |
725 |
++ |
726 |
+ if (copy_from_user(&policy, |
727 |
+ (struct ext4_encryption_policy __user *)arg, |
728 |
+ sizeof(policy))) { |
729 |
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c |
730 |
+index 573b4cbb0cb9..fafa903ab3c0 100644 |
731 |
+--- a/fs/ext4/namei.c |
732 |
++++ b/fs/ext4/namei.c |
733 |
+@@ -1557,6 +1557,24 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi |
734 |
+ struct ext4_dir_entry_2 *de; |
735 |
+ struct buffer_head *bh; |
736 |
+ |
737 |
++ if (ext4_encrypted_inode(dir)) { |
738 |
++ int res = ext4_get_encryption_info(dir); |
739 |
++ |
740 |
++ /* |
741 |
++ * This should be a properly defined flag for |
742 |
++ * dentry->d_flags when we uplift this to the VFS. |
743 |
++ * d_fsdata is set to (void *) 1 if if the dentry is |
744 |
++ * created while the directory was encrypted and we |
745 |
++ * don't have access to the key. |
746 |
++ */ |
747 |
++ dentry->d_fsdata = NULL; |
748 |
++ if (ext4_encryption_info(dir)) |
749 |
++ dentry->d_fsdata = (void *) 1; |
750 |
++ d_set_d_op(dentry, &ext4_encrypted_d_ops); |
751 |
++ if (res && res != -ENOKEY) |
752 |
++ return ERR_PTR(res); |
753 |
++ } |
754 |
++ |
755 |
+ if (dentry->d_name.len > EXT4_NAME_LEN) |
756 |
+ return ERR_PTR(-ENAMETOOLONG); |
757 |
+ |
758 |
+diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c |
759 |
+index 00575d776d91..7162ab7bc093 100644 |
760 |
+--- a/fs/nfsd/nfs3xdr.c |
761 |
++++ b/fs/nfsd/nfs3xdr.c |
762 |
+@@ -358,6 +358,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, |
763 |
+ { |
764 |
+ unsigned int len, v, hdr, dlen; |
765 |
+ u32 max_blocksize = svc_max_payload(rqstp); |
766 |
++ struct kvec *head = rqstp->rq_arg.head; |
767 |
+ |
768 |
+ p = decode_fh(p, &args->fh); |
769 |
+ if (!p) |
770 |
+@@ -367,6 +368,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, |
771 |
+ args->count = ntohl(*p++); |
772 |
+ args->stable = ntohl(*p++); |
773 |
+ len = args->len = ntohl(*p++); |
774 |
++ if ((void *)p > head->iov_base + head->iov_len) |
775 |
++ return 0; |
776 |
+ /* |
777 |
+ * The count must equal the amount of data passed. |
778 |
+ */ |
779 |
+@@ -377,9 +380,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, |
780 |
+ * Check to make sure that we got the right number of |
781 |
+ * bytes. |
782 |
+ */ |
783 |
+- hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; |
784 |
+- dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len |
785 |
+- - hdr; |
786 |
++ hdr = (void*)p - head->iov_base; |
787 |
++ dlen = head->iov_len + rqstp->rq_arg.page_len - hdr; |
788 |
+ /* |
789 |
+ * Round the length of the data which was specified up to |
790 |
+ * the next multiple of XDR units and then compare that |
791 |
+@@ -396,7 +398,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, |
792 |
+ len = args->len = max_blocksize; |
793 |
+ } |
794 |
+ rqstp->rq_vec[0].iov_base = (void*)p; |
795 |
+- rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr; |
796 |
++ rqstp->rq_vec[0].iov_len = head->iov_len - hdr; |
797 |
+ v = 0; |
798 |
+ while (len > rqstp->rq_vec[v].iov_len) { |
799 |
+ len -= rqstp->rq_vec[v].iov_len; |
800 |
+@@ -471,6 +473,8 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, |
801 |
+ /* first copy and check from the first page */ |
802 |
+ old = (char*)p; |
803 |
+ vec = &rqstp->rq_arg.head[0]; |
804 |
++ if ((void *)old > vec->iov_base + vec->iov_len) |
805 |
++ return 0; |
806 |
+ avail = vec->iov_len - (old - (char*)vec->iov_base); |
807 |
+ while (len && avail && *old) { |
808 |
+ *new++ = *old++; |
809 |
+diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c |
810 |
+index 79d964aa8079..bf913201a6ad 100644 |
811 |
+--- a/fs/nfsd/nfsxdr.c |
812 |
++++ b/fs/nfsd/nfsxdr.c |
813 |
+@@ -280,6 +280,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, |
814 |
+ struct nfsd_writeargs *args) |
815 |
+ { |
816 |
+ unsigned int len, hdr, dlen; |
817 |
++ struct kvec *head = rqstp->rq_arg.head; |
818 |
+ int v; |
819 |
+ |
820 |
+ p = decode_fh(p, &args->fh); |
821 |
+@@ -300,9 +301,10 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, |
822 |
+ * Check to make sure that we got the right number of |
823 |
+ * bytes. |
824 |
+ */ |
825 |
+- hdr = (void*)p - rqstp->rq_arg.head[0].iov_base; |
826 |
+- dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len |
827 |
+- - hdr; |
828 |
++ hdr = (void*)p - head->iov_base; |
829 |
++ if (hdr > head->iov_len) |
830 |
++ return 0; |
831 |
++ dlen = head->iov_len + rqstp->rq_arg.page_len - hdr; |
832 |
+ |
833 |
+ /* |
834 |
+ * Round the length of the data which was specified up to |
835 |
+@@ -316,7 +318,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, |
836 |
+ return 0; |
837 |
+ |
838 |
+ rqstp->rq_vec[0].iov_base = (void*)p; |
839 |
+- rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr; |
840 |
++ rqstp->rq_vec[0].iov_len = head->iov_len - hdr; |
841 |
+ v = 0; |
842 |
+ while (len > rqstp->rq_vec[v].iov_len) { |
843 |
+ len -= rqstp->rq_vec[v].iov_len; |
844 |
+diff --git a/fs/timerfd.c b/fs/timerfd.c |
845 |
+index 053818dd6c18..1327a02ec778 100644 |
846 |
+--- a/fs/timerfd.c |
847 |
++++ b/fs/timerfd.c |
848 |
+@@ -40,6 +40,7 @@ struct timerfd_ctx { |
849 |
+ short unsigned settime_flags; /* to show in fdinfo */ |
850 |
+ struct rcu_head rcu; |
851 |
+ struct list_head clist; |
852 |
++ spinlock_t cancel_lock; |
853 |
+ bool might_cancel; |
854 |
+ }; |
855 |
+ |
856 |
+@@ -112,7 +113,7 @@ void timerfd_clock_was_set(void) |
857 |
+ rcu_read_unlock(); |
858 |
+ } |
859 |
+ |
860 |
+-static void timerfd_remove_cancel(struct timerfd_ctx *ctx) |
861 |
++static void __timerfd_remove_cancel(struct timerfd_ctx *ctx) |
862 |
+ { |
863 |
+ if (ctx->might_cancel) { |
864 |
+ ctx->might_cancel = false; |
865 |
+@@ -122,6 +123,13 @@ static void timerfd_remove_cancel(struct timerfd_ctx *ctx) |
866 |
+ } |
867 |
+ } |
868 |
+ |
869 |
++static void timerfd_remove_cancel(struct timerfd_ctx *ctx) |
870 |
++{ |
871 |
++ spin_lock(&ctx->cancel_lock); |
872 |
++ __timerfd_remove_cancel(ctx); |
873 |
++ spin_unlock(&ctx->cancel_lock); |
874 |
++} |
875 |
++ |
876 |
+ static bool timerfd_canceled(struct timerfd_ctx *ctx) |
877 |
+ { |
878 |
+ if (!ctx->might_cancel || ctx->moffs.tv64 != KTIME_MAX) |
879 |
+@@ -132,6 +140,7 @@ static bool timerfd_canceled(struct timerfd_ctx *ctx) |
880 |
+ |
881 |
+ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) |
882 |
+ { |
883 |
++ spin_lock(&ctx->cancel_lock); |
884 |
+ if ((ctx->clockid == CLOCK_REALTIME || |
885 |
+ ctx->clockid == CLOCK_REALTIME_ALARM) && |
886 |
+ (flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) { |
887 |
+@@ -141,9 +150,10 @@ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) |
888 |
+ list_add_rcu(&ctx->clist, &cancel_list); |
889 |
+ spin_unlock(&cancel_lock); |
890 |
+ } |
891 |
+- } else if (ctx->might_cancel) { |
892 |
+- timerfd_remove_cancel(ctx); |
893 |
++ } else { |
894 |
++ __timerfd_remove_cancel(ctx); |
895 |
+ } |
896 |
++ spin_unlock(&ctx->cancel_lock); |
897 |
+ } |
898 |
+ |
899 |
+ static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx) |
900 |
+@@ -395,6 +405,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) |
901 |
+ return -ENOMEM; |
902 |
+ |
903 |
+ init_waitqueue_head(&ctx->wqh); |
904 |
++ spin_lock_init(&ctx->cancel_lock); |
905 |
+ ctx->clockid = clockid; |
906 |
+ |
907 |
+ if (isalarm(ctx)) |
908 |
+diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h |
909 |
+index 366cf77953b5..806d0ab845e0 100644 |
910 |
+--- a/include/linux/mtd/map.h |
911 |
++++ b/include/linux/mtd/map.h |
912 |
+@@ -122,18 +122,13 @@ |
913 |
+ #endif |
914 |
+ |
915 |
+ #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32 |
916 |
+-# ifdef map_bankwidth |
917 |
+-# undef map_bankwidth |
918 |
+-# define map_bankwidth(map) ((map)->bankwidth) |
919 |
+-# undef map_bankwidth_is_large |
920 |
+-# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) |
921 |
+-# undef map_words |
922 |
+-# define map_words(map) map_calc_words(map) |
923 |
+-# else |
924 |
+-# define map_bankwidth(map) 32 |
925 |
+-# define map_bankwidth_is_large(map) (1) |
926 |
+-# define map_words(map) map_calc_words(map) |
927 |
+-# endif |
928 |
++/* always use indirect access for 256-bit to preserve kernel stack */ |
929 |
++# undef map_bankwidth |
930 |
++# define map_bankwidth(map) ((map)->bankwidth) |
931 |
++# undef map_bankwidth_is_large |
932 |
++# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) |
933 |
++# undef map_words |
934 |
++# define map_words(map) map_calc_words(map) |
935 |
+ #define map_bankwidth_is_32(map) (map_bankwidth(map) == 32) |
936 |
+ #undef MAX_MAP_BANKWIDTH |
937 |
+ #define MAX_MAP_BANKWIDTH 32 |
938 |
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c |
939 |
+index 8e33019d8e7b..acfb16fdcd55 100644 |
940 |
+--- a/net/netlink/af_netlink.c |
941 |
++++ b/net/netlink/af_netlink.c |
942 |
+@@ -2107,7 +2107,7 @@ static int netlink_dump(struct sock *sk) |
943 |
+ if (!skb) { |
944 |
+ alloc_size = alloc_min_size; |
945 |
+ skb = netlink_alloc_skb(sk, alloc_size, nlk->portid, |
946 |
+- (GFP_KERNEL & ~__GFP_DIRECT_RECLAIM)); |
947 |
++ GFP_KERNEL); |
948 |
+ } |
949 |
+ if (!skb) |
950 |
+ goto errout_skb; |
951 |
+diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c |
952 |
+index 09da7b52bc2e..1468e4b7bf93 100644 |
953 |
+--- a/sound/ppc/awacs.c |
954 |
++++ b/sound/ppc/awacs.c |
955 |
+@@ -991,6 +991,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip) |
956 |
+ if (err < 0) |
957 |
+ return err; |
958 |
+ } |
959 |
++ master_vol = NULL; |
960 |
+ if (pm7500) |
961 |
+ err = build_mixers(chip, |
962 |
+ ARRAY_SIZE(snd_pmac_awacs_mixers_pmac7500), |
963 |
+diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c |
964 |
+index 7a5c9a36c1db..daba8c56b43b 100644 |
965 |
+--- a/sound/soc/intel/boards/bytcr_rt5640.c |
966 |
++++ b/sound/soc/intel/boards/bytcr_rt5640.c |
967 |
+@@ -139,7 +139,7 @@ static struct snd_soc_dai_link byt_dailink[] = { |
968 |
+ .codec_dai_name = "snd-soc-dummy-dai", |
969 |
+ .codec_name = "snd-soc-dummy", |
970 |
+ .platform_name = "sst-mfld-platform", |
971 |
+- .ignore_suspend = 1, |
972 |
++ .nonatomic = true, |
973 |
+ .dynamic = 1, |
974 |
+ .dpcm_playback = 1, |
975 |
+ .dpcm_capture = 1, |
976 |
+@@ -166,6 +166,7 @@ static struct snd_soc_dai_link byt_dailink[] = { |
977 |
+ | SND_SOC_DAIFMT_CBS_CFS, |
978 |
+ .be_hw_params_fixup = byt_codec_fixup, |
979 |
+ .ignore_suspend = 1, |
980 |
++ .nonatomic = true, |
981 |
+ .dpcm_playback = 1, |
982 |
+ .dpcm_capture = 1, |
983 |
+ .ops = &byt_be_ssp2_ops, |