diff options
author | Michel Lespinasse <walken@google.com> | 2010-10-26 17:21:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-26 19:52:09 -0400 |
commit | b522c94da5d9cbc73f708be5e530ebc3bbd4a031 (patch) | |
tree | d29cc4887bca05fde5b86a367f02a3ea70043e11 /mm/filemap.c | |
parent | 182fea8f48332de085c0ae936605cb72671db9f2 (diff) |
mm: filemap_fault: unique path for locking page
Introduce a single location where filemap_fault() locks the desired page.
There used to be two such places, depending if the initial find_get_page()
was successful or not.
Signed-off-by: Michel Lespinasse <walken@google.com>
Acked-by: Rik van Riel <riel@redhat.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Reviewed-by: Wu Fengguang <fengguang.wu@intel.com>
Cc: Ying Han <yinghan@google.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/filemap.c')
-rw-r--r-- | mm/filemap.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index 3d4df44e4221..8ed709a83eb7 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -1539,25 +1539,27 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1539 | * waiting for the lock. | 1539 | * waiting for the lock. |
1540 | */ | 1540 | */ |
1541 | do_async_mmap_readahead(vma, ra, file, page, offset); | 1541 | do_async_mmap_readahead(vma, ra, file, page, offset); |
1542 | lock_page(page); | ||
1543 | |||
1544 | /* Did it get truncated? */ | ||
1545 | if (unlikely(page->mapping != mapping)) { | ||
1546 | unlock_page(page); | ||
1547 | put_page(page); | ||
1548 | goto no_cached_page; | ||
1549 | } | ||
1550 | } else { | 1542 | } else { |
1551 | /* No page in the page cache at all */ | 1543 | /* No page in the page cache at all */ |
1552 | do_sync_mmap_readahead(vma, ra, file, offset); | 1544 | do_sync_mmap_readahead(vma, ra, file, offset); |
1553 | count_vm_event(PGMAJFAULT); | 1545 | count_vm_event(PGMAJFAULT); |
1554 | ret = VM_FAULT_MAJOR; | 1546 | ret = VM_FAULT_MAJOR; |
1555 | retry_find: | 1547 | retry_find: |
1556 | page = find_lock_page(mapping, offset); | 1548 | page = find_get_page(mapping, offset); |
1557 | if (!page) | 1549 | if (!page) |
1558 | goto no_cached_page; | 1550 | goto no_cached_page; |
1559 | } | 1551 | } |
1560 | 1552 | ||
1553 | lock_page(page); | ||
1554 | |||
1555 | /* Did it get truncated? */ | ||
1556 | if (unlikely(page->mapping != mapping)) { | ||
1557 | unlock_page(page); | ||
1558 | put_page(page); | ||
1559 | goto retry_find; | ||
1560 | } | ||
1561 | VM_BUG_ON(page->index != offset); | ||
1562 | |||
1561 | /* | 1563 | /* |
1562 | * We have a locked page in the page cache, now we need to check | 1564 | * We have a locked page in the page cache, now we need to check |
1563 | * that it's up-to-date. If not, it is going to be due to an error. | 1565 | * that it's up-to-date. If not, it is going to be due to an error. |