diff options
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 109 |
1 files changed, 75 insertions, 34 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 3464b681f844..7b84dc814347 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -75,8 +75,8 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, | |||
75 | * ->mmap_sem | 75 | * ->mmap_sem |
76 | * ->lock_page (access_process_vm) | 76 | * ->lock_page (access_process_vm) |
77 | * | 77 | * |
78 | * ->mmap_sem | 78 | * ->i_mutex (generic_file_buffered_write) |
79 | * ->i_mutex (msync) | 79 | * ->mmap_sem (fault_in_pages_readable->do_page_fault) |
80 | * | 80 | * |
81 | * ->i_mutex | 81 | * ->i_mutex |
82 | * ->i_alloc_sem (various) | 82 | * ->i_alloc_sem (various) |
@@ -467,25 +467,15 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping, | |||
467 | } | 467 | } |
468 | 468 | ||
469 | #ifdef CONFIG_NUMA | 469 | #ifdef CONFIG_NUMA |
470 | struct page *page_cache_alloc(struct address_space *x) | 470 | struct page *__page_cache_alloc(gfp_t gfp) |
471 | { | 471 | { |
472 | if (cpuset_do_page_mem_spread()) { | 472 | if (cpuset_do_page_mem_spread()) { |
473 | int n = cpuset_mem_spread_node(); | 473 | int n = cpuset_mem_spread_node(); |
474 | return alloc_pages_node(n, mapping_gfp_mask(x), 0); | 474 | return alloc_pages_node(n, gfp, 0); |
475 | } | 475 | } |
476 | return alloc_pages(mapping_gfp_mask(x), 0); | 476 | return alloc_pages(gfp, 0); |
477 | } | 477 | } |
478 | EXPORT_SYMBOL(page_cache_alloc); | 478 | EXPORT_SYMBOL(__page_cache_alloc); |
479 | |||
480 | struct page *page_cache_alloc_cold(struct address_space *x) | ||
481 | { | ||
482 | if (cpuset_do_page_mem_spread()) { | ||
483 | int n = cpuset_mem_spread_node(); | ||
484 | return alloc_pages_node(n, mapping_gfp_mask(x)|__GFP_COLD, 0); | ||
485 | } | ||
486 | return alloc_pages(mapping_gfp_mask(x)|__GFP_COLD, 0); | ||
487 | } | ||
488 | EXPORT_SYMBOL(page_cache_alloc_cold); | ||
489 | #endif | 479 | #endif |
490 | 480 | ||
491 | static int __sleep_on_page_lock(void *word) | 481 | static int __sleep_on_page_lock(void *word) |
@@ -826,7 +816,6 @@ struct page * | |||
826 | grab_cache_page_nowait(struct address_space *mapping, unsigned long index) | 816 | grab_cache_page_nowait(struct address_space *mapping, unsigned long index) |
827 | { | 817 | { |
828 | struct page *page = find_get_page(mapping, index); | 818 | struct page *page = find_get_page(mapping, index); |
829 | gfp_t gfp_mask; | ||
830 | 819 | ||
831 | if (page) { | 820 | if (page) { |
832 | if (!TestSetPageLocked(page)) | 821 | if (!TestSetPageLocked(page)) |
@@ -834,9 +823,8 @@ grab_cache_page_nowait(struct address_space *mapping, unsigned long index) | |||
834 | page_cache_release(page); | 823 | page_cache_release(page); |
835 | return NULL; | 824 | return NULL; |
836 | } | 825 | } |
837 | gfp_mask = mapping_gfp_mask(mapping) & ~__GFP_FS; | 826 | page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~__GFP_FS); |
838 | page = alloc_pages(gfp_mask, 0); | 827 | if (page && add_to_page_cache_lru(page, mapping, index, GFP_KERNEL)) { |
839 | if (page && add_to_page_cache_lru(page, mapping, index, gfp_mask)) { | ||
840 | page_cache_release(page); | 828 | page_cache_release(page); |
841 | page = NULL; | 829 | page = NULL; |
842 | } | 830 | } |
@@ -1884,11 +1872,10 @@ repeat: | |||
1884 | * if suid or (sgid and xgrp) | 1872 | * if suid or (sgid and xgrp) |
1885 | * remove privs | 1873 | * remove privs |
1886 | */ | 1874 | */ |
1887 | int remove_suid(struct dentry *dentry) | 1875 | int should_remove_suid(struct dentry *dentry) |
1888 | { | 1876 | { |
1889 | mode_t mode = dentry->d_inode->i_mode; | 1877 | mode_t mode = dentry->d_inode->i_mode; |
1890 | int kill = 0; | 1878 | int kill = 0; |
1891 | int result = 0; | ||
1892 | 1879 | ||
1893 | /* suid always must be killed */ | 1880 | /* suid always must be killed */ |
1894 | if (unlikely(mode & S_ISUID)) | 1881 | if (unlikely(mode & S_ISUID)) |
@@ -1901,13 +1888,28 @@ int remove_suid(struct dentry *dentry) | |||
1901 | if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) | 1888 | if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) |
1902 | kill |= ATTR_KILL_SGID; | 1889 | kill |= ATTR_KILL_SGID; |
1903 | 1890 | ||
1904 | if (unlikely(kill && !capable(CAP_FSETID))) { | 1891 | if (unlikely(kill && !capable(CAP_FSETID))) |
1905 | struct iattr newattrs; | 1892 | return kill; |
1906 | 1893 | ||
1907 | newattrs.ia_valid = ATTR_FORCE | kill; | 1894 | return 0; |
1908 | result = notify_change(dentry, &newattrs); | 1895 | } |
1909 | } | 1896 | |
1910 | return result; | 1897 | int __remove_suid(struct dentry *dentry, int kill) |
1898 | { | ||
1899 | struct iattr newattrs; | ||
1900 | |||
1901 | newattrs.ia_valid = ATTR_FORCE | kill; | ||
1902 | return notify_change(dentry, &newattrs); | ||
1903 | } | ||
1904 | |||
1905 | int remove_suid(struct dentry *dentry) | ||
1906 | { | ||
1907 | int kill = should_remove_suid(dentry); | ||
1908 | |||
1909 | if (unlikely(kill)) | ||
1910 | return __remove_suid(dentry, kill); | ||
1911 | |||
1912 | return 0; | ||
1911 | } | 1913 | } |
1912 | EXPORT_SYMBOL(remove_suid); | 1914 | EXPORT_SYMBOL(remove_suid); |
1913 | 1915 | ||
@@ -2222,7 +2224,7 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov, | |||
2222 | unsigned long nr_segs, loff_t *ppos) | 2224 | unsigned long nr_segs, loff_t *ppos) |
2223 | { | 2225 | { |
2224 | struct file *file = iocb->ki_filp; | 2226 | struct file *file = iocb->ki_filp; |
2225 | const struct address_space * mapping = file->f_mapping; | 2227 | struct address_space * mapping = file->f_mapping; |
2226 | size_t ocount; /* original count */ | 2228 | size_t ocount; /* original count */ |
2227 | size_t count; /* after file limit checks */ | 2229 | size_t count; /* after file limit checks */ |
2228 | struct inode *inode = mapping->host; | 2230 | struct inode *inode = mapping->host; |
@@ -2275,8 +2277,11 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov, | |||
2275 | 2277 | ||
2276 | /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */ | 2278 | /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */ |
2277 | if (unlikely(file->f_flags & O_DIRECT)) { | 2279 | if (unlikely(file->f_flags & O_DIRECT)) { |
2278 | written = generic_file_direct_write(iocb, iov, | 2280 | loff_t endbyte; |
2279 | &nr_segs, pos, ppos, count, ocount); | 2281 | ssize_t written_buffered; |
2282 | |||
2283 | written = generic_file_direct_write(iocb, iov, &nr_segs, pos, | ||
2284 | ppos, count, ocount); | ||
2280 | if (written < 0 || written == count) | 2285 | if (written < 0 || written == count) |
2281 | goto out; | 2286 | goto out; |
2282 | /* | 2287 | /* |
@@ -2285,10 +2290,46 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov, | |||
2285 | */ | 2290 | */ |
2286 | pos += written; | 2291 | pos += written; |
2287 | count -= written; | 2292 | count -= written; |
2288 | } | 2293 | written_buffered = generic_file_buffered_write(iocb, iov, |
2294 | nr_segs, pos, ppos, count, | ||
2295 | written); | ||
2296 | /* | ||
2297 | * If generic_file_buffered_write() retuned a synchronous error | ||
2298 | * then we want to return the number of bytes which were | ||
2299 | * direct-written, or the error code if that was zero. Note | ||
2300 | * that this differs from normal direct-io semantics, which | ||
2301 | * will return -EFOO even if some bytes were written. | ||
2302 | */ | ||
2303 | if (written_buffered < 0) { | ||
2304 | err = written_buffered; | ||
2305 | goto out; | ||
2306 | } | ||
2289 | 2307 | ||
2290 | written = generic_file_buffered_write(iocb, iov, nr_segs, | 2308 | /* |
2291 | pos, ppos, count, written); | 2309 | * We need to ensure that the page cache pages are written to |
2310 | * disk and invalidated to preserve the expected O_DIRECT | ||
2311 | * semantics. | ||
2312 | */ | ||
2313 | endbyte = pos + written_buffered - written - 1; | ||
2314 | err = do_sync_file_range(file, pos, endbyte, | ||
2315 | SYNC_FILE_RANGE_WAIT_BEFORE| | ||
2316 | SYNC_FILE_RANGE_WRITE| | ||
2317 | SYNC_FILE_RANGE_WAIT_AFTER); | ||
2318 | if (err == 0) { | ||
2319 | written = written_buffered; | ||
2320 | invalidate_mapping_pages(mapping, | ||
2321 | pos >> PAGE_CACHE_SHIFT, | ||
2322 | endbyte >> PAGE_CACHE_SHIFT); | ||
2323 | } else { | ||
2324 | /* | ||
2325 | * We don't know how much we wrote, so just return | ||
2326 | * the number of bytes which were direct-written | ||
2327 | */ | ||
2328 | } | ||
2329 | } else { | ||
2330 | written = generic_file_buffered_write(iocb, iov, nr_segs, | ||
2331 | pos, ppos, count, written); | ||
2332 | } | ||
2292 | out: | 2333 | out: |
2293 | current->backing_dev_info = NULL; | 2334 | current->backing_dev_info = NULL; |
2294 | return written ? written : err; | 2335 | return written ? written : err; |