[v3,1/5] mount: save the result of mnt_is_overmounted

Submitted by Pavel Tikhomirov on Sept. 27, 2018, 9:17 a.m.

Details

Message ID 20180927091736.10727-2-ptikhomirov@virtuozzo.com
State New
Series "support restoring ghost files on readonly mounts"
Headers show

Commit Message

Pavel Tikhomirov Sept. 27, 2018, 9:17 a.m.
On restore we change mounts tree topology and paths in find_remap_mounts
thus mns_is_overmounted does not account remaped overmounts. So to know
which mounts will be actually overmounted after restore we need two much
effort, better prepare these info in advance.

That also should improve performance of mnt_is_overmounted on dump,
as we reuse calculations from previous calls.

v3: make mnt_is_overmounted boolean again

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
 criu/include/mount.h |  2 ++
 criu/mount.c         | 34 +++++++++++++++++++++++++++++-----
 2 files changed, 31 insertions(+), 5 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/mount.h b/criu/include/mount.h
index ca17b059a..e7d026264 100644
--- a/criu/include/mount.h
+++ b/criu/include/mount.h
@@ -70,6 +70,8 @@  struct mount_info {
 
 	struct list_head	postpone;
 
+	int			is_overmounted;
+
 	void			*private;	/* associated filesystem data */
 };
 
diff --git a/criu/mount.c b/criu/mount.c
index 218facb76..29370afc7 100644
--- a/criu/mount.c
+++ b/criu/mount.c
@@ -1156,13 +1156,25 @@  static bool mnt_is_overmounted(struct mount_info *mi)
 {
 	struct mount_info *t, *c, *m = mi;
 
+	if (mi->is_overmounted != -1)
+		goto exit;
+
+	mi->is_overmounted = 0;
+
 	while (m->parent) {
+		if (mi->parent->is_overmounted == 1) {
+			mi->is_overmounted = 1;
+			goto exit;
+		}
+
 		/* Check there is no sibling-overmount */
 		list_for_each_entry(t, &m->parent->children, siblings) {
 			if (m == t)
 				continue;
-			if (issubpath(m->mountpoint, t->mountpoint))
-				return true;
+			if (issubpath(m->mountpoint, t->mountpoint)) {
+				mi->is_overmounted = 1;
+				goto exit;
+			}
 		}
 
 		/*
@@ -1175,10 +1187,19 @@  static bool mnt_is_overmounted(struct mount_info *mi)
 
 	/* Check there is no children-overmount */
 	list_for_each_entry(c, &mi->children, siblings)
-		if (!strcmp(c->mountpoint, mi->mountpoint))
-			return true;
+		if (!strcmp(c->mountpoint, mi->mountpoint)) {
+			mi->is_overmounted = 1;
+			goto exit;
+		}
 
-	return false;
+exit:
+	return mi->is_overmounted;
+}
+
+static int set_is_overmounted(struct mount_info *mi)
+{
+	mnt_is_overmounted(mi);
+	return 0;
 }
 
 /*
@@ -2723,6 +2744,7 @@  struct mount_info *mnt_entry_alloc()
 	new = xzalloc(sizeof(struct mount_info));
 	if (new) {
 		new->fd = -1;
+		new->is_overmounted = -1;
 		INIT_LIST_HEAD(&new->children);
 		INIT_LIST_HEAD(&new->siblings);
 		INIT_LIST_HEAD(&new->mnt_slave_list);
@@ -3160,6 +3182,8 @@  static int populate_mnt_ns(void)
 	if (validate_mounts(mntinfo, false))
 		return -1;
 
+	mnt_tree_for_each(pms, set_is_overmounted);
+
 	if (find_remap_mounts(pms))
 		return -1;