diff options
Diffstat (limited to 'fs/sysfs')
-rw-r--r-- | fs/sysfs/mount.c | 58 | ||||
-rw-r--r-- | fs/sysfs/sysfs.h | 3 |
2 files changed, 59 insertions, 2 deletions
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 776137828dca..db0b1f2138af 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -72,16 +72,70 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent) | |||
72 | return 0; | 72 | return 0; |
73 | } | 73 | } |
74 | 74 | ||
75 | static int sysfs_test_super(struct super_block *sb, void *data) | ||
76 | { | ||
77 | struct sysfs_super_info *sb_info = sysfs_info(sb); | ||
78 | struct sysfs_super_info *info = data; | ||
79 | int found = 1; | ||
80 | return found; | ||
81 | } | ||
82 | |||
83 | static int sysfs_set_super(struct super_block *sb, void *data) | ||
84 | { | ||
85 | int error; | ||
86 | error = set_anon_super(sb, data); | ||
87 | if (!error) | ||
88 | sb->s_fs_info = data; | ||
89 | return error; | ||
90 | } | ||
91 | |||
75 | static int sysfs_get_sb(struct file_system_type *fs_type, | 92 | static int sysfs_get_sb(struct file_system_type *fs_type, |
76 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) | 93 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) |
77 | { | 94 | { |
78 | return get_sb_single(fs_type, flags, data, sysfs_fill_super, mnt); | 95 | struct sysfs_super_info *info; |
96 | struct super_block *sb; | ||
97 | int error; | ||
98 | |||
99 | error = -ENOMEM; | ||
100 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
101 | if (!info) | ||
102 | goto out; | ||
103 | sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info); | ||
104 | if (IS_ERR(sb) || sb->s_fs_info != info) | ||
105 | kfree(info); | ||
106 | if (IS_ERR(sb)) { | ||
107 | kfree(info); | ||
108 | error = PTR_ERR(sb); | ||
109 | goto out; | ||
110 | } | ||
111 | if (!sb->s_root) { | ||
112 | sb->s_flags = flags; | ||
113 | error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); | ||
114 | if (error) { | ||
115 | deactivate_locked_super(sb); | ||
116 | goto out; | ||
117 | } | ||
118 | sb->s_flags |= MS_ACTIVE; | ||
119 | } | ||
120 | |||
121 | simple_set_mnt(mnt, sb); | ||
122 | error = 0; | ||
123 | out: | ||
124 | return error; | ||
125 | } | ||
126 | |||
127 | static void sysfs_kill_sb(struct super_block *sb) | ||
128 | { | ||
129 | struct sysfs_super_info *info = sysfs_info(sb); | ||
130 | |||
131 | kill_anon_super(sb); | ||
132 | kfree(info); | ||
79 | } | 133 | } |
80 | 134 | ||
81 | static struct file_system_type sysfs_fs_type = { | 135 | static struct file_system_type sysfs_fs_type = { |
82 | .name = "sysfs", | 136 | .name = "sysfs", |
83 | .get_sb = sysfs_get_sb, | 137 | .get_sb = sysfs_get_sb, |
84 | .kill_sb = kill_anon_super, | 138 | .kill_sb = sysfs_kill_sb, |
85 | }; | 139 | }; |
86 | 140 | ||
87 | int __init sysfs_init(void) | 141 | int __init sysfs_init(void) |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 30f5a44fb5d3..030a39dbb02c 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -114,6 +114,9 @@ struct sysfs_addrm_cxt { | |||
114 | /* | 114 | /* |
115 | * mount.c | 115 | * mount.c |
116 | */ | 116 | */ |
117 | struct sysfs_super_info { | ||
118 | }; | ||
119 | #define sysfs_info(SB) ((struct sysfs_super_info *)(SB->s_fs_info)) | ||
117 | extern struct sysfs_dirent sysfs_root; | 120 | extern struct sysfs_dirent sysfs_root; |
118 | extern struct kmem_cache *sysfs_dir_cachep; | 121 | extern struct kmem_cache *sysfs_dir_cachep; |
119 | 122 | ||