[CRIU] [PATCH] vma: don't skip vmas during searching a parent vma

Andrey Vagin avagin at openvz.org
Tue May 13 05:25:13 PDT 2014


We stop searching if vma->start is bigger than a required one.
The coursor is set on the last examined vma. When we are searching a
parent vma for the next vma, we start examine vma-s starting from
coursor->next, so we don't examine the vma, which is pointed by cursor.

This patch replaces list_for_each_entry_continue on list_for_each_entry_from.

Reported-by: Filipe Brandenburger <filbranden at google.com>
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-restore.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index 91cce50..530d2c4 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -239,7 +239,7 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void **tgt_addr,
 	if (vma->page_bitmap == NULL)
 		return -1;
 
-	list_for_each_entry_continue(p, pvma_list, list) {
+	list_for_each_entry_from(p, pvma_list, list) {
 		if (p->e->start > vma->e->start)
 			 break;
 
@@ -265,8 +265,6 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void **tgt_addr,
 		break;
 	}
 
-	*pvma = p;
-
 	/*
 	 * A grow-down VMA has a guard page, which protect a VMA below it.
 	 * So one more page is mapped here to restore content of the first page
@@ -295,6 +293,8 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void **tgt_addr,
 			pr_perror("Unable to map ANON_VMA");
 			return -1;
 		}
+
+		*pvma = p;
 	} else {
 		/*
 		 * This region was found in parent -- remap it to inherit physical
@@ -309,6 +309,7 @@ static int map_private_vma(pid_t pid, struct vma_area *vma, void **tgt_addr,
 			return -1;
 		}
 
+		*pvma = list_entry(p->list.next, struct vma_area, list);
 	}
 
 	vma->premmaped_addr = (unsigned long) addr;
@@ -508,7 +509,7 @@ static int prepare_mappings(int pid)
 	current->rst->premmapped_addr = addr;
 	current->rst->premmapped_len = vmas->priv_size;
 
-	pvma = list_entry(parent_vmas, struct vma_area, list);
+	pvma = list_first_entry(parent_vmas, struct vma_area, list);
 
 	list_for_each_entry(vma, &vmas->h, list) {
 		if (pstart > vma->e->start) {
-- 
1.8.5.3



More information about the CRIU mailing list