Commit 1ba08ca6 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

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: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 5372e391
...@@ -270,7 +270,7 @@ struct file_remap *lookup_ghost_remap(u32 dev, u32 ino) ...@@ -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) ...@@ -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) ...@@ -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); ...@@ -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__ */
...@@ -159,17 +159,11 @@ dev_t phys_stat_resolve_dev(dev_t st_dev, const char *path) ...@@ -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, ...@@ -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",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment