diff options
Diffstat (limited to 'mm/filemap.c')
| -rw-r--r-- | mm/filemap.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index b9a60c43b61a..3277f3b23524 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
| @@ -488,6 +488,12 @@ struct page *page_cache_alloc_cold(struct address_space *x) | |||
| 488 | EXPORT_SYMBOL(page_cache_alloc_cold); | 488 | EXPORT_SYMBOL(page_cache_alloc_cold); |
| 489 | #endif | 489 | #endif |
| 490 | 490 | ||
| 491 | static int __sleep_on_page_lock(void *word) | ||
| 492 | { | ||
| 493 | io_schedule(); | ||
| 494 | return 0; | ||
| 495 | } | ||
| 496 | |||
| 491 | /* | 497 | /* |
| 492 | * In order to wait for pages to become available there must be | 498 | * In order to wait for pages to become available there must be |
| 493 | * waitqueues associated with pages. By using a hash table of | 499 | * waitqueues associated with pages. By using a hash table of |
| @@ -577,13 +583,24 @@ void fastcall __lock_page(struct page *page) | |||
| 577 | } | 583 | } |
| 578 | EXPORT_SYMBOL(__lock_page); | 584 | EXPORT_SYMBOL(__lock_page); |
| 579 | 585 | ||
| 586 | /* | ||
| 587 | * Variant of lock_page that does not require the caller to hold a reference | ||
| 588 | * on the page's mapping. | ||
| 589 | */ | ||
| 590 | void fastcall __lock_page_nosync(struct page *page) | ||
| 591 | { | ||
| 592 | DEFINE_WAIT_BIT(wait, &page->flags, PG_locked); | ||
| 593 | __wait_on_bit_lock(page_waitqueue(page), &wait, __sleep_on_page_lock, | ||
| 594 | TASK_UNINTERRUPTIBLE); | ||
| 595 | } | ||
| 596 | |||
| 580 | /** | 597 | /** |
| 581 | * find_get_page - find and get a page reference | 598 | * find_get_page - find and get a page reference |
| 582 | * @mapping: the address_space to search | 599 | * @mapping: the address_space to search |
| 583 | * @offset: the page index | 600 | * @offset: the page index |
| 584 | * | 601 | * |
| 585 | * A rather lightweight function, finding and getting a reference to a | 602 | * Is there a pagecache struct page at the given (mapping, offset) tuple? |
| 586 | * hashed page atomically. | 603 | * If yes, increment its refcount and return it; if no, return NULL. |
| 587 | */ | 604 | */ |
| 588 | struct page * find_get_page(struct address_space *mapping, unsigned long offset) | 605 | struct page * find_get_page(struct address_space *mapping, unsigned long offset) |
| 589 | { | 606 | { |
| @@ -970,7 +987,7 @@ page_not_up_to_date: | |||
| 970 | /* Get exclusive access to the page ... */ | 987 | /* Get exclusive access to the page ... */ |
| 971 | lock_page(page); | 988 | lock_page(page); |
| 972 | 989 | ||
| 973 | /* Did it get unhashed before we got the lock? */ | 990 | /* Did it get truncated before we got the lock? */ |
| 974 | if (!page->mapping) { | 991 | if (!page->mapping) { |
| 975 | unlock_page(page); | 992 | unlock_page(page); |
| 976 | page_cache_release(page); | 993 | page_cache_release(page); |
| @@ -1454,7 +1471,7 @@ outside_data_content: | |||
| 1454 | * accessible.. | 1471 | * accessible.. |
| 1455 | */ | 1472 | */ |
| 1456 | if (area->vm_mm == current->mm) | 1473 | if (area->vm_mm == current->mm) |
| 1457 | return NULL; | 1474 | return NOPAGE_SIGBUS; |
| 1458 | /* Fall through to the non-read-ahead case */ | 1475 | /* Fall through to the non-read-ahead case */ |
| 1459 | no_cached_page: | 1476 | no_cached_page: |
| 1460 | /* | 1477 | /* |
| @@ -1479,7 +1496,7 @@ no_cached_page: | |||
| 1479 | */ | 1496 | */ |
| 1480 | if (error == -ENOMEM) | 1497 | if (error == -ENOMEM) |
| 1481 | return NOPAGE_OOM; | 1498 | return NOPAGE_OOM; |
| 1482 | return NULL; | 1499 | return NOPAGE_SIGBUS; |
| 1483 | 1500 | ||
| 1484 | page_not_uptodate: | 1501 | page_not_uptodate: |
| 1485 | if (!did_readaround) { | 1502 | if (!did_readaround) { |
| @@ -1548,7 +1565,7 @@ page_not_uptodate: | |||
| 1548 | */ | 1565 | */ |
| 1549 | shrink_readahead_size_eio(file, ra); | 1566 | shrink_readahead_size_eio(file, ra); |
| 1550 | page_cache_release(page); | 1567 | page_cache_release(page); |
| 1551 | return NULL; | 1568 | return NOPAGE_SIGBUS; |
| 1552 | } | 1569 | } |
| 1553 | EXPORT_SYMBOL(filemap_nopage); | 1570 | EXPORT_SYMBOL(filemap_nopage); |
| 1554 | 1571 | ||
| @@ -1610,7 +1627,7 @@ no_cached_page: | |||
| 1610 | page_not_uptodate: | 1627 | page_not_uptodate: |
| 1611 | lock_page(page); | 1628 | lock_page(page); |
| 1612 | 1629 | ||
| 1613 | /* Did it get unhashed while we waited for it? */ | 1630 | /* Did it get truncated while we waited for it? */ |
| 1614 | if (!page->mapping) { | 1631 | if (!page->mapping) { |
| 1615 | unlock_page(page); | 1632 | unlock_page(page); |
| 1616 | goto err; | 1633 | goto err; |
