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:
committed by
Pavel Emelyanov
parent
5372e3910c
commit
1ba08ca664
@@ -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);
|
||||||
|
@@ -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
10
mount.c
@@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -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",
|
||||||
|
Reference in New Issue
Block a user