From 1ba08ca6646800927e2c47119f2281858672c20b Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Sat, 7 Dec 2013 00:41:48 +0400 Subject: [PATCH] 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 Signed-off-by: Pavel Emelyanov --- files-reg.c | 7 ++++--- include/mount.h | 2 +- mount.c | 10 ++-------- sk-unix.c | 2 +- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/files-reg.c b/files-reg.c index 728979d26..ca12b8b2a 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; @@ -285,6 +285,7 @@ static int dump_ghost_remap(char *path, const struct stat *st, int lfd, u32 id) { struct ghost_file *gf; 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); @@ -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) - if ((gf->dev == st->st_dev) && (gf->ino == st->st_ino)) + if ((gf->dev == phys_dev) && (gf->ino == st->st_ino)) goto dump_entry; gf = xmalloc(sizeof(*gf)); if (gf == NULL) return -1; - gf->dev = st->st_dev; + gf->dev = phys_dev; gf->ino = st->st_ino; gf->id = ghost_file_ids++; list_add_tail(&gf->list, &ghost_files); diff --git a/include/mount.h b/include/mount.h index 30cedd54e..dade585c7 100644 --- a/include/mount.h +++ b/include/mount.h @@ -23,6 +23,6 @@ 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); +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 75160ae66..e1010bfc5 100644 --- a/mount.c +++ b/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; } -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) return true; - - /* - * 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); + return phys_dev == phys_stat_resolve_dev(st_dev, path); } /* diff --git a/sk-unix.c b/sk-unix.c index df07999d9..21d2de746 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",