vfsmountの検証
vfsmount構造体のパスリンクに掛かる情報は以下のとうりで、実際この内容を検証してみました。
struct vfsmount {
struct dentry *mnt_root; /* root of the mounted tree */
:
};
struct mount {
struct mount *mnt_parent;
struct dentry *mnt_mountpoint;
struct vfsmount mnt;
const char *mnt_devname;
:
};
/tmp/hoge0に/dev/loop0をマウントし、/tmp/hoge0/hoge1に/dev/loop1をマウントした状態の/dev/loop1のvfsmount構造体の内容です。[root@localhost lkm]# mount /home/kitamura/lkm/disk/disk0 on /tmp/hoge0 type ext2 /home/kitamura/lkm/disk/disk1 on /tmp/hoge0/hoge1 type ext2
#include <linux/kernel.h>
#include <linux/namei.h>
#include <linux/mnt_namespace.h>
#include <linux/mount.h>
struct mount {
struct list_head mnt_hash;
struct mount *mnt_parent;
struct dentry *mnt_mountpoint;
struct vfsmount mnt;
int mnt_count;
int mnt_writers;
struct list_head mnt_mounts; /* list of children, anchored here */
struct list_head mnt_child; /* and going through their mnt_child */
struct list_head mnt_instance; /* mount instance on sb->s_mounts */
const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
struct list_head mnt_list;
struct list_head mnt_expire; /* link in fs-specific expiry list */
struct list_head mnt_share; /* circular list of shared mounts */
struct list_head mnt_slave_list;/* list of slave mounts */
struct list_head mnt_slave; /* slave list entry */
struct mount *mnt_master; /* slave is on master->mnt_slave_list */
struct mnt_namespace *mnt_ns; /* containing namespace */
int mnt_id; /* mount identifier */
int mnt_group_id; /* peer group identifier */
int mnt_expiry_mark; /* true if marked for expiry */
int mnt_pinned;
int mnt_ghosts;
};
static inline struct mount *real_mount(struct vfsmount *mnt)
{
return container_of(mnt, struct mount, mnt);
}
void get_mntchild(struct mount *r_mnt)
{
struct mount *i;
int act = 0;
list_for_each_entry(i, &r_mnt->mnt_mounts, mnt_child) {
act = 1;
printk("child:%s\n", i->mnt_devname);
}
if (act == 0) {
printk("child:no\n");
}
}
void get_mntinfo(char *pathname)
{
struct path path;
struct mount *r_mnt;
int err;
printk("%s\n", pathname);
err = kern_path(pathname, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);
if (err) {
printk("err\n");
}
else {
r_mnt = real_mount(path.mnt);
printk("devname:%s\n",r_mnt->mnt_devname);
printk("root:%s\n", path.mnt->mnt_root->d_name.name);
printk("parent:%s\n",r_mnt->mnt_parent->mnt_devname);
printk("mountpoint:%s\n",r_mnt->mnt_mountpoint->d_name.name);
get_mntchild(r_mnt);
printk("----------\n");
path_put(&path);
}
}
int init_module(void)
{
get_mntinfo("/tmp/hoge0");
get_mntinfo("/tmp/hoge0/hoge1");
return 0;
}
void cleanup_module(void)
{
}
期待通りの結果となりました。[root@localhost lkm]# dmesg : [39913.089605] /tmp/hoge0 [39913.089629] devname:/dev/loop0 [39913.089634] root:/ <- [39913.089639] parent:/dev/mapper/VolGroup-lv_root [39913.089644] mountpoint:hoge0 [39913.089649] child:/dev/loop1 [39913.089652] ---------- [39913.089657] /tmp/hoge0/hoge1 [39913.089665] devname:/dev/loop1 [39913.089670] root:/ [39913.089673] parent:/dev/loop0 [39913.089677] mountpoint:hoge1 [39913.089681] child:noroot:はmountのマウント元で、bindオプションによって変わります。




