2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-30 13:58:34 +00:00

mount: Extend phys_stat_dev_match to use path resolving instead of btrfs engine

Instead of scanning btrfs subvolumes (which can be even unaccessbile
if mount point lays on directory instead of subvolume itself) we use
path resolving feature here -- once we need to figure out if some
device number need to be altered up to mount point (as we know stat()
called on subvolume returns st_dev for subvolume itself, but not
one that associated with a superblock and shown in /proc/self/mountinfo
output).

This as well implies that we need to check if device number for ghost
files are to be updated to match mountinfo, thus we use phys_stat_resolve_dev
helper here.

After this patch the previously merged btrfs engine is no longer needed
(at least it seems so) and can be dropped.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
Cyrill Gorcunov
2013-12-07 00:41:48 +04:00
committed by Pavel Emelyanov
parent 5372e3910c
commit 1ba08ca664
4 changed files with 8 additions and 13 deletions

View File

@@ -270,7 +270,7 @@ struct file_remap *lookup_ghost_remap(u32 dev, u32 ino)
mutex_lock(ghost_file_mutex); mutex_lock(ghost_file_mutex);
list_for_each_entry(gf, &ghost_files, list) { 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++; gf->remap.users++;
mutex_unlock(ghost_file_mutex); mutex_unlock(ghost_file_mutex);
return &gf->remap; return &gf->remap;
@@ -285,6 +285,7 @@ static int dump_ghost_remap(char *path, const struct stat *st, int lfd, u32 id)
{ {
struct ghost_file *gf; struct ghost_file *gf;
RemapFilePathEntry rpe = REMAP_FILE_PATH_ENTRY__INIT; RemapFilePathEntry rpe = REMAP_FILE_PATH_ENTRY__INIT;
dev_t phys_dev = phys_stat_resolve_dev(st->st_dev, path);
pr_info("Dumping ghost file for fd %d id %#x\n", lfd, id); pr_info("Dumping ghost file for fd %d id %#x\n", lfd, id);
@@ -295,14 +296,14 @@ static int dump_ghost_remap(char *path, const struct stat *st, int lfd, u32 id)
} }
list_for_each_entry(gf, &ghost_files, list) list_for_each_entry(gf, &ghost_files, list)
if ((gf->dev == st->st_dev) && (gf->ino == st->st_ino)) if ((gf->dev == phys_dev) && (gf->ino == st->st_ino))
goto dump_entry; goto dump_entry;
gf = xmalloc(sizeof(*gf)); gf = xmalloc(sizeof(*gf));
if (gf == NULL) if (gf == NULL)
return -1; return -1;
gf->dev = st->st_dev; gf->dev = phys_dev;
gf->ino = st->st_ino; gf->ino = st->st_ino;
gf->id = ghost_file_ids++; gf->id = ghost_file_ids++;
list_add_tail(&gf->list, &ghost_files); list_add_tail(&gf->list, &ghost_files);

View File

@@ -23,6 +23,6 @@ extern struct mount_info *lookup_mnt_sdev(unsigned int s_dev);
extern struct ns_desc mnt_ns_desc; extern struct ns_desc mnt_ns_desc;
extern dev_t phys_stat_resolve_dev(dev_t st_dev, const char *path); 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); extern bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev, const char *path);
#endif /* __CR_MOUNT_H__ */ #endif /* __CR_MOUNT_H__ */

10
mount.c
View File

@@ -159,17 +159,11 @@ dev_t phys_stat_resolve_dev(dev_t st_dev, const char *path)
return strcmp(m->fstype->name, "btrfs") ? st_dev : m->s_dev; return strcmp(m->fstype->name, "btrfs") ? st_dev : m->s_dev;
} }
bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev) bool phys_stat_dev_match(dev_t st_dev, dev_t phys_dev, const char *path)
{ {
if (st_dev == phys_dev) if (st_dev == phys_dev)
return true; return true;
return phys_dev == phys_stat_resolve_dev(st_dev, path);
/*
* BTRFS returns subvolume dev-id instead of
* superblock dev-id so we might need additional
* tests here.
*/
return is_btrfs_subvol(phys_dev, st_dev);
} }
/* /*

View File

@@ -355,7 +355,7 @@ static int unix_collect_one(const struct unix_diag_msg *m,
} }
if ((st.st_ino != uv->udiag_vfs_ino) || 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 " pr_info("unix: Dropping path %s for "
"unlinked bound " "unlinked bound "
"sk %#x.%#x real %#x.%#x\n", "sk %#x.%#x real %#x.%#x\n",