From: Hugh Dickins <hugh@veritas.com>

Clean up mremap move's copy_one_pte:

- get_one_pte_map_nested already weeded out the pte_none case,
  now don't even call copy_one_pte if it has nothing to do.

- check pfn_valid before passing page to page_remove_rmap.


---

 25-akpm/mm/mremap.c |   31 ++++++++++++-------------------
 1 files changed, 12 insertions(+), 19 deletions(-)

diff -puN mm/mremap.c~mremap-copy_one_pte-fix mm/mremap.c
--- 25/mm/mremap.c~mremap-copy_one_pte-fix	Tue Mar 30 16:04:14 2004
+++ 25-akpm/mm/mremap.c	Tue Mar 30 16:04:14 2004
@@ -79,31 +79,21 @@ static inline pte_t *alloc_one_pte_map(s
 	return pte;
 }
 
-static int
+static void
 copy_one_pte(struct vm_area_struct *vma, unsigned long old_addr,
 	     pte_t *src, pte_t *dst, struct pte_chain **pte_chainp)
 {
-	int error = 0;
-	pte_t pte;
-	struct page *page = NULL;
-
-	if (pte_present(*src))
-		page = pte_page(*src);
+	pte_t pte = ptep_clear_flush(vma, old_addr, src);
+	set_pte(dst, pte);
 
-	if (!pte_none(*src)) {
-		if (page)
+	if (pte_present(pte)) {
+		unsigned long pfn = pte_pfn(pte);
+		if (pfn_valid(pfn)) {
+			struct page *page = pfn_to_page(pfn);
 			page_remove_rmap(page, src);
-		pte = ptep_clear_flush(vma, old_addr, src);
-		if (!dst) {
-			/* No dest?  We must put it back. */
-			dst = src;
-			error++;
-		}
-		set_pte(dst, pte);
-		if (page)
 			*pte_chainp = page_add_rmap(page, dst, *pte_chainp);
+		}
 	}
-	return error;
 }
 
 static int
@@ -140,8 +130,11 @@ move_one_page(struct vm_area_struct *vma
 		 * page_table_lock, we should re-check the src entry...
 		 */
 		if (src) {
-			error = copy_one_pte(vma, old_addr, src,
+			if (dst)
+				copy_one_pte(vma, old_addr, src,
 						dst, &pte_chain);
+			else
+				error = -ENOMEM;
 			pte_unmap_nested(src);
 		}
 		pte_unmap(dst);

_