mount.c (2d8ad8719591fa803b0d589ed057fa46f49b7155) mount.c (a685e08987d1edf1995b76511d4c98ea0e905377)
1/*
2 * fs/sysfs/symlink.c - operations for initializing and mounting sysfs
3 *
4 * Copyright (c) 2001-3 Patrick Mochel
5 * Copyright (c) 2007 SUSE Linux Products GmbH
6 * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
7 *
8 * This file is released under the GPLv2.

--- 81 unchanged lines hidden (view full) ---

90{
91 int error;
92 error = set_anon_super(sb, data);
93 if (!error)
94 sb->s_fs_info = data;
95 return error;
96}
97
1/*
2 * fs/sysfs/symlink.c - operations for initializing and mounting sysfs
3 *
4 * Copyright (c) 2001-3 Patrick Mochel
5 * Copyright (c) 2007 SUSE Linux Products GmbH
6 * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
7 *
8 * This file is released under the GPLv2.

--- 81 unchanged lines hidden (view full) ---

90{
91 int error;
92 error = set_anon_super(sb, data);
93 if (!error)
94 sb->s_fs_info = data;
95 return error;
96}
97
98static void free_sysfs_super_info(struct sysfs_super_info *info)
99{
100 int type;
101 for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++)
102 kobj_ns_drop(type, info->ns[type]);
103 kfree(info);
104}
105
98static struct dentry *sysfs_mount(struct file_system_type *fs_type,
99 int flags, const char *dev_name, void *data)
100{
101 struct sysfs_super_info *info;
102 enum kobj_ns_type type;
103 struct super_block *sb;
104 int error;
105
106 info = kzalloc(sizeof(*info), GFP_KERNEL);
107 if (!info)
108 return ERR_PTR(-ENOMEM);
109
110 for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++)
106static struct dentry *sysfs_mount(struct file_system_type *fs_type,
107 int flags, const char *dev_name, void *data)
108{
109 struct sysfs_super_info *info;
110 enum kobj_ns_type type;
111 struct super_block *sb;
112 int error;
113
114 info = kzalloc(sizeof(*info), GFP_KERNEL);
115 if (!info)
116 return ERR_PTR(-ENOMEM);
117
118 for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++)
111 info->ns[type] = kobj_ns_current(type);
119 info->ns[type] = kobj_ns_grab_current(type);
112
113 sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info);
114 if (IS_ERR(sb) || sb->s_fs_info != info)
120
121 sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info);
122 if (IS_ERR(sb) || sb->s_fs_info != info)
115 kfree(info);
123 free_sysfs_super_info(info);
116 if (IS_ERR(sb))
117 return ERR_CAST(sb);
118 if (!sb->s_root) {
119 sb->s_flags = flags;
120 error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
121 if (error) {
122 deactivate_locked_super(sb);
123 return ERR_PTR(error);
124 }
125 sb->s_flags |= MS_ACTIVE;
126 }
127
128 return dget(sb->s_root);
129}
130
131static void sysfs_kill_sb(struct super_block *sb)
132{
133 struct sysfs_super_info *info = sysfs_info(sb);
124 if (IS_ERR(sb))
125 return ERR_CAST(sb);
126 if (!sb->s_root) {
127 sb->s_flags = flags;
128 error = sysfs_fill_super(sb, data, flags & MS_SILENT ? 1 : 0);
129 if (error) {
130 deactivate_locked_super(sb);
131 return ERR_PTR(error);
132 }
133 sb->s_flags |= MS_ACTIVE;
134 }
135
136 return dget(sb->s_root);
137}
138
139static void sysfs_kill_sb(struct super_block *sb)
140{
141 struct sysfs_super_info *info = sysfs_info(sb);
134
135 /* Remove the superblock from fs_supers/s_instances
136 * so we can't find it, before freeing sysfs_super_info.
137 */
138 kill_anon_super(sb);
142 /* Remove the superblock from fs_supers/s_instances
143 * so we can't find it, before freeing sysfs_super_info.
144 */
145 kill_anon_super(sb);
139 kfree(info);
146 free_sysfs_super_info(info);
140}
141
142static struct file_system_type sysfs_fs_type = {
143 .name = "sysfs",
144 .mount = sysfs_mount,
145 .kill_sb = sysfs_kill_sb,
146};
147
147}
148
149static struct file_system_type sysfs_fs_type = {
150 .name = "sysfs",
151 .mount = sysfs_mount,
152 .kill_sb = sysfs_kill_sb,
153};
154
148void sysfs_exit_ns(enum kobj_ns_type type, const void *ns)
149{
150 struct super_block *sb;
151
152 mutex_lock(&sysfs_mutex);
153 spin_lock(&sb_lock);
154 list_for_each_entry(sb, &sysfs_fs_type.fs_supers, s_instances) {
155 struct sysfs_super_info *info = sysfs_info(sb);
156 /*
157 * If we see a superblock on the fs_supers/s_instances
158 * list the unmount has not completed and sb->s_fs_info
159 * points to a valid struct sysfs_super_info.
160 */
161 /* Ignore superblocks with the wrong ns */
162 if (info->ns[type] != ns)
163 continue;
164 info->ns[type] = NULL;
165 }
166 spin_unlock(&sb_lock);
167 mutex_unlock(&sysfs_mutex);
168}
169
170int __init sysfs_init(void)
171{
172 int err = -ENOMEM;
173
174 sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache",
175 sizeof(struct sysfs_dirent),
176 0, 0, NULL);
177 if (!sysfs_dir_cachep)

--- 39 unchanged lines hidden ---
155int __init sysfs_init(void)
156{
157 int err = -ENOMEM;
158
159 sysfs_dir_cachep = kmem_cache_create("sysfs_dir_cache",
160 sizeof(struct sysfs_dirent),
161 0, 0, NULL);
162 if (!sysfs_dir_cachep)

--- 39 unchanged lines hidden ---