Annotation of /trunk/kernel26-alx/patches-2.6.27-r3/0123-2.6.27.24-all-fixes.patch
Parent Directory | Revision Log
Revision 1176 -
(hide annotations)
(download)
Thu Oct 14 15:11:06 2010 UTC (13 years, 11 months ago) by niro
File size: 49489 byte(s)
Thu Oct 14 15:11:06 2010 UTC (13 years, 11 months ago) by niro
File size: 49489 byte(s)
-2.6.27-alx-r3: new magellan 0.5.2 kernel
1 | niro | 1176 | diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking |
2 | index 8362860..0a7c8a9 100644 | ||
3 | --- a/Documentation/filesystems/Locking | ||
4 | +++ b/Documentation/filesystems/Locking | ||
5 | @@ -502,23 +502,31 @@ prototypes: | ||
6 | void (*open)(struct vm_area_struct*); | ||
7 | void (*close)(struct vm_area_struct*); | ||
8 | int (*fault)(struct vm_area_struct*, struct vm_fault *); | ||
9 | - int (*page_mkwrite)(struct vm_area_struct *, struct page *); | ||
10 | + int (*page_mkwrite)(struct vm_area_struct *, struct vm_fault *); | ||
11 | int (*access)(struct vm_area_struct *, unsigned long, void*, int, int); | ||
12 | |||
13 | locking rules: | ||
14 | BKL mmap_sem PageLocked(page) | ||
15 | open: no yes | ||
16 | close: no yes | ||
17 | -fault: no yes | ||
18 | -page_mkwrite: no yes no | ||
19 | +fault: no yes can return with page locked | ||
20 | +page_mkwrite: no yes can return with page locked | ||
21 | access: no yes | ||
22 | |||
23 | - ->page_mkwrite() is called when a previously read-only page is | ||
24 | -about to become writeable. The file system is responsible for | ||
25 | -protecting against truncate races. Once appropriate action has been | ||
26 | -taking to lock out truncate, the page range should be verified to be | ||
27 | -within i_size. The page mapping should also be checked that it is not | ||
28 | -NULL. | ||
29 | + ->fault() is called when a previously not present pte is about | ||
30 | +to be faulted in. The filesystem must find and return the page associated | ||
31 | +with the passed in "pgoff" in the vm_fault structure. If it is possible that | ||
32 | +the page may be truncated and/or invalidated, then the filesystem must lock | ||
33 | +the page, then ensure it is not already truncated (the page lock will block | ||
34 | +subsequent truncate), and then return with VM_FAULT_LOCKED, and the page | ||
35 | +locked. The VM will unlock the page. | ||
36 | + | ||
37 | + ->page_mkwrite() is called when a previously read-only pte is | ||
38 | +about to become writeable. The filesystem again must ensure that there are | ||
39 | +no truncate/invalidate races, and then return with the page locked. If | ||
40 | +the page has been truncated, the filesystem should not look up a new page | ||
41 | +like the ->fault() handler, but simply return with VM_FAULT_NOPAGE, which | ||
42 | +will cause the VM to retry the fault. | ||
43 | |||
44 | ->access() is called when get_user_pages() fails in | ||
45 | acces_process_vm(), typically used to debug a process through | ||
46 | diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c | ||
47 | index eb8f72c..0e034a4 100644 | ||
48 | --- a/drivers/i2c/algos/i2c-algo-bit.c | ||
49 | +++ b/drivers/i2c/algos/i2c-algo-bit.c | ||
50 | @@ -104,7 +104,7 @@ static int sclhi(struct i2c_algo_bit_data *adap) | ||
51 | * chips may hold it low ("clock stretching") while they | ||
52 | * are processing data internally. | ||
53 | */ | ||
54 | - if (time_after_eq(jiffies, start + adap->timeout)) | ||
55 | + if (time_after(jiffies, start + adap->timeout)) | ||
56 | return -ETIMEDOUT; | ||
57 | cond_resched(); | ||
58 | } | ||
59 | diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c | ||
60 | index d50b329..2346a89 100644 | ||
61 | --- a/drivers/i2c/algos/i2c-algo-pca.c | ||
62 | +++ b/drivers/i2c/algos/i2c-algo-pca.c | ||
63 | @@ -270,10 +270,21 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, | ||
64 | |||
65 | case 0x30: /* Data byte in I2CDAT has been transmitted; NOT ACK has been received */ | ||
66 | DEB2("NOT ACK received after data byte\n"); | ||
67 | + pca_stop(adap); | ||
68 | goto out; | ||
69 | |||
70 | case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */ | ||
71 | DEB2("Arbitration lost\n"); | ||
72 | + /* | ||
73 | + * The PCA9564 data sheet (2006-09-01) says "A | ||
74 | + * START condition will be transmitted when the | ||
75 | + * bus becomes free (STOP or SCL and SDA high)" | ||
76 | + * when the STA bit is set (p. 11). | ||
77 | + * | ||
78 | + * In case this won't work, try pca_reset() | ||
79 | + * instead. | ||
80 | + */ | ||
81 | + pca_start(adap); | ||
82 | goto out; | ||
83 | |||
84 | case 0x58: /* Data byte has been received; NOT ACK has been returned */ | ||
85 | diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c | ||
86 | index 666b7ba..8c50857 100644 | ||
87 | --- a/drivers/md/bitmap.c | ||
88 | +++ b/drivers/md/bitmap.c | ||
89 | @@ -986,6 +986,9 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | ||
90 | oldindex = index; | ||
91 | oldpage = page; | ||
92 | |||
93 | + bitmap->filemap[bitmap->file_pages++] = page; | ||
94 | + bitmap->last_page_size = count; | ||
95 | + | ||
96 | if (outofdate) { | ||
97 | /* | ||
98 | * if bitmap is out of date, dirty the | ||
99 | @@ -998,15 +1001,9 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | ||
100 | write_page(bitmap, page, 1); | ||
101 | |||
102 | ret = -EIO; | ||
103 | - if (bitmap->flags & BITMAP_WRITE_ERROR) { | ||
104 | - /* release, page not in filemap yet */ | ||
105 | - put_page(page); | ||
106 | + if (bitmap->flags & BITMAP_WRITE_ERROR) | ||
107 | goto err; | ||
108 | - } | ||
109 | } | ||
110 | - | ||
111 | - bitmap->filemap[bitmap->file_pages++] = page; | ||
112 | - bitmap->last_page_size = count; | ||
113 | } | ||
114 | paddr = kmap_atomic(page, KM_USER0); | ||
115 | if (bitmap->flags & BITMAP_HOSTENDIAN) | ||
116 | @@ -1016,9 +1013,11 @@ static int bitmap_init_from_disk(struct bitmap *bitmap, sector_t start) | ||
117 | kunmap_atomic(paddr, KM_USER0); | ||
118 | if (b) { | ||
119 | /* if the disk bit is set, set the memory bit */ | ||
120 | - bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap), | ||
121 | - ((i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) >= start) | ||
122 | - ); | ||
123 | + int needed = ((sector_t)(i+1) << (CHUNK_BLOCK_SHIFT(bitmap)) | ||
124 | + >= start); | ||
125 | + bitmap_set_memory_bits(bitmap, | ||
126 | + (sector_t)i << CHUNK_BLOCK_SHIFT(bitmap), | ||
127 | + needed); | ||
128 | bit_cnt++; | ||
129 | set_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); | ||
130 | } | ||
131 | @@ -1154,8 +1153,9 @@ void bitmap_daemon_work(struct bitmap *bitmap) | ||
132 | spin_lock_irqsave(&bitmap->lock, flags); | ||
133 | clear_page_attr(bitmap, page, BITMAP_PAGE_CLEAN); | ||
134 | } | ||
135 | - bmc = bitmap_get_counter(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap), | ||
136 | - &blocks, 0); | ||
137 | + bmc = bitmap_get_counter(bitmap, | ||
138 | + (sector_t)j << CHUNK_BLOCK_SHIFT(bitmap), | ||
139 | + &blocks, 0); | ||
140 | if (bmc) { | ||
141 | /* | ||
142 | if (j < 100) printk("bitmap: j=%lu, *bmc = 0x%x\n", j, *bmc); | ||
143 | @@ -1169,7 +1169,8 @@ void bitmap_daemon_work(struct bitmap *bitmap) | ||
144 | } else if (*bmc == 1) { | ||
145 | /* we can clear the bit */ | ||
146 | *bmc = 0; | ||
147 | - bitmap_count_page(bitmap, j << CHUNK_BLOCK_SHIFT(bitmap), | ||
148 | + bitmap_count_page(bitmap, | ||
149 | + (sector_t)j << CHUNK_BLOCK_SHIFT(bitmap), | ||
150 | -1); | ||
151 | |||
152 | /* clear the bit */ | ||
153 | @@ -1485,7 +1486,7 @@ void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e) | ||
154 | unsigned long chunk; | ||
155 | |||
156 | for (chunk = s; chunk <= e; chunk++) { | ||
157 | - sector_t sec = chunk << CHUNK_BLOCK_SHIFT(bitmap); | ||
158 | + sector_t sec = (sector_t)chunk << CHUNK_BLOCK_SHIFT(bitmap); | ||
159 | bitmap_set_memory_bits(bitmap, sec, 1); | ||
160 | bitmap_file_set_bit(bitmap, sec); | ||
161 | } | ||
162 | diff --git a/drivers/md/md.c b/drivers/md/md.c | ||
163 | index 60f3e59..ebbc3bb 100644 | ||
164 | --- a/drivers/md/md.c | ||
165 | +++ b/drivers/md/md.c | ||
166 | @@ -2772,11 +2772,8 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | ||
167 | } else | ||
168 | err = -EBUSY; | ||
169 | spin_unlock_irq(&mddev->write_lock); | ||
170 | - } else { | ||
171 | - mddev->ro = 0; | ||
172 | - mddev->recovery_cp = MaxSector; | ||
173 | - err = do_md_run(mddev); | ||
174 | - } | ||
175 | + } else | ||
176 | + err = -EINVAL; | ||
177 | break; | ||
178 | case active: | ||
179 | if (mddev->pers) { | ||
180 | diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c | ||
181 | index dc50f98..b08dd95 100644 | ||
182 | --- a/drivers/md/raid10.c | ||
183 | +++ b/drivers/md/raid10.c | ||
184 | @@ -1805,17 +1805,17 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | ||
185 | r10_bio->sector = sect; | ||
186 | |||
187 | raid10_find_phys(conf, r10_bio); | ||
188 | - /* Need to check if this section will still be | ||
189 | + | ||
190 | + /* Need to check if the array will still be | ||
191 | * degraded | ||
192 | */ | ||
193 | - for (j=0; j<conf->copies;j++) { | ||
194 | - int d = r10_bio->devs[j].devnum; | ||
195 | - if (conf->mirrors[d].rdev == NULL || | ||
196 | - test_bit(Faulty, &conf->mirrors[d].rdev->flags)) { | ||
197 | + for (j=0; j<conf->raid_disks; j++) | ||
198 | + if (conf->mirrors[j].rdev == NULL || | ||
199 | + test_bit(Faulty, &conf->mirrors[j].rdev->flags)) { | ||
200 | still_degraded = 1; | ||
201 | break; | ||
202 | } | ||
203 | - } | ||
204 | + | ||
205 | must_sync = bitmap_start_sync(mddev->bitmap, sect, | ||
206 | &sync_blocks, still_degraded); | ||
207 | |||
208 | diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c | ||
209 | index b70c531..a6e730f 100644 | ||
210 | --- a/drivers/net/ehea/ehea_main.c | ||
211 | +++ b/drivers/net/ehea/ehea_main.c | ||
212 | @@ -529,14 +529,17 @@ static inline struct sk_buff *get_skb_by_index(struct sk_buff **skb_array, | ||
213 | x &= (arr_len - 1); | ||
214 | |||
215 | pref = skb_array[x]; | ||
216 | - prefetchw(pref); | ||
217 | - prefetchw(pref + EHEA_CACHE_LINE); | ||
218 | - | ||
219 | - pref = (skb_array[x]->data); | ||
220 | - prefetch(pref); | ||
221 | - prefetch(pref + EHEA_CACHE_LINE); | ||
222 | - prefetch(pref + EHEA_CACHE_LINE * 2); | ||
223 | - prefetch(pref + EHEA_CACHE_LINE * 3); | ||
224 | + if (pref) { | ||
225 | + prefetchw(pref); | ||
226 | + prefetchw(pref + EHEA_CACHE_LINE); | ||
227 | + | ||
228 | + pref = (skb_array[x]->data); | ||
229 | + prefetch(pref); | ||
230 | + prefetch(pref + EHEA_CACHE_LINE); | ||
231 | + prefetch(pref + EHEA_CACHE_LINE * 2); | ||
232 | + prefetch(pref + EHEA_CACHE_LINE * 3); | ||
233 | + } | ||
234 | + | ||
235 | skb = skb_array[skb_index]; | ||
236 | skb_array[skb_index] = NULL; | ||
237 | return skb; | ||
238 | @@ -553,12 +556,14 @@ static inline struct sk_buff *get_skb_by_index_ll(struct sk_buff **skb_array, | ||
239 | x &= (arr_len - 1); | ||
240 | |||
241 | pref = skb_array[x]; | ||
242 | - prefetchw(pref); | ||
243 | - prefetchw(pref + EHEA_CACHE_LINE); | ||
244 | + if (pref) { | ||
245 | + prefetchw(pref); | ||
246 | + prefetchw(pref + EHEA_CACHE_LINE); | ||
247 | |||
248 | - pref = (skb_array[x]->data); | ||
249 | - prefetchw(pref); | ||
250 | - prefetchw(pref + EHEA_CACHE_LINE); | ||
251 | + pref = (skb_array[x]->data); | ||
252 | + prefetchw(pref); | ||
253 | + prefetchw(pref + EHEA_CACHE_LINE); | ||
254 | + } | ||
255 | |||
256 | skb = skb_array[wqe_index]; | ||
257 | skb_array[wqe_index] = NULL; | ||
258 | diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c | ||
259 | index 3612607..32e7acb 100644 | ||
260 | --- a/drivers/serial/mpc52xx_uart.c | ||
261 | +++ b/drivers/serial/mpc52xx_uart.c | ||
262 | @@ -515,7 +515,7 @@ mpc52xx_uart_startup(struct uart_port *port) | ||
263 | |||
264 | /* Request IRQ */ | ||
265 | ret = request_irq(port->irq, mpc52xx_uart_int, | ||
266 | - IRQF_DISABLED | IRQF_SAMPLE_RANDOM | IRQF_SHARED, | ||
267 | + IRQF_DISABLED | IRQF_SAMPLE_RANDOM, | ||
268 | "mpc52xx_psc_uart", port); | ||
269 | if (ret) | ||
270 | return ret; | ||
271 | diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c | ||
272 | index 4154be3..58c4d37 100644 | ||
273 | --- a/drivers/usb/gadget/usbstring.c | ||
274 | +++ b/drivers/usb/gadget/usbstring.c | ||
275 | @@ -38,7 +38,7 @@ static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len) | ||
276 | uchar = (c & 0x1f) << 6; | ||
277 | |||
278 | c = (u8) *s++; | ||
279 | - if ((c & 0xc0) != 0xc0) | ||
280 | + if ((c & 0xc0) != 0x80) | ||
281 | goto fail; | ||
282 | c &= 0x3f; | ||
283 | uchar |= c; | ||
284 | @@ -49,13 +49,13 @@ static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len) | ||
285 | uchar = (c & 0x0f) << 12; | ||
286 | |||
287 | c = (u8) *s++; | ||
288 | - if ((c & 0xc0) != 0xc0) | ||
289 | + if ((c & 0xc0) != 0x80) | ||
290 | goto fail; | ||
291 | c &= 0x3f; | ||
292 | uchar |= c << 6; | ||
293 | |||
294 | c = (u8) *s++; | ||
295 | - if ((c & 0xc0) != 0xc0) | ||
296 | + if ((c & 0xc0) != 0x80) | ||
297 | goto fail; | ||
298 | c &= 0x3f; | ||
299 | uchar |= c; | ||
300 | diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c | ||
301 | index 4835bdc..d1c3cba 100644 | ||
302 | --- a/drivers/video/fb_defio.c | ||
303 | +++ b/drivers/video/fb_defio.c | ||
304 | @@ -70,8 +70,9 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_fsync); | ||
305 | |||
306 | /* vm_ops->page_mkwrite handler */ | ||
307 | static int fb_deferred_io_mkwrite(struct vm_area_struct *vma, | ||
308 | - struct page *page) | ||
309 | + struct vm_fault *vmf) | ||
310 | { | ||
311 | + struct page *page = vmf->page; | ||
312 | struct fb_info *info = vma->vm_private_data; | ||
313 | struct fb_deferred_io *fbdefio = info->fbdefio; | ||
314 | struct page *cur; | ||
315 | diff --git a/fs/buffer.c b/fs/buffer.c | ||
316 | index a5d806d..abe9640 100644 | ||
317 | --- a/fs/buffer.c | ||
318 | +++ b/fs/buffer.c | ||
319 | @@ -2402,20 +2402,22 @@ int block_commit_write(struct page *page, unsigned from, unsigned to) | ||
320 | * unlock the page. | ||
321 | */ | ||
322 | int | ||
323 | -block_page_mkwrite(struct vm_area_struct *vma, struct page *page, | ||
324 | +block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | ||
325 | get_block_t get_block) | ||
326 | { | ||
327 | + struct page *page = vmf->page; | ||
328 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | ||
329 | unsigned long end; | ||
330 | loff_t size; | ||
331 | - int ret = -EINVAL; | ||
332 | + int ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */ | ||
333 | |||
334 | lock_page(page); | ||
335 | size = i_size_read(inode); | ||
336 | if ((page->mapping != inode->i_mapping) || | ||
337 | (page_offset(page) > size)) { | ||
338 | /* page got truncated out from underneath us */ | ||
339 | - goto out_unlock; | ||
340 | + unlock_page(page); | ||
341 | + goto out; | ||
342 | } | ||
343 | |||
344 | /* page is wholly or partially inside EOF */ | ||
345 | @@ -2428,8 +2430,16 @@ block_page_mkwrite(struct vm_area_struct *vma, struct page *page, | ||
346 | if (!ret) | ||
347 | ret = block_commit_write(page, 0, end); | ||
348 | |||
349 | -out_unlock: | ||
350 | - unlock_page(page); | ||
351 | + if (unlikely(ret)) { | ||
352 | + unlock_page(page); | ||
353 | + if (ret == -ENOMEM) | ||
354 | + ret = VM_FAULT_OOM; | ||
355 | + else /* -ENOSPC, -EIO, etc */ | ||
356 | + ret = VM_FAULT_SIGBUS; | ||
357 | + } else | ||
358 | + ret = VM_FAULT_LOCKED; | ||
359 | + | ||
360 | +out: | ||
361 | return ret; | ||
362 | } | ||
363 | |||
364 | diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h | ||
365 | index 14eb9a2..604ce8a 100644 | ||
366 | --- a/fs/cifs/cifs_unicode.h | ||
367 | +++ b/fs/cifs/cifs_unicode.h | ||
368 | @@ -64,6 +64,13 @@ int cifs_strtoUCS(__le16 *, const char *, int, const struct nls_table *); | ||
369 | #endif | ||
370 | |||
371 | /* | ||
372 | + * To be safe - for UCS to UTF-8 with strings loaded with the rare long | ||
373 | + * characters alloc more to account for such multibyte target UTF-8 | ||
374 | + * characters. | ||
375 | + */ | ||
376 | +#define UNICODE_NAME_MAX ((4 * NAME_MAX) + 2) | ||
377 | + | ||
378 | +/* | ||
379 | * UniStrcat: Concatenate the second string to the first | ||
380 | * | ||
381 | * Returns: | ||
382 | diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c | ||
383 | index 9231e0a..cff0c53 100644 | ||
384 | --- a/fs/cifs/cifssmb.c | ||
385 | +++ b/fs/cifs/cifssmb.c | ||
386 | @@ -91,23 +91,22 @@ static int | ||
387 | cifs_strncpy_to_host(char **dst, const char *src, const int maxlen, | ||
388 | const bool is_unicode, const struct nls_table *nls_codepage) | ||
389 | { | ||
390 | - int plen; | ||
391 | + int src_len, dst_len; | ||
392 | |||
393 | if (is_unicode) { | ||
394 | - plen = UniStrnlen((wchar_t *)src, maxlen); | ||
395 | - *dst = kmalloc(plen + 2, GFP_KERNEL); | ||
396 | + src_len = UniStrnlen((wchar_t *)src, maxlen); | ||
397 | + *dst = kmalloc((4 * src_len) + 2, GFP_KERNEL); | ||
398 | if (!*dst) | ||
399 | goto cifs_strncpy_to_host_ErrExit; | ||
400 | - cifs_strfromUCS_le(*dst, (__le16 *)src, plen, nls_codepage); | ||
401 | + dst_len = cifs_strfromUCS_le(*dst, (__le16 *)src, src_len, nls_codepage); | ||
402 | + (*dst)[dst_len + 1] = 0; | ||
403 | } else { | ||
404 | - plen = strnlen(src, maxlen); | ||
405 | - *dst = kmalloc(plen + 2, GFP_KERNEL); | ||
406 | + src_len = strnlen(src, maxlen); | ||
407 | + *dst = kmalloc(src_len + 1, GFP_KERNEL); | ||
408 | if (!*dst) | ||
409 | goto cifs_strncpy_to_host_ErrExit; | ||
410 | - strncpy(*dst, src, plen); | ||
411 | + strlcpy(*dst, src, src_len + 1); | ||
412 | } | ||
413 | - (*dst)[plen] = 0; | ||
414 | - (*dst)[plen+1] = 0; /* harmless for ASCII case, needed for Unicode */ | ||
415 | return 0; | ||
416 | |||
417 | cifs_strncpy_to_host_ErrExit: | ||
418 | diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c | ||
419 | index 21a1abf..d059b3f 100644 | ||
420 | --- a/fs/cifs/connect.c | ||
421 | +++ b/fs/cifs/connect.c | ||
422 | @@ -3549,16 +3549,12 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | ||
423 | BCC(smb_buffer_response)) { | ||
424 | kfree(tcon->nativeFileSystem); | ||
425 | tcon->nativeFileSystem = | ||
426 | - kzalloc(2*(length + 1), GFP_KERNEL); | ||
427 | + kzalloc((4 * length) + 2, GFP_KERNEL); | ||
428 | if (tcon->nativeFileSystem) | ||
429 | cifs_strfromUCS_le( | ||
430 | tcon->nativeFileSystem, | ||
431 | (__le16 *) bcc_ptr, | ||
432 | length, nls_codepage); | ||
433 | - bcc_ptr += 2 * length; | ||
434 | - bcc_ptr[0] = 0; /* null terminate the string */ | ||
435 | - bcc_ptr[1] = 0; | ||
436 | - bcc_ptr += 2; | ||
437 | } | ||
438 | /* else do not bother copying these information fields*/ | ||
439 | } else { | ||
440 | diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c | ||
441 | index b891553..6205593 100644 | ||
442 | --- a/fs/cifs/misc.c | ||
443 | +++ b/fs/cifs/misc.c | ||
444 | @@ -685,14 +685,15 @@ cifs_convertUCSpath(char *target, const __le16 *source, int maxlen, | ||
445 | NLS_MAX_CHARSET_SIZE); | ||
446 | if (len > 0) { | ||
447 | j += len; | ||
448 | - continue; | ||
449 | + goto overrun_chk; | ||
450 | } else { | ||
451 | target[j] = '?'; | ||
452 | } | ||
453 | } | ||
454 | j++; | ||
455 | /* make sure we do not overrun callers allocated temp buffer */ | ||
456 | - if (j >= (2 * NAME_MAX)) | ||
457 | +overrun_chk: | ||
458 | + if (j >= UNICODE_NAME_MAX) | ||
459 | break; | ||
460 | } | ||
461 | cUCS_out: | ||
462 | diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c | ||
463 | index 58d5729..2878892 100644 | ||
464 | --- a/fs/cifs/readdir.c | ||
465 | +++ b/fs/cifs/readdir.c | ||
466 | @@ -1075,7 +1075,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | ||
467 | with the rare long characters alloc more to account for | ||
468 | such multibyte target UTF-8 characters. cifs_unicode.c, | ||
469 | which actually does the conversion, has the same limit */ | ||
470 | - tmp_buf = kmalloc((2 * NAME_MAX) + 4, GFP_KERNEL); | ||
471 | + tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL); | ||
472 | for (i = 0; (i < num_to_fill) && (rc == 0); i++) { | ||
473 | if (current_entry == NULL) { | ||
474 | /* evaluate whether this case is an error */ | ||
475 | diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c | ||
476 | index 89fac77..3890cc2 100644 | ||
477 | --- a/fs/cifs/sess.c | ||
478 | +++ b/fs/cifs/sess.c | ||
479 | @@ -202,27 +202,26 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, | ||
480 | int words_left, len; | ||
481 | char *data = *pbcc_area; | ||
482 | |||
483 | - | ||
484 | - | ||
485 | cFYI(1, ("bleft %d", bleft)); | ||
486 | |||
487 | - | ||
488 | - /* SMB header is unaligned, so cifs servers word align start of | ||
489 | - Unicode strings */ | ||
490 | - data++; | ||
491 | - bleft--; /* Windows servers do not always double null terminate | ||
492 | - their final Unicode string - in which case we | ||
493 | - now will not attempt to decode the byte of junk | ||
494 | - which follows it */ | ||
495 | + /* | ||
496 | + * Windows servers do not always double null terminate their final | ||
497 | + * Unicode string. Check to see if there are an uneven number of bytes | ||
498 | + * left. If so, then add an extra NULL pad byte to the end of the | ||
499 | + * response. | ||
500 | + * | ||
501 | + * See section 2.7.2 in "Implementing CIFS" for details | ||
502 | + */ | ||
503 | + if (bleft % 2) { | ||
504 | + data[bleft] = 0; | ||
505 | + ++bleft; | ||
506 | + } | ||
507 | |||
508 | words_left = bleft / 2; | ||
509 | |||
510 | /* save off server operating system */ | ||
511 | len = UniStrnlen((wchar_t *) data, words_left); | ||
512 | |||
513 | -/* We look for obvious messed up bcc or strings in response so we do not go off | ||
514 | - the end since (at least) WIN2K and Windows XP have a major bug in not null | ||
515 | - terminating last Unicode string in response */ | ||
516 | if (len >= words_left) | ||
517 | return rc; | ||
518 | |||
519 | @@ -260,13 +259,10 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, | ||
520 | return rc; | ||
521 | |||
522 | kfree(ses->serverDomain); | ||
523 | - ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */ | ||
524 | - if (ses->serverDomain != NULL) { | ||
525 | + ses->serverDomain = kzalloc((4 * len) + 2, GFP_KERNEL); | ||
526 | + if (ses->serverDomain != NULL) | ||
527 | cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len, | ||
528 | nls_cp); | ||
529 | - ses->serverDomain[2*len] = 0; | ||
530 | - ses->serverDomain[(2*len) + 1] = 0; | ||
531 | - } | ||
532 | data += 2 * (len + 1); | ||
533 | words_left -= len + 1; | ||
534 | |||
535 | @@ -616,12 +612,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | ||
536 | } | ||
537 | |||
538 | /* BB check if Unicode and decode strings */ | ||
539 | - if (smb_buf->Flags2 & SMBFLG2_UNICODE) | ||
540 | + if (smb_buf->Flags2 & SMBFLG2_UNICODE) { | ||
541 | + /* unicode string area must be word-aligned */ | ||
542 | + if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) { | ||
543 | + ++bcc_ptr; | ||
544 | + --bytes_remaining; | ||
545 | + } | ||
546 | rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining, | ||
547 | - ses, nls_cp); | ||
548 | - else | ||
549 | + ses, nls_cp); | ||
550 | + } else { | ||
551 | rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, | ||
552 | ses, nls_cp); | ||
553 | + } | ||
554 | |||
555 | ssetup_exit: | ||
556 | if (spnego_key) | ||
557 | diff --git a/fs/eventpoll.c b/fs/eventpoll.c | ||
558 | index 801de2c..fd5835b 100644 | ||
559 | --- a/fs/eventpoll.c | ||
560 | +++ b/fs/eventpoll.c | ||
561 | @@ -1132,7 +1132,7 @@ error_return: | ||
562 | |||
563 | SYSCALL_DEFINE1(epoll_create, int, size) | ||
564 | { | ||
565 | - if (size < 0) | ||
566 | + if (size <= 0) | ||
567 | return -EINVAL; | ||
568 | |||
569 | return sys_epoll_create1(0); | ||
570 | diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h | ||
571 | index f613d57..eadbee3 100644 | ||
572 | --- a/fs/ext4/ext4.h | ||
573 | +++ b/fs/ext4/ext4.h | ||
574 | @@ -1084,7 +1084,7 @@ extern int ext4_meta_trans_blocks(struct inode *, int nrblocks, int idxblocks); | ||
575 | extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks); | ||
576 | extern int ext4_block_truncate_page(handle_t *handle, | ||
577 | struct address_space *mapping, loff_t from); | ||
578 | -extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page); | ||
579 | +extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); | ||
580 | |||
581 | /* ioctl.c */ | ||
582 | extern long ext4_ioctl(struct file *, unsigned int, unsigned long); | ||
583 | diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c | ||
584 | index b233ade..63b911b 100644 | ||
585 | --- a/fs/ext4/inode.c | ||
586 | +++ b/fs/ext4/inode.c | ||
587 | @@ -4861,8 +4861,9 @@ static int ext4_bh_unmapped(handle_t *handle, struct buffer_head *bh) | ||
588 | return !buffer_mapped(bh); | ||
589 | } | ||
590 | |||
591 | -int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page) | ||
592 | +int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | ||
593 | { | ||
594 | + struct page *page = vmf->page; | ||
595 | loff_t size; | ||
596 | unsigned long len; | ||
597 | int ret = -EINVAL; | ||
598 | @@ -4913,6 +4914,8 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page) | ||
599 | goto out_unlock; | ||
600 | ret = 0; | ||
601 | out_unlock: | ||
602 | + if (ret) | ||
603 | + ret = VM_FAULT_SIGBUS; | ||
604 | up_read(&inode->i_alloc_sem); | ||
605 | return ret; | ||
606 | } | ||
607 | diff --git a/fs/fcntl.c b/fs/fcntl.c | ||
608 | index 08a109b..ac79b7e 100644 | ||
609 | --- a/fs/fcntl.c | ||
610 | +++ b/fs/fcntl.c | ||
611 | @@ -117,11 +117,13 @@ SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd) | ||
612 | { | ||
613 | if (unlikely(newfd == oldfd)) { /* corner case */ | ||
614 | struct files_struct *files = current->files; | ||
615 | + int retval = oldfd; | ||
616 | + | ||
617 | rcu_read_lock(); | ||
618 | if (!fcheck_files(files, oldfd)) | ||
619 | - oldfd = -EBADF; | ||
620 | + retval = -EBADF; | ||
621 | rcu_read_unlock(); | ||
622 | - return oldfd; | ||
623 | + return retval; | ||
624 | } | ||
625 | return sys_dup3(oldfd, newfd, 0); | ||
626 | } | ||
627 | diff --git a/fs/fuse/file.c b/fs/fuse/file.c | ||
628 | index 3ada9d7..0c92f15 100644 | ||
629 | --- a/fs/fuse/file.c | ||
630 | +++ b/fs/fuse/file.c | ||
631 | @@ -1219,8 +1219,9 @@ static void fuse_vma_close(struct vm_area_struct *vma) | ||
632 | * - sync(2) | ||
633 | * - try_to_free_pages() with order > PAGE_ALLOC_COSTLY_ORDER | ||
634 | */ | ||
635 | -static int fuse_page_mkwrite(struct vm_area_struct *vma, struct page *page) | ||
636 | +static int fuse_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | ||
637 | { | ||
638 | + struct page *page = vmf->page; | ||
639 | /* | ||
640 | * Don't use page->mapping as it may become NULL from a | ||
641 | * concurrent truncate. | ||
642 | diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c | ||
643 | index e9a366d..641c43b 100644 | ||
644 | --- a/fs/gfs2/ops_file.c | ||
645 | +++ b/fs/gfs2/ops_file.c | ||
646 | @@ -338,8 +338,9 @@ static int gfs2_allocate_page_backing(struct page *page) | ||
647 | * blocks allocated on disk to back that page. | ||
648 | */ | ||
649 | |||
650 | -static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) | ||
651 | +static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | ||
652 | { | ||
653 | + struct page *page = vmf->page; | ||
654 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | ||
655 | struct gfs2_inode *ip = GFS2_I(inode); | ||
656 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
657 | @@ -411,6 +412,10 @@ out_unlock: | ||
658 | gfs2_glock_dq(&gh); | ||
659 | out: | ||
660 | gfs2_holder_uninit(&gh); | ||
661 | + if (ret == -ENOMEM) | ||
662 | + ret = VM_FAULT_OOM; | ||
663 | + else if (ret) | ||
664 | + ret = VM_FAULT_SIGBUS; | ||
665 | return ret; | ||
666 | } | ||
667 | |||
668 | diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c | ||
669 | index 74f92b7..bff8733 100644 | ||
670 | --- a/fs/nfs/dir.c | ||
671 | +++ b/fs/nfs/dir.c | ||
672 | @@ -1613,8 +1613,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry, | ||
673 | } else if (atomic_read(&new_dentry->d_count) > 1) | ||
674 | /* dentry still busy? */ | ||
675 | goto out; | ||
676 | - } else | ||
677 | - nfs_drop_nlink(new_inode); | ||
678 | + } | ||
679 | |||
680 | go_ahead: | ||
681 | /* | ||
682 | @@ -1627,10 +1626,8 @@ go_ahead: | ||
683 | } | ||
684 | nfs_inode_return_delegation(old_inode); | ||
685 | |||
686 | - if (new_inode != NULL) { | ||
687 | + if (new_inode != NULL) | ||
688 | nfs_inode_return_delegation(new_inode); | ||
689 | - d_delete(new_dentry); | ||
690 | - } | ||
691 | |||
692 | error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name, | ||
693 | new_dir, &new_dentry->d_name); | ||
694 | @@ -1639,6 +1636,8 @@ out: | ||
695 | if (rehash) | ||
696 | d_rehash(rehash); | ||
697 | if (!error) { | ||
698 | + if (new_inode != NULL) | ||
699 | + nfs_drop_nlink(new_inode); | ||
700 | d_move(old_dentry, new_dentry); | ||
701 | nfs_set_verifier(new_dentry, | ||
702 | nfs_save_change_attribute(new_dir)); | ||
703 | diff --git a/fs/nfs/file.c b/fs/nfs/file.c | ||
704 | index 30541f0..4a57a0f 100644 | ||
705 | --- a/fs/nfs/file.c | ||
706 | +++ b/fs/nfs/file.c | ||
707 | @@ -448,8 +448,9 @@ const struct address_space_operations nfs_file_aops = { | ||
708 | .launder_page = nfs_launder_page, | ||
709 | }; | ||
710 | |||
711 | -static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) | ||
712 | +static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | ||
713 | { | ||
714 | + struct page *page = vmf->page; | ||
715 | struct file *filp = vma->vm_file; | ||
716 | struct dentry *dentry = filp->f_path.dentry; | ||
717 | unsigned pagelen; | ||
718 | @@ -476,11 +477,11 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) | ||
719 | goto out_unlock; | ||
720 | |||
721 | ret = nfs_updatepage(filp, page, 0, pagelen); | ||
722 | - if (ret == 0) | ||
723 | - ret = pagelen; | ||
724 | out_unlock: | ||
725 | + if (!ret) | ||
726 | + return VM_FAULT_LOCKED; | ||
727 | unlock_page(page); | ||
728 | - return ret; | ||
729 | + return VM_FAULT_SIGBUS; | ||
730 | } | ||
731 | |||
732 | static struct vm_operations_struct nfs_file_vm_ops = { | ||
733 | diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c | ||
734 | index b0b07df..abffc90 100644 | ||
735 | --- a/fs/nfsd/nfs4xdr.c | ||
736 | +++ b/fs/nfsd/nfs4xdr.c | ||
737 | @@ -1833,6 +1833,15 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, | ||
738 | dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen); | ||
739 | if (IS_ERR(dentry)) | ||
740 | return nfserrno(PTR_ERR(dentry)); | ||
741 | + if (!dentry->d_inode) { | ||
742 | + /* | ||
743 | + * nfsd_buffered_readdir drops the i_mutex between | ||
744 | + * readdir and calling this callback, leaving a window | ||
745 | + * where this directory entry could have gone away. | ||
746 | + */ | ||
747 | + dput(dentry); | ||
748 | + return nfserr_noent; | ||
749 | + } | ||
750 | |||
751 | exp_get(exp); | ||
752 | /* | ||
753 | @@ -1895,6 +1904,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | ||
754 | struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); | ||
755 | int buflen; | ||
756 | __be32 *p = cd->buffer; | ||
757 | + __be32 *cookiep; | ||
758 | __be32 nfserr = nfserr_toosmall; | ||
759 | |||
760 | /* In nfsv4, "." and ".." never make it onto the wire.. */ | ||
761 | @@ -1911,7 +1921,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | ||
762 | goto fail; | ||
763 | |||
764 | *p++ = xdr_one; /* mark entry present */ | ||
765 | - cd->offset = p; /* remember pointer */ | ||
766 | + cookiep = p; | ||
767 | p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */ | ||
768 | p = xdr_encode_array(p, name, namlen); /* name length & name */ | ||
769 | |||
770 | @@ -1925,6 +1935,8 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | ||
771 | goto fail; | ||
772 | case nfserr_dropit: | ||
773 | goto fail; | ||
774 | + case nfserr_noent: | ||
775 | + goto skip_entry; | ||
776 | default: | ||
777 | /* | ||
778 | * If the client requested the RDATTR_ERROR attribute, | ||
779 | @@ -1943,6 +1955,8 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, | ||
780 | } | ||
781 | cd->buflen -= (p - cd->buffer); | ||
782 | cd->buffer = p; | ||
783 | + cd->offset = cookiep; | ||
784 | +skip_entry: | ||
785 | cd->common.err = nfs_ok; | ||
786 | return 0; | ||
787 | fail: | ||
788 | diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c | ||
789 | index 6f7ea0a..08af0ed 100644 | ||
790 | --- a/fs/ocfs2/file.c | ||
791 | +++ b/fs/ocfs2/file.c | ||
792 | @@ -2075,6 +2075,22 @@ out_sems: | ||
793 | return written ? written : ret; | ||
794 | } | ||
795 | |||
796 | +static int ocfs2_splice_to_file(struct pipe_inode_info *pipe, | ||
797 | + struct file *out, | ||
798 | + struct splice_desc *sd) | ||
799 | +{ | ||
800 | + int ret; | ||
801 | + | ||
802 | + ret = ocfs2_prepare_inode_for_write(out->f_path.dentry, &sd->pos, | ||
803 | + sd->total_len, 0, NULL); | ||
804 | + if (ret < 0) { | ||
805 | + mlog_errno(ret); | ||
806 | + return ret; | ||
807 | + } | ||
808 | + | ||
809 | + return splice_from_pipe_feed(pipe, sd, pipe_to_file); | ||
810 | +} | ||
811 | + | ||
812 | static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, | ||
813 | struct file *out, | ||
814 | loff_t *ppos, | ||
815 | @@ -2082,38 +2098,76 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, | ||
816 | unsigned int flags) | ||
817 | { | ||
818 | int ret; | ||
819 | - struct inode *inode = out->f_path.dentry->d_inode; | ||
820 | + struct address_space *mapping = out->f_mapping; | ||
821 | + struct inode *inode = mapping->host; | ||
822 | + struct splice_desc sd = { | ||
823 | + .total_len = len, | ||
824 | + .flags = flags, | ||
825 | + .pos = *ppos, | ||
826 | + .u.file = out, | ||
827 | + }; | ||
828 | |||
829 | mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", out, pipe, | ||
830 | (unsigned int)len, | ||
831 | out->f_path.dentry->d_name.len, | ||
832 | out->f_path.dentry->d_name.name); | ||
833 | |||
834 | - mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); | ||
835 | + if (pipe->inode) | ||
836 | + mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_PARENT); | ||
837 | |||
838 | - ret = ocfs2_rw_lock(inode, 1); | ||
839 | - if (ret < 0) { | ||
840 | - mlog_errno(ret); | ||
841 | - goto out; | ||
842 | - } | ||
843 | + splice_from_pipe_begin(&sd); | ||
844 | + do { | ||
845 | + ret = splice_from_pipe_next(pipe, &sd); | ||
846 | + if (ret <= 0) | ||
847 | + break; | ||
848 | |||
849 | - ret = ocfs2_prepare_inode_for_write(out->f_path.dentry, ppos, len, 0, | ||
850 | - NULL); | ||
851 | - if (ret < 0) { | ||
852 | - mlog_errno(ret); | ||
853 | - goto out_unlock; | ||
854 | - } | ||
855 | + mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); | ||
856 | + ret = ocfs2_rw_lock(inode, 1); | ||
857 | + if (ret < 0) | ||
858 | + mlog_errno(ret); | ||
859 | + else { | ||
860 | + ret = ocfs2_splice_to_file(pipe, out, &sd); | ||
861 | + ocfs2_rw_unlock(inode, 1); | ||
862 | + } | ||
863 | + mutex_unlock(&inode->i_mutex); | ||
864 | + } while (ret > 0); | ||
865 | + splice_from_pipe_end(pipe, &sd); | ||
866 | |||
867 | if (pipe->inode) | ||
868 | - mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD); | ||
869 | - ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags); | ||
870 | - if (pipe->inode) | ||
871 | mutex_unlock(&pipe->inode->i_mutex); | ||
872 | |||
873 | -out_unlock: | ||
874 | - ocfs2_rw_unlock(inode, 1); | ||
875 | -out: | ||
876 | - mutex_unlock(&inode->i_mutex); | ||
877 | + if (sd.num_spliced) | ||
878 | + ret = sd.num_spliced; | ||
879 | + | ||
880 | + if (ret > 0) { | ||
881 | + unsigned long nr_pages; | ||
882 | + | ||
883 | + *ppos += ret; | ||
884 | + nr_pages = (ret + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | ||
885 | + | ||
886 | + /* | ||
887 | + * If file or inode is SYNC and we actually wrote some data, | ||
888 | + * sync it. | ||
889 | + */ | ||
890 | + if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) { | ||
891 | + int err; | ||
892 | + | ||
893 | + mutex_lock(&inode->i_mutex); | ||
894 | + err = ocfs2_rw_lock(inode, 1); | ||
895 | + if (err < 0) { | ||
896 | + mlog_errno(err); | ||
897 | + } else { | ||
898 | + err = generic_osync_inode(inode, mapping, | ||
899 | + OSYNC_METADATA|OSYNC_DATA); | ||
900 | + ocfs2_rw_unlock(inode, 1); | ||
901 | + } | ||
902 | + mutex_unlock(&inode->i_mutex); | ||
903 | + | ||
904 | + if (err) | ||
905 | + ret = err; | ||
906 | + } | ||
907 | + balance_dirty_pages_ratelimited_nr(mapping, nr_pages); | ||
908 | + } | ||
909 | |||
910 | mlog_exit(ret); | ||
911 | return ret; | ||
912 | diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c | ||
913 | index 3dc18d6..2383cbd 100644 | ||
914 | --- a/fs/ocfs2/mmap.c | ||
915 | +++ b/fs/ocfs2/mmap.c | ||
916 | @@ -150,8 +150,9 @@ out: | ||
917 | return ret; | ||
918 | } | ||
919 | |||
920 | -static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) | ||
921 | +static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | ||
922 | { | ||
923 | + struct page *page = vmf->page; | ||
924 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | ||
925 | struct buffer_head *di_bh = NULL; | ||
926 | sigset_t blocked, oldset; | ||
927 | @@ -192,7 +193,8 @@ out: | ||
928 | ret2 = ocfs2_vm_op_unblock_sigs(&oldset); | ||
929 | if (ret2 < 0) | ||
930 | mlog_errno(ret2); | ||
931 | - | ||
932 | + if (ret) | ||
933 | + ret = VM_FAULT_SIGBUS; | ||
934 | return ret; | ||
935 | } | ||
936 | |||
937 | diff --git a/fs/splice.c b/fs/splice.c | ||
938 | index aea1eb4..2f2d8c1 100644 | ||
939 | --- a/fs/splice.c | ||
940 | +++ b/fs/splice.c | ||
941 | @@ -553,8 +553,8 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe, | ||
942 | * SPLICE_F_MOVE isn't set, or we cannot move the page, we simply create | ||
943 | * a new page in the output file page cache and fill/dirty that. | ||
944 | */ | ||
945 | -static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | ||
946 | - struct splice_desc *sd) | ||
947 | +int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | ||
948 | + struct splice_desc *sd) | ||
949 | { | ||
950 | struct file *file = sd->u.file; | ||
951 | struct address_space *mapping = file->f_mapping; | ||
952 | @@ -598,108 +598,178 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | ||
953 | out: | ||
954 | return ret; | ||
955 | } | ||
956 | +EXPORT_SYMBOL(pipe_to_file); | ||
957 | + | ||
958 | +static void wakeup_pipe_writers(struct pipe_inode_info *pipe) | ||
959 | +{ | ||
960 | + smp_mb(); | ||
961 | + if (waitqueue_active(&pipe->wait)) | ||
962 | + wake_up_interruptible(&pipe->wait); | ||
963 | + kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | ||
964 | +} | ||
965 | |||
966 | /** | ||
967 | - * __splice_from_pipe - splice data from a pipe to given actor | ||
968 | + * splice_from_pipe_feed - feed available data from a pipe to a file | ||
969 | * @pipe: pipe to splice from | ||
970 | * @sd: information to @actor | ||
971 | * @actor: handler that splices the data | ||
972 | * | ||
973 | * Description: | ||
974 | - * This function does little more than loop over the pipe and call | ||
975 | - * @actor to do the actual moving of a single struct pipe_buffer to | ||
976 | - * the desired destination. See pipe_to_file, pipe_to_sendpage, or | ||
977 | - * pipe_to_user. | ||
978 | + | ||
979 | + * This function loops over the pipe and calls @actor to do the | ||
980 | + * actual moving of a single struct pipe_buffer to the desired | ||
981 | + * destination. It returns when there's no more buffers left in | ||
982 | + * the pipe or if the requested number of bytes (@sd->total_len) | ||
983 | + * have been copied. It returns a positive number (one) if the | ||
984 | + * pipe needs to be filled with more data, zero if the required | ||
985 | + * number of bytes have been copied and -errno on error. | ||
986 | * | ||
987 | + * This, together with splice_from_pipe_{begin,end,next}, may be | ||
988 | + * used to implement the functionality of __splice_from_pipe() when | ||
989 | + * locking is required around copying the pipe buffers to the | ||
990 | + * destination. | ||
991 | */ | ||
992 | -ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd, | ||
993 | - splice_actor *actor) | ||
994 | +int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd, | ||
995 | + splice_actor *actor) | ||
996 | { | ||
997 | - int ret, do_wakeup, err; | ||
998 | - | ||
999 | - ret = 0; | ||
1000 | - do_wakeup = 0; | ||
1001 | - | ||
1002 | - for (;;) { | ||
1003 | - if (pipe->nrbufs) { | ||
1004 | - struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; | ||
1005 | - const struct pipe_buf_operations *ops = buf->ops; | ||
1006 | + int ret; | ||
1007 | |||
1008 | - sd->len = buf->len; | ||
1009 | - if (sd->len > sd->total_len) | ||
1010 | - sd->len = sd->total_len; | ||
1011 | + while (pipe->nrbufs) { | ||
1012 | + struct pipe_buffer *buf = pipe->bufs + pipe->curbuf; | ||
1013 | + const struct pipe_buf_operations *ops = buf->ops; | ||
1014 | |||
1015 | - err = actor(pipe, buf, sd); | ||
1016 | - if (err <= 0) { | ||
1017 | - if (!ret && err != -ENODATA) | ||
1018 | - ret = err; | ||
1019 | + sd->len = buf->len; | ||
1020 | + if (sd->len > sd->total_len) | ||
1021 | + sd->len = sd->total_len; | ||
1022 | |||
1023 | - break; | ||
1024 | - } | ||
1025 | + ret = actor(pipe, buf, sd); | ||
1026 | + if (ret <= 0) { | ||
1027 | + if (ret == -ENODATA) | ||
1028 | + ret = 0; | ||
1029 | + return ret; | ||
1030 | + } | ||
1031 | + buf->offset += ret; | ||
1032 | + buf->len -= ret; | ||
1033 | |||
1034 | - ret += err; | ||
1035 | - buf->offset += err; | ||
1036 | - buf->len -= err; | ||
1037 | + sd->num_spliced += ret; | ||
1038 | + sd->len -= ret; | ||
1039 | + sd->pos += ret; | ||
1040 | + sd->total_len -= ret; | ||
1041 | |||
1042 | - sd->len -= err; | ||
1043 | - sd->pos += err; | ||
1044 | - sd->total_len -= err; | ||
1045 | - if (sd->len) | ||
1046 | - continue; | ||
1047 | + if (!buf->len) { | ||
1048 | + buf->ops = NULL; | ||
1049 | + ops->release(pipe, buf); | ||
1050 | + pipe->curbuf = (pipe->curbuf + 1) & (PIPE_BUFFERS - 1); | ||
1051 | + pipe->nrbufs--; | ||
1052 | + if (pipe->inode) | ||
1053 | + sd->need_wakeup = true; | ||
1054 | + } | ||
1055 | |||
1056 | - if (!buf->len) { | ||
1057 | - buf->ops = NULL; | ||
1058 | - ops->release(pipe, buf); | ||
1059 | - pipe->curbuf = (pipe->curbuf + 1) & (PIPE_BUFFERS - 1); | ||
1060 | - pipe->nrbufs--; | ||
1061 | - if (pipe->inode) | ||
1062 | - do_wakeup = 1; | ||
1063 | - } | ||
1064 | + if (!sd->total_len) | ||
1065 | + return 0; | ||
1066 | + } | ||
1067 | |||
1068 | - if (!sd->total_len) | ||
1069 | - break; | ||
1070 | - } | ||
1071 | + return 1; | ||
1072 | +} | ||
1073 | +EXPORT_SYMBOL(splice_from_pipe_feed); | ||
1074 | |||
1075 | - if (pipe->nrbufs) | ||
1076 | - continue; | ||
1077 | +/** | ||
1078 | + * splice_from_pipe_next - wait for some data to splice from | ||
1079 | + * @pipe: pipe to splice from | ||
1080 | + * @sd: information about the splice operation | ||
1081 | + * | ||
1082 | + * Description: | ||
1083 | + * This function will wait for some data and return a positive | ||
1084 | + * value (one) if pipe buffers are available. It will return zero | ||
1085 | + * or -errno if no more data needs to be spliced. | ||
1086 | + */ | ||
1087 | +int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd) | ||
1088 | +{ | ||
1089 | + while (!pipe->nrbufs) { | ||
1090 | if (!pipe->writers) | ||
1091 | - break; | ||
1092 | - if (!pipe->waiting_writers) { | ||
1093 | - if (ret) | ||
1094 | - break; | ||
1095 | - } | ||
1096 | + return 0; | ||
1097 | |||
1098 | - if (sd->flags & SPLICE_F_NONBLOCK) { | ||
1099 | - if (!ret) | ||
1100 | - ret = -EAGAIN; | ||
1101 | - break; | ||
1102 | - } | ||
1103 | + if (!pipe->waiting_writers && sd->num_spliced) | ||
1104 | + return 0; | ||
1105 | |||
1106 | - if (signal_pending(current)) { | ||
1107 | - if (!ret) | ||
1108 | - ret = -ERESTARTSYS; | ||
1109 | - break; | ||
1110 | - } | ||
1111 | + if (sd->flags & SPLICE_F_NONBLOCK) | ||
1112 | + return -EAGAIN; | ||
1113 | |||
1114 | - if (do_wakeup) { | ||
1115 | - smp_mb(); | ||
1116 | - if (waitqueue_active(&pipe->wait)) | ||
1117 | - wake_up_interruptible_sync(&pipe->wait); | ||
1118 | - kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | ||
1119 | - do_wakeup = 0; | ||
1120 | + if (signal_pending(current)) | ||
1121 | + return -ERESTARTSYS; | ||
1122 | + | ||
1123 | + if (sd->need_wakeup) { | ||
1124 | + wakeup_pipe_writers(pipe); | ||
1125 | + sd->need_wakeup = false; | ||
1126 | } | ||
1127 | |||
1128 | pipe_wait(pipe); | ||
1129 | } | ||
1130 | |||
1131 | - if (do_wakeup) { | ||
1132 | - smp_mb(); | ||
1133 | - if (waitqueue_active(&pipe->wait)) | ||
1134 | - wake_up_interruptible(&pipe->wait); | ||
1135 | - kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT); | ||
1136 | - } | ||
1137 | + return 1; | ||
1138 | +} | ||
1139 | +EXPORT_SYMBOL(splice_from_pipe_next); | ||
1140 | |||
1141 | - return ret; | ||
1142 | +/** | ||
1143 | + * splice_from_pipe_begin - start splicing from pipe | ||
1144 | + * @pipe: pipe to splice from | ||
1145 | + * | ||
1146 | + * Description: | ||
1147 | + * This function should be called before a loop containing | ||
1148 | + * splice_from_pipe_next() and splice_from_pipe_feed() to | ||
1149 | + * initialize the necessary fields of @sd. | ||
1150 | + */ | ||
1151 | +void splice_from_pipe_begin(struct splice_desc *sd) | ||
1152 | +{ | ||
1153 | + sd->num_spliced = 0; | ||
1154 | + sd->need_wakeup = false; | ||
1155 | +} | ||
1156 | +EXPORT_SYMBOL(splice_from_pipe_begin); | ||
1157 | + | ||
1158 | +/** | ||
1159 | + * splice_from_pipe_end - finish splicing from pipe | ||
1160 | + * @pipe: pipe to splice from | ||
1161 | + * @sd: information about the splice operation | ||
1162 | + * | ||
1163 | + * Description: | ||
1164 | + * This function will wake up pipe writers if necessary. It should | ||
1165 | + * be called after a loop containing splice_from_pipe_next() and | ||
1166 | + * splice_from_pipe_feed(). | ||
1167 | + */ | ||
1168 | +void splice_from_pipe_end(struct pipe_inode_info *pipe, struct splice_desc *sd) | ||
1169 | +{ | ||
1170 | + if (sd->need_wakeup) | ||
1171 | + wakeup_pipe_writers(pipe); | ||
1172 | +} | ||
1173 | +EXPORT_SYMBOL(splice_from_pipe_end); | ||
1174 | + | ||
1175 | +/** | ||
1176 | + * __splice_from_pipe - splice data from a pipe to given actor | ||
1177 | + * @pipe: pipe to splice from | ||
1178 | + * @sd: information to @actor | ||
1179 | + * @actor: handler that splices the data | ||
1180 | + * | ||
1181 | + * Description: | ||
1182 | + * This function does little more than loop over the pipe and call | ||
1183 | + * @actor to do the actual moving of a single struct pipe_buffer to | ||
1184 | + * the desired destination. See pipe_to_file, pipe_to_sendpage, or | ||
1185 | + * pipe_to_user. | ||
1186 | + * | ||
1187 | + */ | ||
1188 | +ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd, | ||
1189 | + splice_actor *actor) | ||
1190 | +{ | ||
1191 | + int ret; | ||
1192 | + | ||
1193 | + splice_from_pipe_begin(sd); | ||
1194 | + do { | ||
1195 | + ret = splice_from_pipe_next(pipe, sd); | ||
1196 | + if (ret > 0) | ||
1197 | + ret = splice_from_pipe_feed(pipe, sd, actor); | ||
1198 | + } while (ret > 0); | ||
1199 | + splice_from_pipe_end(pipe, sd); | ||
1200 | + | ||
1201 | + return sd->num_spliced ? sd->num_spliced : ret; | ||
1202 | } | ||
1203 | EXPORT_SYMBOL(__splice_from_pipe); | ||
1204 | |||
1205 | @@ -713,7 +783,7 @@ EXPORT_SYMBOL(__splice_from_pipe); | ||
1206 | * @actor: handler that splices the data | ||
1207 | * | ||
1208 | * Description: | ||
1209 | - * See __splice_from_pipe. This function locks the input and output inodes, | ||
1210 | + * See __splice_from_pipe. This function locks the pipe inode, | ||
1211 | * otherwise it's identical to __splice_from_pipe(). | ||
1212 | * | ||
1213 | */ | ||
1214 | @@ -722,7 +792,6 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, | ||
1215 | splice_actor *actor) | ||
1216 | { | ||
1217 | ssize_t ret; | ||
1218 | - struct inode *inode = out->f_mapping->host; | ||
1219 | struct splice_desc sd = { | ||
1220 | .total_len = len, | ||
1221 | .flags = flags, | ||
1222 | @@ -730,24 +799,11 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, | ||
1223 | .u.file = out, | ||
1224 | }; | ||
1225 | |||
1226 | - /* | ||
1227 | - * The actor worker might be calling ->prepare_write and | ||
1228 | - * ->commit_write. Most of the time, these expect i_mutex to | ||
1229 | - * be held. Since this may result in an ABBA deadlock with | ||
1230 | - * pipe->inode, we have to order lock acquiry here. | ||
1231 | - * | ||
1232 | - * Outer lock must be inode->i_mutex, as pipe_wait() will | ||
1233 | - * release and reacquire pipe->inode->i_mutex, AND inode must | ||
1234 | - * never be a pipe. | ||
1235 | - */ | ||
1236 | - WARN_ON(S_ISFIFO(inode->i_mode)); | ||
1237 | - mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); | ||
1238 | if (pipe->inode) | ||
1239 | - mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD); | ||
1240 | + mutex_lock(&pipe->inode->i_mutex); | ||
1241 | ret = __splice_from_pipe(pipe, &sd, actor); | ||
1242 | if (pipe->inode) | ||
1243 | mutex_unlock(&pipe->inode->i_mutex); | ||
1244 | - mutex_unlock(&inode->i_mutex); | ||
1245 | |||
1246 | return ret; | ||
1247 | } | ||
1248 | @@ -838,17 +894,29 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | ||
1249 | }; | ||
1250 | ssize_t ret; | ||
1251 | |||
1252 | - WARN_ON(S_ISFIFO(inode->i_mode)); | ||
1253 | - mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); | ||
1254 | - ret = file_remove_suid(out); | ||
1255 | - if (likely(!ret)) { | ||
1256 | - if (pipe->inode) | ||
1257 | - mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD); | ||
1258 | - ret = __splice_from_pipe(pipe, &sd, pipe_to_file); | ||
1259 | - if (pipe->inode) | ||
1260 | - mutex_unlock(&pipe->inode->i_mutex); | ||
1261 | - } | ||
1262 | - mutex_unlock(&inode->i_mutex); | ||
1263 | + if (pipe->inode) | ||
1264 | + mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_PARENT); | ||
1265 | + | ||
1266 | + splice_from_pipe_begin(&sd); | ||
1267 | + do { | ||
1268 | + ret = splice_from_pipe_next(pipe, &sd); | ||
1269 | + if (ret <= 0) | ||
1270 | + break; | ||
1271 | + | ||
1272 | + mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); | ||
1273 | + ret = file_remove_suid(out); | ||
1274 | + if (!ret) | ||
1275 | + ret = splice_from_pipe_feed(pipe, &sd, pipe_to_file); | ||
1276 | + mutex_unlock(&inode->i_mutex); | ||
1277 | + } while (ret > 0); | ||
1278 | + splice_from_pipe_end(pipe, &sd); | ||
1279 | + | ||
1280 | + if (pipe->inode) | ||
1281 | + mutex_unlock(&pipe->inode->i_mutex); | ||
1282 | + | ||
1283 | + if (sd.num_spliced) | ||
1284 | + ret = sd.num_spliced; | ||
1285 | + | ||
1286 | if (ret > 0) { | ||
1287 | unsigned long nr_pages; | ||
1288 | |||
1289 | diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c | ||
1290 | index 40033dc..82b1c4a 100644 | ||
1291 | --- a/fs/ubifs/file.c | ||
1292 | +++ b/fs/ubifs/file.c | ||
1293 | @@ -1140,8 +1140,9 @@ static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags) | ||
1294 | * mmap()d file has taken write protection fault and is being made | ||
1295 | * writable. UBIFS must ensure page is budgeted for. | ||
1296 | */ | ||
1297 | -static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) | ||
1298 | +static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | ||
1299 | { | ||
1300 | + struct page *page = vmf->page; | ||
1301 | struct inode *inode = vma->vm_file->f_path.dentry->d_inode; | ||
1302 | struct ubifs_info *c = inode->i_sb->s_fs_info; | ||
1303 | struct timespec now = ubifs_current_time(inode); | ||
1304 | @@ -1153,7 +1154,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) | ||
1305 | ubifs_assert(!(inode->i_sb->s_flags & MS_RDONLY)); | ||
1306 | |||
1307 | if (unlikely(c->ro_media)) | ||
1308 | - return -EROFS; | ||
1309 | + return VM_FAULT_SIGBUS; /* -EROFS */ | ||
1310 | |||
1311 | /* | ||
1312 | * We have not locked @page so far so we may budget for changing the | ||
1313 | @@ -1186,7 +1187,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) | ||
1314 | if (err == -ENOSPC) | ||
1315 | ubifs_warn("out of space for mmapped file " | ||
1316 | "(inode number %lu)", inode->i_ino); | ||
1317 | - return err; | ||
1318 | + return VM_FAULT_SIGBUS; | ||
1319 | } | ||
1320 | |||
1321 | lock_page(page); | ||
1322 | @@ -1226,6 +1227,8 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) | ||
1323 | out_unlock: | ||
1324 | unlock_page(page); | ||
1325 | ubifs_release_budget(c, &req); | ||
1326 | + if (err) | ||
1327 | + err = VM_FAULT_SIGBUS; | ||
1328 | return err; | ||
1329 | } | ||
1330 | |||
1331 | diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c | ||
1332 | index 5311c1a..469502c 100644 | ||
1333 | --- a/fs/xfs/linux-2.6/xfs_file.c | ||
1334 | +++ b/fs/xfs/linux-2.6/xfs_file.c | ||
1335 | @@ -427,9 +427,9 @@ xfs_file_ioctl_invis( | ||
1336 | STATIC int | ||
1337 | xfs_vm_page_mkwrite( | ||
1338 | struct vm_area_struct *vma, | ||
1339 | - struct page *page) | ||
1340 | + struct vm_fault *vmf) | ||
1341 | { | ||
1342 | - return block_page_mkwrite(vma, page, xfs_get_blocks); | ||
1343 | + return block_page_mkwrite(vma, vmf, xfs_get_blocks); | ||
1344 | } | ||
1345 | |||
1346 | const struct file_operations xfs_file_operations = { | ||
1347 | diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h | ||
1348 | index eadaab4..657c072 100644 | ||
1349 | --- a/include/linux/buffer_head.h | ||
1350 | +++ b/include/linux/buffer_head.h | ||
1351 | @@ -222,7 +222,7 @@ int cont_write_begin(struct file *, struct address_space *, loff_t, | ||
1352 | get_block_t *, loff_t *); | ||
1353 | int generic_cont_expand_simple(struct inode *inode, loff_t size); | ||
1354 | int block_commit_write(struct page *page, unsigned from, unsigned to); | ||
1355 | -int block_page_mkwrite(struct vm_area_struct *vma, struct page *page, | ||
1356 | +int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | ||
1357 | get_block_t get_block); | ||
1358 | void block_sync_page(struct page *); | ||
1359 | sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); | ||
1360 | diff --git a/include/linux/mm.h b/include/linux/mm.h | ||
1361 | index 2a75579..ae9775d 100644 | ||
1362 | --- a/include/linux/mm.h | ||
1363 | +++ b/include/linux/mm.h | ||
1364 | @@ -138,6 +138,7 @@ extern pgprot_t protection_map[16]; | ||
1365 | |||
1366 | #define FAULT_FLAG_WRITE 0x01 /* Fault was a write access */ | ||
1367 | #define FAULT_FLAG_NONLINEAR 0x02 /* Fault was via a nonlinear mapping */ | ||
1368 | +#define FAULT_FLAG_MKWRITE 0x04 /* Fault was mkwrite of existing pte */ | ||
1369 | |||
1370 | |||
1371 | /* | ||
1372 | @@ -173,7 +174,7 @@ struct vm_operations_struct { | ||
1373 | |||
1374 | /* notification that a previously read-only page is about to become | ||
1375 | * writable, if an error is returned it will cause a SIGBUS */ | ||
1376 | - int (*page_mkwrite)(struct vm_area_struct *vma, struct page *page); | ||
1377 | + int (*page_mkwrite)(struct vm_area_struct *vma, struct vm_fault *vmf); | ||
1378 | |||
1379 | /* called by access_process_vm when get_user_pages() fails, typically | ||
1380 | * for use by special VMAs that can switch between memory and hardware | ||
1381 | diff --git a/include/linux/splice.h b/include/linux/splice.h | ||
1382 | index 528dcb9..5f3faa9 100644 | ||
1383 | --- a/include/linux/splice.h | ||
1384 | +++ b/include/linux/splice.h | ||
1385 | @@ -36,6 +36,8 @@ struct splice_desc { | ||
1386 | void *data; /* cookie */ | ||
1387 | } u; | ||
1388 | loff_t pos; /* file position */ | ||
1389 | + size_t num_spliced; /* number of bytes already spliced */ | ||
1390 | + bool need_wakeup; /* need to wake up writer */ | ||
1391 | }; | ||
1392 | |||
1393 | struct partial_page { | ||
1394 | @@ -66,6 +68,16 @@ extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *, | ||
1395 | splice_actor *); | ||
1396 | extern ssize_t __splice_from_pipe(struct pipe_inode_info *, | ||
1397 | struct splice_desc *, splice_actor *); | ||
1398 | +extern int splice_from_pipe_feed(struct pipe_inode_info *, struct splice_desc *, | ||
1399 | + splice_actor *); | ||
1400 | +extern int splice_from_pipe_next(struct pipe_inode_info *, | ||
1401 | + struct splice_desc *); | ||
1402 | +extern void splice_from_pipe_begin(struct splice_desc *); | ||
1403 | +extern void splice_from_pipe_end(struct pipe_inode_info *, | ||
1404 | + struct splice_desc *); | ||
1405 | +extern int pipe_to_file(struct pipe_inode_info *, struct pipe_buffer *, | ||
1406 | + struct splice_desc *); | ||
1407 | + | ||
1408 | extern ssize_t splice_to_pipe(struct pipe_inode_info *, | ||
1409 | struct splice_pipe_desc *); | ||
1410 | extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, | ||
1411 | diff --git a/mm/memory.c b/mm/memory.c | ||
1412 | index 1002f47..3856c36 100644 | ||
1413 | --- a/mm/memory.c | ||
1414 | +++ b/mm/memory.c | ||
1415 | @@ -1801,6 +1801,15 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | ||
1416 | * get_user_pages(.write=1, .force=1). | ||
1417 | */ | ||
1418 | if (vma->vm_ops && vma->vm_ops->page_mkwrite) { | ||
1419 | + struct vm_fault vmf; | ||
1420 | + int tmp; | ||
1421 | + | ||
1422 | + vmf.virtual_address = (void __user *)(address & | ||
1423 | + PAGE_MASK); | ||
1424 | + vmf.pgoff = old_page->index; | ||
1425 | + vmf.flags = FAULT_FLAG_WRITE|FAULT_FLAG_MKWRITE; | ||
1426 | + vmf.page = old_page; | ||
1427 | + | ||
1428 | /* | ||
1429 | * Notify the address space that the page is about to | ||
1430 | * become writable so that it can prohibit this or wait | ||
1431 | @@ -1812,8 +1821,21 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | ||
1432 | page_cache_get(old_page); | ||
1433 | pte_unmap_unlock(page_table, ptl); | ||
1434 | |||
1435 | - if (vma->vm_ops->page_mkwrite(vma, old_page) < 0) | ||
1436 | + tmp = vma->vm_ops->page_mkwrite(vma, &vmf); | ||
1437 | + if (unlikely(tmp & | ||
1438 | + (VM_FAULT_ERROR | VM_FAULT_NOPAGE))) { | ||
1439 | + ret = tmp; | ||
1440 | goto unwritable_page; | ||
1441 | + } | ||
1442 | + if (unlikely(!(tmp & VM_FAULT_LOCKED))) { | ||
1443 | + lock_page(old_page); | ||
1444 | + if (!old_page->mapping) { | ||
1445 | + ret = 0; /* retry the fault */ | ||
1446 | + unlock_page(old_page); | ||
1447 | + goto unwritable_page; | ||
1448 | + } | ||
1449 | + } else | ||
1450 | + VM_BUG_ON(!PageLocked(old_page)); | ||
1451 | |||
1452 | /* | ||
1453 | * Since we dropped the lock we need to revalidate | ||
1454 | @@ -1823,9 +1845,11 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, | ||
1455 | */ | ||
1456 | page_table = pte_offset_map_lock(mm, pmd, address, | ||
1457 | &ptl); | ||
1458 | - page_cache_release(old_page); | ||
1459 | - if (!pte_same(*page_table, orig_pte)) | ||
1460 | + if (!pte_same(*page_table, orig_pte)) { | ||
1461 | + unlock_page(old_page); | ||
1462 | + page_cache_release(old_page); | ||
1463 | goto unlock; | ||
1464 | + } | ||
1465 | |||
1466 | page_mkwrite = 1; | ||
1467 | } | ||
1468 | @@ -1930,9 +1954,6 @@ gotten: | ||
1469 | unlock: | ||
1470 | pte_unmap_unlock(page_table, ptl); | ||
1471 | if (dirty_page) { | ||
1472 | - if (vma->vm_file) | ||
1473 | - file_update_time(vma->vm_file); | ||
1474 | - | ||
1475 | /* | ||
1476 | * Yes, Virginia, this is actually required to prevent a race | ||
1477 | * with clear_page_dirty_for_io() from clearing the page dirty | ||
1478 | @@ -1941,21 +1962,46 @@ unlock: | ||
1479 | * | ||
1480 | * do_no_page is protected similarly. | ||
1481 | */ | ||
1482 | - wait_on_page_locked(dirty_page); | ||
1483 | - set_page_dirty_balance(dirty_page, page_mkwrite); | ||
1484 | + if (!page_mkwrite) { | ||
1485 | + wait_on_page_locked(dirty_page); | ||
1486 | + set_page_dirty_balance(dirty_page, page_mkwrite); | ||
1487 | + } | ||
1488 | put_page(dirty_page); | ||
1489 | + if (page_mkwrite) { | ||
1490 | + struct address_space *mapping = dirty_page->mapping; | ||
1491 | + | ||
1492 | + set_page_dirty(dirty_page); | ||
1493 | + unlock_page(dirty_page); | ||
1494 | + page_cache_release(dirty_page); | ||
1495 | + if (mapping) { | ||
1496 | + /* | ||
1497 | + * Some device drivers do not set page.mapping | ||
1498 | + * but still dirty their pages | ||
1499 | + */ | ||
1500 | + balance_dirty_pages_ratelimited(mapping); | ||
1501 | + } | ||
1502 | + } | ||
1503 | + | ||
1504 | + /* file_update_time outside page_lock */ | ||
1505 | + if (vma->vm_file) | ||
1506 | + file_update_time(vma->vm_file); | ||
1507 | } | ||
1508 | return ret; | ||
1509 | oom_free_new: | ||
1510 | page_cache_release(new_page); | ||
1511 | oom: | ||
1512 | - if (old_page) | ||
1513 | + if (old_page) { | ||
1514 | + if (page_mkwrite) { | ||
1515 | + unlock_page(old_page); | ||
1516 | + page_cache_release(old_page); | ||
1517 | + } | ||
1518 | page_cache_release(old_page); | ||
1519 | + } | ||
1520 | return VM_FAULT_OOM; | ||
1521 | |||
1522 | unwritable_page: | ||
1523 | page_cache_release(old_page); | ||
1524 | - return VM_FAULT_SIGBUS; | ||
1525 | + return ret; | ||
1526 | } | ||
1527 | |||
1528 | /* | ||
1529 | @@ -2472,25 +2518,25 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, | ||
1530 | * to become writable | ||
1531 | */ | ||
1532 | if (vma->vm_ops->page_mkwrite) { | ||
1533 | + int tmp; | ||
1534 | + | ||
1535 | unlock_page(page); | ||
1536 | - if (vma->vm_ops->page_mkwrite(vma, page) < 0) { | ||
1537 | - ret = VM_FAULT_SIGBUS; | ||
1538 | - anon = 1; /* no anon but release vmf.page */ | ||
1539 | - goto out_unlocked; | ||
1540 | - } | ||
1541 | - lock_page(page); | ||
1542 | - /* | ||
1543 | - * XXX: this is not quite right (racy vs | ||
1544 | - * invalidate) to unlock and relock the page | ||
1545 | - * like this, however a better fix requires | ||
1546 | - * reworking page_mkwrite locking API, which | ||
1547 | - * is better done later. | ||
1548 | - */ | ||
1549 | - if (!page->mapping) { | ||
1550 | - ret = 0; | ||
1551 | - anon = 1; /* no anon but release vmf.page */ | ||
1552 | - goto out; | ||
1553 | + vmf.flags = FAULT_FLAG_WRITE|FAULT_FLAG_MKWRITE; | ||
1554 | + tmp = vma->vm_ops->page_mkwrite(vma, &vmf); | ||
1555 | + if (unlikely(tmp & | ||
1556 | + (VM_FAULT_ERROR | VM_FAULT_NOPAGE))) { | ||
1557 | + ret = tmp; | ||
1558 | + goto unwritable_page; | ||
1559 | } | ||
1560 | + if (unlikely(!(tmp & VM_FAULT_LOCKED))) { | ||
1561 | + lock_page(page); | ||
1562 | + if (!page->mapping) { | ||
1563 | + ret = 0; /* retry the fault */ | ||
1564 | + unlock_page(page); | ||
1565 | + goto unwritable_page; | ||
1566 | + } | ||
1567 | + } else | ||
1568 | + VM_BUG_ON(!PageLocked(page)); | ||
1569 | page_mkwrite = 1; | ||
1570 | } | ||
1571 | } | ||
1572 | @@ -2547,19 +2593,35 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma, | ||
1573 | pte_unmap_unlock(page_table, ptl); | ||
1574 | |||
1575 | out: | ||
1576 | - unlock_page(vmf.page); | ||
1577 | -out_unlocked: | ||
1578 | - if (anon) | ||
1579 | - page_cache_release(vmf.page); | ||
1580 | - else if (dirty_page) { | ||
1581 | - if (vma->vm_file) | ||
1582 | - file_update_time(vma->vm_file); | ||
1583 | + if (dirty_page) { | ||
1584 | + struct address_space *mapping = page->mapping; | ||
1585 | |||
1586 | - set_page_dirty_balance(dirty_page, page_mkwrite); | ||
1587 | + if (set_page_dirty(dirty_page)) | ||
1588 | + page_mkwrite = 1; | ||
1589 | + unlock_page(dirty_page); | ||
1590 | put_page(dirty_page); | ||
1591 | + if (page_mkwrite && mapping) { | ||
1592 | + /* | ||
1593 | + * Some device drivers do not set page.mapping but still | ||
1594 | + * dirty their pages | ||
1595 | + */ | ||
1596 | + balance_dirty_pages_ratelimited(mapping); | ||
1597 | + } | ||
1598 | + | ||
1599 | + /* file_update_time outside page_lock */ | ||
1600 | + if (vma->vm_file) | ||
1601 | + file_update_time(vma->vm_file); | ||
1602 | + } else { | ||
1603 | + unlock_page(vmf.page); | ||
1604 | + if (anon) | ||
1605 | + page_cache_release(vmf.page); | ||
1606 | } | ||
1607 | |||
1608 | return ret; | ||
1609 | + | ||
1610 | +unwritable_page: | ||
1611 | + page_cache_release(page); | ||
1612 | + return ret; | ||
1613 | } | ||
1614 | |||
1615 | static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma, |