diff options
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 8ed709a83eb..33f81252a74 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -612,6 +612,19 @@ void __lock_page_nosync(struct page *page) | |||
612 | TASK_UNINTERRUPTIBLE); | 612 | TASK_UNINTERRUPTIBLE); |
613 | } | 613 | } |
614 | 614 | ||
615 | int __lock_page_or_retry(struct page *page, struct mm_struct *mm, | ||
616 | unsigned int flags) | ||
617 | { | ||
618 | if (!(flags & FAULT_FLAG_ALLOW_RETRY)) { | ||
619 | __lock_page(page); | ||
620 | return 1; | ||
621 | } else { | ||
622 | up_read(&mm->mmap_sem); | ||
623 | wait_on_page_locked(page); | ||
624 | return 0; | ||
625 | } | ||
626 | } | ||
627 | |||
615 | /** | 628 | /** |
616 | * find_get_page - find and get a page reference | 629 | * find_get_page - find and get a page reference |
617 | * @mapping: the address_space to search | 630 | * @mapping: the address_space to search |
@@ -1550,7 +1563,8 @@ retry_find: | |||
1550 | goto no_cached_page; | 1563 | goto no_cached_page; |
1551 | } | 1564 | } |
1552 | 1565 | ||
1553 | lock_page(page); | 1566 | if (!lock_page_or_retry(page, vma->vm_mm, vmf->flags)) |
1567 | return ret | VM_FAULT_RETRY; | ||
1554 | 1568 | ||
1555 | /* Did it get truncated? */ | 1569 | /* Did it get truncated? */ |
1556 | if (unlikely(page->mapping != mapping)) { | 1570 | if (unlikely(page->mapping != mapping)) { |