[CRIU] [PATCH 1/2] mount: Use path resolving to find mount points
Cyrill Gorcunov
gorcunov at openvz.org
Thu Dec 5 12:09:03 PST 2013
Instead of btrfs engine lets use path resolving feature.
Once we find that there is some device which dev_t doesn't
match one obtained from stat call we resolve path to a
mountpoint and if mountpoint is laying on btrfs we use
mount's dev_t for matching (because subvolumes may be
not always reachable from chroot'ed environment).
We use slow lookup here but it will be improved once
all things settle down.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
Pavel, what do you think, what is the preferred way would be
to speedup the things? Note this patch actually makes btrfs engine
obsolete ;)
files-reg.c | 2 +-
include/mount.h | 2 +-
mount.c | 49 ++++++++++++++++++++++++++++++++++++++++++-------
sk-unix.c | 2 +-
4 files changed, 45 insertions(+), 10 deletions(-)
diff --git a/files-reg.c b/files-reg.c
index 728979d266d7..715000d06d49 100644
--- a/files-reg.c
+++ b/files-reg.c
@@ -270,7 +270,7 @@ struct file_remap *lookup_ghost_remap(u32 dev, u32 ino)
mutex_lock(ghost_file_mutex);
list_for_each_entry(gf, &ghost_files, list) {
- if (phys_stat_dev_match(gf->dev, dev) && gf->ino == ino) {
+ if (gf->ino == ino && phys_stat_dev_match(gf->dev, dev, gf->remap.path)) {
gf->remap.users++;
mutex_unlock(ghost_file_mutex);
return &gf->remap;
diff --git a/include/mount.h b/include/mount.h
index 3e4508715c79..b64673c3801d 100644
--- a/include/mount.h
+++ b/include/mount.h
@@ -22,6 +22,6 @@ extern struct mount_info *lookup_mnt_sdev(unsigned int s_dev);
extern struct ns_desc mnt_ns_desc;
-extern bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev);
+extern bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev, const char *path);
#endif /* __CR_MOUNT_H__ */
diff --git a/mount.c b/mount.c
index 3c85cb036619..23d62da527e3 100644
--- a/mount.c
+++ b/mount.c
@@ -98,17 +98,52 @@ struct mount_info *lookup_mnt_sdev(unsigned int s_dev)
return NULL;
}
-bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev)
+static struct mount_info *mount_resolve_path(const char *path)
{
- if (st_dev == phys_dev)
- return true;
+ struct mount_info *m, *best = NULL, *root = NULL;
+ size_t pathlen = strlen(path);
+ size_t bestlen = PATH_MAX;
/*
- * BTRFS returns subvolume dev-id instead of
- * superblock dev-id so we might need additional
- * tests here.
+ * Find suitable mount point for a @path.
+ *
+ * FIXME We need some fast path resolving algorithm here.
+ * For a while stick with stupid matches.
*/
- return is_btrfs_subvol(phys_dev, st_dev);
+ for (m = mntinfo; m; m = m->next) {
+ size_t n = strlen(m->mountpoint);
+
+ if (!strncmp(m->mountpoint, path, min(n, pathlen))) {
+ if (bestlen > n && !is_root_mount(m)) {
+ best = m;
+ bestlen = n;
+ }
+ if (is_root_mount(m))
+ root = m;
+ }
+ }
+
+ if (!best) {
+ BUG_ON(!root);
+ best = root;
+ }
+
+ pr_debug("Path `%s' resolved to `%s' mountpoint\n", path, best->mountpoint);
+ return best;
+}
+
+bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev, const char *path)
+{
+ struct mount_info *m;
+
+ if (st_dev == phys_dev)
+ return true;
+
+ m = mount_resolve_path(path);
+
+ if (!strcmp(m->fstype->name, "btrfs"))
+ return m->s_dev == phys_dev;
+ return false;
}
/*
diff --git a/sk-unix.c b/sk-unix.c
index df07999d9aa9..21d2de746454 100644
--- a/sk-unix.c
+++ b/sk-unix.c
@@ -355,7 +355,7 @@ static int unix_collect_one(const struct unix_diag_msg *m,
}
if ((st.st_ino != uv->udiag_vfs_ino) ||
- !phys_stat_dev_match(st.st_dev, kdev_to_odev(uv->udiag_vfs_dev))) {
+ !phys_stat_dev_match(st.st_dev, kdev_to_odev(uv->udiag_vfs_dev), name)) {
pr_info("unix: Dropping path %s for "
"unlinked bound "
"sk %#x.%#x real %#x.%#x\n",
--
1.8.3.1
More information about the CRIU
mailing list