diff options
| -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 | ||||
| -rw-r--r-- | include/linux/kernfs.h | 4 |
4 files changed, 21 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. |
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index b0122dc6f96a..589318b73e61 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h | |||
| @@ -144,6 +144,10 @@ struct kernfs_root { | |||
| 144 | /* private fields, do not use outside kernfs proper */ | 144 | /* private fields, do not use outside kernfs proper */ |
| 145 | struct ida ino_ida; | 145 | struct ida ino_ida; |
| 146 | struct kernfs_syscall_ops *syscall_ops; | 146 | struct kernfs_syscall_ops *syscall_ops; |
| 147 | |||
| 148 | /* list of kernfs_super_info of this root, protected by kernfs_mutex */ | ||
| 149 | struct list_head supers; | ||
| 150 | |||
| 147 | wait_queue_head_t deactivate_waitq; | 151 | wait_queue_head_t deactivate_waitq; |
| 148 | }; | 152 | }; |
| 149 | 153 | ||
