aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
authorHugh Dickins <hugh.dickins@tiscali.co.uk>2009-09-21 20:03:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-22 10:17:40 -0400
commitf3e8fccd06d27773186a0094371daf2d84c79469 (patch)
tree46e652e6ac3588a26c6d3e38ea10274eb3fc2ea8 /mm/memory.c
parent1c3aff1ceec2cc86810e2690e67873ff0c505862 (diff)
mm: add get_dump_page
In preparation for the next patch, add a simple get_dump_page(addr) interface for the CONFIG_ELF_CORE dumpers to use, instead of calling get_user_pages() directly. They're not interested in errors: they just want to use holes as much as possible, to save space and make sure that the data is aligned where the headers said it would be. Oh, and don't use that horrid DUMP_SEEK(off) macro! Signed-off-by: Hugh Dickins <hugh.dickins@tiscali.co.uk> Acked-by: Rik van Riel <riel@redhat.com> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Nick Piggin <npiggin@suse.de> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Minchan Kim <minchan.kim@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/mm/memory.c b/mm/memory.c
index 4b5200f5f35a..a8430ff13837 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1423,9 +1423,40 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
1423 1423
1424 return __get_user_pages(tsk, mm, start, nr_pages, flags, pages, vmas); 1424 return __get_user_pages(tsk, mm, start, nr_pages, flags, pages, vmas);
1425} 1425}
1426
1427EXPORT_SYMBOL(get_user_pages); 1426EXPORT_SYMBOL(get_user_pages);
1428 1427
1428/**
1429 * get_dump_page() - pin user page in memory while writing it to core dump
1430 * @addr: user address
1431 *
1432 * Returns struct page pointer of user page pinned for dump,
1433 * to be freed afterwards by page_cache_release() or put_page().
1434 *
1435 * Returns NULL on any kind of failure - a hole must then be inserted into
1436 * the corefile, to preserve alignment with its headers; and also returns
1437 * NULL wherever the ZERO_PAGE, or an anonymous pte_none, has been found -
1438 * allowing a hole to be left in the corefile to save diskspace.
1439 *
1440 * Called without mmap_sem, but after all other threads have been killed.
1441 */
1442#ifdef CONFIG_ELF_CORE
1443struct page *get_dump_page(unsigned long addr)
1444{
1445 struct vm_area_struct *vma;
1446 struct page *page;
1447
1448 if (__get_user_pages(current, current->mm, addr, 1,
1449 GUP_FLAGS_FORCE, &page, &vma) < 1)
1450 return NULL;
1451 if (page == ZERO_PAGE(0)) {
1452 page_cache_release(page);
1453 return NULL;
1454 }
1455 flush_cache_page(vma, addr, page_to_pfn(page));
1456 return page;
1457}
1458#endif /* CONFIG_ELF_CORE */
1459
1429pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, 1460pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr,
1430 spinlock_t **ptl) 1461 spinlock_t **ptl)
1431{ 1462{