diff options
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 57 |
1 files changed, 48 insertions, 9 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 140ebda9640f..20e5642e9f9f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -151,6 +151,7 @@ void remove_from_page_cache(struct page *page) | |||
151 | spin_unlock_irq(&mapping->tree_lock); | 151 | spin_unlock_irq(&mapping->tree_lock); |
152 | mem_cgroup_uncharge_cache_page(page); | 152 | mem_cgroup_uncharge_cache_page(page); |
153 | } | 153 | } |
154 | EXPORT_SYMBOL(remove_from_page_cache); | ||
154 | 155 | ||
155 | static int sync_page(void *word) | 156 | static int sync_page(void *word) |
156 | { | 157 | { |
@@ -441,7 +442,7 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping, | |||
441 | /* | 442 | /* |
442 | * Splice_read and readahead add shmem/tmpfs pages into the page cache | 443 | * Splice_read and readahead add shmem/tmpfs pages into the page cache |
443 | * before shmem_readpage has a chance to mark them as SwapBacked: they | 444 | * before shmem_readpage has a chance to mark them as SwapBacked: they |
444 | * need to go on the active_anon lru below, and mem_cgroup_cache_charge | 445 | * need to go on the anon lru below, and mem_cgroup_cache_charge |
445 | * (called in add_to_page_cache) needs to know where they're going too. | 446 | * (called in add_to_page_cache) needs to know where they're going too. |
446 | */ | 447 | */ |
447 | if (mapping_cap_swap_backed(mapping)) | 448 | if (mapping_cap_swap_backed(mapping)) |
@@ -452,7 +453,7 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping, | |||
452 | if (page_is_file_cache(page)) | 453 | if (page_is_file_cache(page)) |
453 | lru_cache_add_file(page); | 454 | lru_cache_add_file(page); |
454 | else | 455 | else |
455 | lru_cache_add_active_anon(page); | 456 | lru_cache_add_anon(page); |
456 | } | 457 | } |
457 | return ret; | 458 | return ret; |
458 | } | 459 | } |
@@ -461,9 +462,15 @@ EXPORT_SYMBOL_GPL(add_to_page_cache_lru); | |||
461 | #ifdef CONFIG_NUMA | 462 | #ifdef CONFIG_NUMA |
462 | struct page *__page_cache_alloc(gfp_t gfp) | 463 | struct page *__page_cache_alloc(gfp_t gfp) |
463 | { | 464 | { |
465 | int n; | ||
466 | struct page *page; | ||
467 | |||
464 | if (cpuset_do_page_mem_spread()) { | 468 | if (cpuset_do_page_mem_spread()) { |
465 | int n = cpuset_mem_spread_node(); | 469 | get_mems_allowed(); |
466 | return alloc_pages_exact_node(n, gfp, 0); | 470 | n = cpuset_mem_spread_node(); |
471 | page = alloc_pages_exact_node(n, gfp, 0); | ||
472 | put_mems_allowed(); | ||
473 | return page; | ||
467 | } | 474 | } |
468 | return alloc_pages(gfp, 0); | 475 | return alloc_pages(gfp, 0); |
469 | } | 476 | } |
@@ -1099,6 +1106,12 @@ page_not_up_to_date_locked: | |||
1099 | } | 1106 | } |
1100 | 1107 | ||
1101 | readpage: | 1108 | readpage: |
1109 | /* | ||
1110 | * A previous I/O error may have been due to temporary | ||
1111 | * failures, eg. multipath errors. | ||
1112 | * PG_error will be set again if readpage fails. | ||
1113 | */ | ||
1114 | ClearPageError(page); | ||
1102 | /* Start the actual read. The read will unlock the page. */ | 1115 | /* Start the actual read. The read will unlock the page. */ |
1103 | error = mapping->a_ops->readpage(filp, page); | 1116 | error = mapping->a_ops->readpage(filp, page); |
1104 | 1117 | ||
@@ -1263,7 +1276,7 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
1263 | { | 1276 | { |
1264 | struct file *filp = iocb->ki_filp; | 1277 | struct file *filp = iocb->ki_filp; |
1265 | ssize_t retval; | 1278 | ssize_t retval; |
1266 | unsigned long seg; | 1279 | unsigned long seg = 0; |
1267 | size_t count; | 1280 | size_t count; |
1268 | loff_t *ppos = &iocb->ki_pos; | 1281 | loff_t *ppos = &iocb->ki_pos; |
1269 | 1282 | ||
@@ -1290,21 +1303,47 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
1290 | retval = mapping->a_ops->direct_IO(READ, iocb, | 1303 | retval = mapping->a_ops->direct_IO(READ, iocb, |
1291 | iov, pos, nr_segs); | 1304 | iov, pos, nr_segs); |
1292 | } | 1305 | } |
1293 | if (retval > 0) | 1306 | if (retval > 0) { |
1294 | *ppos = pos + retval; | 1307 | *ppos = pos + retval; |
1295 | if (retval) { | 1308 | count -= retval; |
1309 | } | ||
1310 | |||
1311 | /* | ||
1312 | * Btrfs can have a short DIO read if we encounter | ||
1313 | * compressed extents, so if there was an error, or if | ||
1314 | * we've already read everything we wanted to, or if | ||
1315 | * there was a short read because we hit EOF, go ahead | ||
1316 | * and return. Otherwise fallthrough to buffered io for | ||
1317 | * the rest of the read. | ||
1318 | */ | ||
1319 | if (retval < 0 || !count || *ppos >= size) { | ||
1296 | file_accessed(filp); | 1320 | file_accessed(filp); |
1297 | goto out; | 1321 | goto out; |
1298 | } | 1322 | } |
1299 | } | 1323 | } |
1300 | } | 1324 | } |
1301 | 1325 | ||
1326 | count = retval; | ||
1302 | for (seg = 0; seg < nr_segs; seg++) { | 1327 | for (seg = 0; seg < nr_segs; seg++) { |
1303 | read_descriptor_t desc; | 1328 | read_descriptor_t desc; |
1329 | loff_t offset = 0; | ||
1330 | |||
1331 | /* | ||
1332 | * If we did a short DIO read we need to skip the section of the | ||
1333 | * iov that we've already read data into. | ||
1334 | */ | ||
1335 | if (count) { | ||
1336 | if (count > iov[seg].iov_len) { | ||
1337 | count -= iov[seg].iov_len; | ||
1338 | continue; | ||
1339 | } | ||
1340 | offset = count; | ||
1341 | count = 0; | ||
1342 | } | ||
1304 | 1343 | ||
1305 | desc.written = 0; | 1344 | desc.written = 0; |
1306 | desc.arg.buf = iov[seg].iov_base; | 1345 | desc.arg.buf = iov[seg].iov_base + offset; |
1307 | desc.count = iov[seg].iov_len; | 1346 | desc.count = iov[seg].iov_len - offset; |
1308 | if (desc.count == 0) | 1347 | if (desc.count == 0) |
1309 | continue; | 1348 | continue; |
1310 | desc.error = 0; | 1349 | desc.error = 0; |