[CRIU] [PATCH 3/4] mount: btrfs -- Introduce phys_stat_resolve_dev helper (v2)

Andrew Vagin avagin at openvz.org
Tue Dec 10 21:04:14 PST 2013


From: Cyrill Gorcunov <gorcunov at openvz.org>

This routine is aimed to find a mount point on which
the path passed as argument is laying on. We walk over
all mount points and see which one is matching.

Once found (in worst case it will be a root mount point
so function is never failing) we're checking if this is
btrfs and then return subvolume0 device id.

See commit 921cf873f30ad35df2b65602ed402f94695a6eb3
for details what the hell we're doing here.

v2: rewrite mount_resolve_path w/o recursion

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
Signed-off-by: Andrew Vagin <avagin at openvz.org>
---
 include/mount.h |  1 +
 mount.c         | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/include/mount.h b/include/mount.h
index 9b29af2..30cedd5 100644
--- a/include/mount.h
+++ b/include/mount.h
@@ -22,6 +22,7 @@ extern struct mount_info *lookup_mnt_sdev(unsigned int s_dev);
 
 extern struct ns_desc mnt_ns_desc;
 
+extern dev_t phys_stat_resolve_dev(dev_t st_dev, const char *path);
 extern bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev);
 
 #endif /* __CR_MOUNT_H__ */
diff --git a/mount.c b/mount.c
index ca47e3d..75160ae 100644
--- a/mount.c
+++ b/mount.c
@@ -121,6 +121,44 @@ struct mount_info *lookup_mnt_sdev(unsigned int s_dev)
 	return NULL;
 }
 
+static struct mount_info *mount_resolve_path(const char *path)
+{
+	size_t pathlen = strlen(path);
+	struct mount_info *m = mntinfo_tree, *c;
+
+	while (1) {
+		list_for_each_entry(c, &m->children, siblings) {
+			size_t n;
+
+			n = strlen(c->mountpoint);
+			if (n > pathlen)
+				continue;
+
+			if (strncmp(c->mountpoint, path, min(n, pathlen)))
+				continue;
+
+			m = c;
+			break;
+		}
+		if (&c->siblings == &m->children)
+			break;
+	}
+
+	pr_debug("Path `%s' resolved to `%s' mountpoint\n", path, m->mountpoint);
+	return m;
+}
+
+dev_t phys_stat_resolve_dev(dev_t st_dev, const char *path)
+{
+	struct mount_info *m = mount_resolve_path(path);
+	/*
+	 * BTRFS returns subvolume dev-id instead of
+	 * superblock dev-id, in such case return device
+	 * obtained from mountinfo (ie subvolume0).
+	 */
+	return strcmp(m->fstype->name, "btrfs") ? st_dev : m->s_dev;
+}
+
 bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev)
 {
 	if (st_dev == phys_dev)
-- 
1.8.3.1



More information about the CRIU mailing list