diff options
author | Tejun Heo <tj@kernel.org> | 2014-04-09 11:07:30 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-04-25 14:43:31 -0400 |
commit | 7d568a8383bbb9c1f5167781075906acb2bb1550 (patch) | |
tree | f25a2d70ce8851e991a53ed6391c899320f097a6 /fs | |
parent | a798c10faf62a505d24e5f6213fbaf904a39623f (diff) |
kernfs: implement kernfs_root->supers list
Currently, there's no way to find out which super_blocks are
associated with a given kernfs_root. Let's implement it - the planned
inotify extension to kernfs_notify() needs it.
Make kernfs_super_info point back to the super_block and chain it at
kernfs_root->supers.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/kernfs/dir.c | 1 | ||||
-rw-r--r-- | fs/kernfs/kernfs-internal.h | 5 | ||||
-rw-r--r-- | fs/kernfs/mount.c | 11 |
3 files changed, 17 insertions, 0 deletions
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 78f3403300af..43aa97988c31 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c | |||
@@ -711,6 +711,7 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops, | |||
711 | return ERR_PTR(-ENOMEM); | 711 | return ERR_PTR(-ENOMEM); |
712 | 712 | ||
713 | ida_init(&root->ino_ida); | 713 | ida_init(&root->ino_ida); |
714 | INIT_LIST_HEAD(&root->supers); | ||
714 | 715 | ||
715 | kn = __kernfs_new_node(root, "", S_IFDIR | S_IRUGO | S_IXUGO, | 716 | kn = __kernfs_new_node(root, "", S_IFDIR | S_IRUGO | S_IXUGO, |
716 | KERNFS_DIR); | 717 | KERNFS_DIR); |
diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 8be13b2a079b..dc84a3ef9ca2 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h | |||
@@ -49,6 +49,8 @@ static inline struct kernfs_root *kernfs_root(struct kernfs_node *kn) | |||
49 | * mount.c | 49 | * mount.c |
50 | */ | 50 | */ |
51 | struct kernfs_super_info { | 51 | struct kernfs_super_info { |
52 | struct super_block *sb; | ||
53 | |||
52 | /* | 54 | /* |
53 | * The root associated with this super_block. Each super_block is | 55 | * The root associated with this super_block. Each super_block is |
54 | * identified by the root and ns it's associated with. | 56 | * identified by the root and ns it's associated with. |
@@ -62,6 +64,9 @@ struct kernfs_super_info { | |||
62 | * an array and compare kernfs_node tag against every entry. | 64 | * an array and compare kernfs_node tag against every entry. |
63 | */ | 65 | */ |
64 | const void *ns; | 66 | const void *ns; |
67 | |||
68 | /* anchored at kernfs_root->supers, protected by kernfs_mutex */ | ||
69 | struct list_head node; | ||
65 | }; | 70 | }; |
66 | #define kernfs_info(SB) ((struct kernfs_super_info *)(SB->s_fs_info)) | 71 | #define kernfs_info(SB) ((struct kernfs_super_info *)(SB->s_fs_info)) |
67 | 72 | ||
diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index 6a5f04ac8704..f25a7c0c3cdc 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c | |||
@@ -68,6 +68,7 @@ static int kernfs_fill_super(struct super_block *sb) | |||
68 | struct inode *inode; | 68 | struct inode *inode; |
69 | struct dentry *root; | 69 | struct dentry *root; |
70 | 70 | ||
71 | info->sb = sb; | ||
71 | sb->s_blocksize = PAGE_CACHE_SIZE; | 72 | sb->s_blocksize = PAGE_CACHE_SIZE; |
72 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 73 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; |
73 | sb->s_magic = SYSFS_MAGIC; | 74 | sb->s_magic = SYSFS_MAGIC; |
@@ -166,12 +167,18 @@ struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, | |||
166 | *new_sb_created = !sb->s_root; | 167 | *new_sb_created = !sb->s_root; |
167 | 168 | ||
168 | if (!sb->s_root) { | 169 | if (!sb->s_root) { |
170 | struct kernfs_super_info *info = kernfs_info(sb); | ||
171 | |||
169 | error = kernfs_fill_super(sb); | 172 | error = kernfs_fill_super(sb); |
170 | if (error) { | 173 | if (error) { |
171 | deactivate_locked_super(sb); | 174 | deactivate_locked_super(sb); |
172 | return ERR_PTR(error); | 175 | return ERR_PTR(error); |
173 | } | 176 | } |
174 | sb->s_flags |= MS_ACTIVE; | 177 | sb->s_flags |= MS_ACTIVE; |
178 | |||
179 | mutex_lock(&kernfs_mutex); | ||
180 | list_add(&info->node, &root->supers); | ||
181 | mutex_unlock(&kernfs_mutex); | ||
175 | } | 182 | } |
176 | 183 | ||
177 | return dget(sb->s_root); | 184 | return dget(sb->s_root); |
@@ -190,6 +197,10 @@ void kernfs_kill_sb(struct super_block *sb) | |||
190 | struct kernfs_super_info *info = kernfs_info(sb); | 197 | struct kernfs_super_info *info = kernfs_info(sb); |
191 | struct kernfs_node *root_kn = sb->s_root->d_fsdata; | 198 | struct kernfs_node *root_kn = sb->s_root->d_fsdata; |
192 | 199 | ||
200 | mutex_lock(&kernfs_mutex); | ||
201 | list_del(&info->node); | ||
202 | mutex_unlock(&kernfs_mutex); | ||
203 | |||
193 | /* | 204 | /* |
194 | * Remove the superblock from fs_supers/s_instances | 205 | * Remove the superblock from fs_supers/s_instances |
195 | * so we can't find it, before freeing kernfs_super_info. | 206 | * so we can't find it, before freeing kernfs_super_info. |