Commit 7c6455e368bc87ef38df7b6ddba2339a67107bdf

Authored by Al Viro
1 parent 988f032567

configfs: register_filesystem() called too early

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 2 changed files with 18 additions and 20 deletions Inline Diff

1 /* -*- mode: c; c-basic-offset: 8; -*- 1 /* -*- mode: c; c-basic-offset: 8; -*-
2 * vim: noexpandtab sw=8 ts=8 sts=0: 2 * vim: noexpandtab sw=8 ts=8 sts=0:
3 * 3 *
4 * inode.c - basic inode and dentry operations. 4 * inode.c - basic inode and dentry operations.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public 7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 9 * version 2 of the License, or (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details. 14 * General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public 16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the 17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 021110-1307, USA. 19 * Boston, MA 021110-1307, USA.
20 * 20 *
21 * Based on sysfs: 21 * Based on sysfs:
22 * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel 22 * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
23 * 23 *
24 * configfs Copyright (C) 2005 Oracle. All rights reserved. 24 * configfs Copyright (C) 2005 Oracle. All rights reserved.
25 * 25 *
26 * Please see Documentation/filesystems/configfs/configfs.txt for more 26 * Please see Documentation/filesystems/configfs/configfs.txt for more
27 * information. 27 * information.
28 */ 28 */
29 29
30 #undef DEBUG 30 #undef DEBUG
31 31
32 #include <linux/pagemap.h> 32 #include <linux/pagemap.h>
33 #include <linux/namei.h> 33 #include <linux/namei.h>
34 #include <linux/backing-dev.h> 34 #include <linux/backing-dev.h>
35 #include <linux/capability.h> 35 #include <linux/capability.h>
36 #include <linux/sched.h> 36 #include <linux/sched.h>
37 #include <linux/lockdep.h> 37 #include <linux/lockdep.h>
38 #include <linux/slab.h> 38 #include <linux/slab.h>
39 39
40 #include <linux/configfs.h> 40 #include <linux/configfs.h>
41 #include "configfs_internal.h" 41 #include "configfs_internal.h"
42 42
43 #ifdef CONFIG_LOCKDEP 43 #ifdef CONFIG_LOCKDEP
44 static struct lock_class_key default_group_class[MAX_LOCK_DEPTH]; 44 static struct lock_class_key default_group_class[MAX_LOCK_DEPTH];
45 #endif 45 #endif
46 46
47 extern struct super_block * configfs_sb; 47 extern struct super_block * configfs_sb;
48 48
49 static const struct address_space_operations configfs_aops = { 49 static const struct address_space_operations configfs_aops = {
50 .readpage = simple_readpage, 50 .readpage = simple_readpage,
51 .write_begin = simple_write_begin, 51 .write_begin = simple_write_begin,
52 .write_end = simple_write_end, 52 .write_end = simple_write_end,
53 }; 53 };
54 54
55 static struct backing_dev_info configfs_backing_dev_info = { 55 static struct backing_dev_info configfs_backing_dev_info = {
56 .name = "configfs", 56 .name = "configfs",
57 .ra_pages = 0, /* No readahead */ 57 .ra_pages = 0, /* No readahead */
58 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, 58 .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
59 }; 59 };
60 60
61 static const struct inode_operations configfs_inode_operations ={ 61 static const struct inode_operations configfs_inode_operations ={
62 .setattr = configfs_setattr, 62 .setattr = configfs_setattr,
63 }; 63 };
64 64
65 int configfs_setattr(struct dentry * dentry, struct iattr * iattr) 65 int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
66 { 66 {
67 struct inode * inode = dentry->d_inode; 67 struct inode * inode = dentry->d_inode;
68 struct configfs_dirent * sd = dentry->d_fsdata; 68 struct configfs_dirent * sd = dentry->d_fsdata;
69 struct iattr * sd_iattr; 69 struct iattr * sd_iattr;
70 unsigned int ia_valid = iattr->ia_valid; 70 unsigned int ia_valid = iattr->ia_valid;
71 int error; 71 int error;
72 72
73 if (!sd) 73 if (!sd)
74 return -EINVAL; 74 return -EINVAL;
75 75
76 sd_iattr = sd->s_iattr; 76 sd_iattr = sd->s_iattr;
77 if (!sd_iattr) { 77 if (!sd_iattr) {
78 /* setting attributes for the first time, allocate now */ 78 /* setting attributes for the first time, allocate now */
79 sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL); 79 sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
80 if (!sd_iattr) 80 if (!sd_iattr)
81 return -ENOMEM; 81 return -ENOMEM;
82 /* assign default attributes */ 82 /* assign default attributes */
83 sd_iattr->ia_mode = sd->s_mode; 83 sd_iattr->ia_mode = sd->s_mode;
84 sd_iattr->ia_uid = 0; 84 sd_iattr->ia_uid = 0;
85 sd_iattr->ia_gid = 0; 85 sd_iattr->ia_gid = 0;
86 sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME; 86 sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME;
87 sd->s_iattr = sd_iattr; 87 sd->s_iattr = sd_iattr;
88 } 88 }
89 /* attributes were changed atleast once in past */ 89 /* attributes were changed atleast once in past */
90 90
91 error = simple_setattr(dentry, iattr); 91 error = simple_setattr(dentry, iattr);
92 if (error) 92 if (error)
93 return error; 93 return error;
94 94
95 if (ia_valid & ATTR_UID) 95 if (ia_valid & ATTR_UID)
96 sd_iattr->ia_uid = iattr->ia_uid; 96 sd_iattr->ia_uid = iattr->ia_uid;
97 if (ia_valid & ATTR_GID) 97 if (ia_valid & ATTR_GID)
98 sd_iattr->ia_gid = iattr->ia_gid; 98 sd_iattr->ia_gid = iattr->ia_gid;
99 if (ia_valid & ATTR_ATIME) 99 if (ia_valid & ATTR_ATIME)
100 sd_iattr->ia_atime = timespec_trunc(iattr->ia_atime, 100 sd_iattr->ia_atime = timespec_trunc(iattr->ia_atime,
101 inode->i_sb->s_time_gran); 101 inode->i_sb->s_time_gran);
102 if (ia_valid & ATTR_MTIME) 102 if (ia_valid & ATTR_MTIME)
103 sd_iattr->ia_mtime = timespec_trunc(iattr->ia_mtime, 103 sd_iattr->ia_mtime = timespec_trunc(iattr->ia_mtime,
104 inode->i_sb->s_time_gran); 104 inode->i_sb->s_time_gran);
105 if (ia_valid & ATTR_CTIME) 105 if (ia_valid & ATTR_CTIME)
106 sd_iattr->ia_ctime = timespec_trunc(iattr->ia_ctime, 106 sd_iattr->ia_ctime = timespec_trunc(iattr->ia_ctime,
107 inode->i_sb->s_time_gran); 107 inode->i_sb->s_time_gran);
108 if (ia_valid & ATTR_MODE) { 108 if (ia_valid & ATTR_MODE) {
109 umode_t mode = iattr->ia_mode; 109 umode_t mode = iattr->ia_mode;
110 110
111 if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) 111 if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
112 mode &= ~S_ISGID; 112 mode &= ~S_ISGID;
113 sd_iattr->ia_mode = sd->s_mode = mode; 113 sd_iattr->ia_mode = sd->s_mode = mode;
114 } 114 }
115 115
116 return error; 116 return error;
117 } 117 }
118 118
119 static inline void set_default_inode_attr(struct inode * inode, mode_t mode) 119 static inline void set_default_inode_attr(struct inode * inode, mode_t mode)
120 { 120 {
121 inode->i_mode = mode; 121 inode->i_mode = mode;
122 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 122 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
123 } 123 }
124 124
125 static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) 125 static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
126 { 126 {
127 inode->i_mode = iattr->ia_mode; 127 inode->i_mode = iattr->ia_mode;
128 inode->i_uid = iattr->ia_uid; 128 inode->i_uid = iattr->ia_uid;
129 inode->i_gid = iattr->ia_gid; 129 inode->i_gid = iattr->ia_gid;
130 inode->i_atime = iattr->ia_atime; 130 inode->i_atime = iattr->ia_atime;
131 inode->i_mtime = iattr->ia_mtime; 131 inode->i_mtime = iattr->ia_mtime;
132 inode->i_ctime = iattr->ia_ctime; 132 inode->i_ctime = iattr->ia_ctime;
133 } 133 }
134 134
135 struct inode * configfs_new_inode(mode_t mode, struct configfs_dirent * sd) 135 struct inode * configfs_new_inode(mode_t mode, struct configfs_dirent * sd)
136 { 136 {
137 struct inode * inode = new_inode(configfs_sb); 137 struct inode * inode = new_inode(configfs_sb);
138 if (inode) { 138 if (inode) {
139 inode->i_ino = get_next_ino(); 139 inode->i_ino = get_next_ino();
140 inode->i_mapping->a_ops = &configfs_aops; 140 inode->i_mapping->a_ops = &configfs_aops;
141 inode->i_mapping->backing_dev_info = &configfs_backing_dev_info; 141 inode->i_mapping->backing_dev_info = &configfs_backing_dev_info;
142 inode->i_op = &configfs_inode_operations; 142 inode->i_op = &configfs_inode_operations;
143 143
144 if (sd->s_iattr) { 144 if (sd->s_iattr) {
145 /* sysfs_dirent has non-default attributes 145 /* sysfs_dirent has non-default attributes
146 * get them for the new inode from persistent copy 146 * get them for the new inode from persistent copy
147 * in sysfs_dirent 147 * in sysfs_dirent
148 */ 148 */
149 set_inode_attr(inode, sd->s_iattr); 149 set_inode_attr(inode, sd->s_iattr);
150 } else 150 } else
151 set_default_inode_attr(inode, mode); 151 set_default_inode_attr(inode, mode);
152 } 152 }
153 return inode; 153 return inode;
154 } 154 }
155 155
156 #ifdef CONFIG_LOCKDEP 156 #ifdef CONFIG_LOCKDEP
157 157
158 static void configfs_set_inode_lock_class(struct configfs_dirent *sd, 158 static void configfs_set_inode_lock_class(struct configfs_dirent *sd,
159 struct inode *inode) 159 struct inode *inode)
160 { 160 {
161 int depth = sd->s_depth; 161 int depth = sd->s_depth;
162 162
163 if (depth > 0) { 163 if (depth > 0) {
164 if (depth <= ARRAY_SIZE(default_group_class)) { 164 if (depth <= ARRAY_SIZE(default_group_class)) {
165 lockdep_set_class(&inode->i_mutex, 165 lockdep_set_class(&inode->i_mutex,
166 &default_group_class[depth - 1]); 166 &default_group_class[depth - 1]);
167 } else { 167 } else {
168 /* 168 /*
169 * In practice the maximum level of locking depth is 169 * In practice the maximum level of locking depth is
170 * already reached. Just inform about possible reasons. 170 * already reached. Just inform about possible reasons.
171 */ 171 */
172 printk(KERN_INFO "configfs: Too many levels of inodes" 172 printk(KERN_INFO "configfs: Too many levels of inodes"
173 " for the locking correctness validator.\n"); 173 " for the locking correctness validator.\n");
174 printk(KERN_INFO "Spurious warnings may appear.\n"); 174 printk(KERN_INFO "Spurious warnings may appear.\n");
175 } 175 }
176 } 176 }
177 } 177 }
178 178
179 #else /* CONFIG_LOCKDEP */ 179 #else /* CONFIG_LOCKDEP */
180 180
181 static void configfs_set_inode_lock_class(struct configfs_dirent *sd, 181 static void configfs_set_inode_lock_class(struct configfs_dirent *sd,
182 struct inode *inode) 182 struct inode *inode)
183 { 183 {
184 } 184 }
185 185
186 #endif /* CONFIG_LOCKDEP */ 186 #endif /* CONFIG_LOCKDEP */
187 187
188 int configfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *)) 188 int configfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
189 { 189 {
190 int error = 0; 190 int error = 0;
191 struct inode * inode = NULL; 191 struct inode * inode = NULL;
192 if (dentry) { 192 if (dentry) {
193 if (!dentry->d_inode) { 193 if (!dentry->d_inode) {
194 struct configfs_dirent *sd = dentry->d_fsdata; 194 struct configfs_dirent *sd = dentry->d_fsdata;
195 if ((inode = configfs_new_inode(mode, sd))) { 195 if ((inode = configfs_new_inode(mode, sd))) {
196 if (dentry->d_parent && dentry->d_parent->d_inode) { 196 if (dentry->d_parent && dentry->d_parent->d_inode) {
197 struct inode *p_inode = dentry->d_parent->d_inode; 197 struct inode *p_inode = dentry->d_parent->d_inode;
198 p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME; 198 p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
199 } 199 }
200 configfs_set_inode_lock_class(sd, inode); 200 configfs_set_inode_lock_class(sd, inode);
201 goto Proceed; 201 goto Proceed;
202 } 202 }
203 else 203 else
204 error = -ENOMEM; 204 error = -ENOMEM;
205 } else 205 } else
206 error = -EEXIST; 206 error = -EEXIST;
207 } else 207 } else
208 error = -ENOENT; 208 error = -ENOENT;
209 goto Done; 209 goto Done;
210 210
211 Proceed: 211 Proceed:
212 if (init) 212 if (init)
213 error = init(inode); 213 error = init(inode);
214 if (!error) { 214 if (!error) {
215 d_instantiate(dentry, inode); 215 d_instantiate(dentry, inode);
216 if (S_ISDIR(mode) || S_ISLNK(mode)) 216 if (S_ISDIR(mode) || S_ISLNK(mode))
217 dget(dentry); /* pin link and directory dentries in core */ 217 dget(dentry); /* pin link and directory dentries in core */
218 } else 218 } else
219 iput(inode); 219 iput(inode);
220 Done: 220 Done:
221 return error; 221 return error;
222 } 222 }
223 223
224 /* 224 /*
225 * Get the name for corresponding element represented by the given configfs_dirent 225 * Get the name for corresponding element represented by the given configfs_dirent
226 */ 226 */
227 const unsigned char * configfs_get_name(struct configfs_dirent *sd) 227 const unsigned char * configfs_get_name(struct configfs_dirent *sd)
228 { 228 {
229 struct configfs_attribute *attr; 229 struct configfs_attribute *attr;
230 230
231 BUG_ON(!sd || !sd->s_element); 231 BUG_ON(!sd || !sd->s_element);
232 232
233 /* These always have a dentry, so use that */ 233 /* These always have a dentry, so use that */
234 if (sd->s_type & (CONFIGFS_DIR | CONFIGFS_ITEM_LINK)) 234 if (sd->s_type & (CONFIGFS_DIR | CONFIGFS_ITEM_LINK))
235 return sd->s_dentry->d_name.name; 235 return sd->s_dentry->d_name.name;
236 236
237 if (sd->s_type & CONFIGFS_ITEM_ATTR) { 237 if (sd->s_type & CONFIGFS_ITEM_ATTR) {
238 attr = sd->s_element; 238 attr = sd->s_element;
239 return attr->ca_name; 239 return attr->ca_name;
240 } 240 }
241 return NULL; 241 return NULL;
242 } 242 }
243 243
244 244
245 /* 245 /*
246 * Unhashes the dentry corresponding to given configfs_dirent 246 * Unhashes the dentry corresponding to given configfs_dirent
247 * Called with parent inode's i_mutex held. 247 * Called with parent inode's i_mutex held.
248 */ 248 */
249 void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent) 249 void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent)
250 { 250 {
251 struct dentry * dentry = sd->s_dentry; 251 struct dentry * dentry = sd->s_dentry;
252 252
253 if (dentry) { 253 if (dentry) {
254 spin_lock(&dentry->d_lock); 254 spin_lock(&dentry->d_lock);
255 if (!(d_unhashed(dentry) && dentry->d_inode)) { 255 if (!(d_unhashed(dentry) && dentry->d_inode)) {
256 dget_dlock(dentry); 256 dget_dlock(dentry);
257 __d_drop(dentry); 257 __d_drop(dentry);
258 spin_unlock(&dentry->d_lock); 258 spin_unlock(&dentry->d_lock);
259 simple_unlink(parent->d_inode, dentry); 259 simple_unlink(parent->d_inode, dentry);
260 } else 260 } else
261 spin_unlock(&dentry->d_lock); 261 spin_unlock(&dentry->d_lock);
262 } 262 }
263 } 263 }
264 264
265 void configfs_hash_and_remove(struct dentry * dir, const char * name) 265 void configfs_hash_and_remove(struct dentry * dir, const char * name)
266 { 266 {
267 struct configfs_dirent * sd; 267 struct configfs_dirent * sd;
268 struct configfs_dirent * parent_sd = dir->d_fsdata; 268 struct configfs_dirent * parent_sd = dir->d_fsdata;
269 269
270 if (dir->d_inode == NULL) 270 if (dir->d_inode == NULL)
271 /* no inode means this hasn't been made visible yet */ 271 /* no inode means this hasn't been made visible yet */
272 return; 272 return;
273 273
274 mutex_lock(&dir->d_inode->i_mutex); 274 mutex_lock(&dir->d_inode->i_mutex);
275 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { 275 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
276 if (!sd->s_element) 276 if (!sd->s_element)
277 continue; 277 continue;
278 if (!strcmp(configfs_get_name(sd), name)) { 278 if (!strcmp(configfs_get_name(sd), name)) {
279 spin_lock(&configfs_dirent_lock); 279 spin_lock(&configfs_dirent_lock);
280 list_del_init(&sd->s_sibling); 280 list_del_init(&sd->s_sibling);
281 spin_unlock(&configfs_dirent_lock); 281 spin_unlock(&configfs_dirent_lock);
282 configfs_drop_dentry(sd, dir); 282 configfs_drop_dentry(sd, dir);
283 configfs_put(sd); 283 configfs_put(sd);
284 break; 284 break;
285 } 285 }
286 } 286 }
287 mutex_unlock(&dir->d_inode->i_mutex); 287 mutex_unlock(&dir->d_inode->i_mutex);
288 } 288 }
289 289
290 int __init configfs_inode_init(void) 290 int __init configfs_inode_init(void)
291 { 291 {
292 return bdi_init(&configfs_backing_dev_info); 292 return bdi_init(&configfs_backing_dev_info);
293 } 293 }
294 294
295 void __exit configfs_inode_exit(void) 295 void configfs_inode_exit(void)
296 { 296 {
297 bdi_destroy(&configfs_backing_dev_info); 297 bdi_destroy(&configfs_backing_dev_info);
298 } 298 }
299 299
1 /* -*- mode: c; c-basic-offset: 8; -*- 1 /* -*- mode: c; c-basic-offset: 8; -*-
2 * vim: noexpandtab sw=8 ts=8 sts=0: 2 * vim: noexpandtab sw=8 ts=8 sts=0:
3 * 3 *
4 * mount.c - operations for initializing and mounting configfs. 4 * mount.c - operations for initializing and mounting configfs.
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public 7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 9 * version 2 of the License, or (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details. 14 * General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public 16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the 17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 021110-1307, USA. 19 * Boston, MA 021110-1307, USA.
20 * 20 *
21 * Based on sysfs: 21 * Based on sysfs:
22 * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel 22 * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
23 * 23 *
24 * configfs Copyright (C) 2005 Oracle. All rights reserved. 24 * configfs Copyright (C) 2005 Oracle. All rights reserved.
25 */ 25 */
26 26
27 #include <linux/fs.h> 27 #include <linux/fs.h>
28 #include <linux/module.h> 28 #include <linux/module.h>
29 #include <linux/mount.h> 29 #include <linux/mount.h>
30 #include <linux/pagemap.h> 30 #include <linux/pagemap.h>
31 #include <linux/init.h> 31 #include <linux/init.h>
32 #include <linux/slab.h> 32 #include <linux/slab.h>
33 33
34 #include <linux/configfs.h> 34 #include <linux/configfs.h>
35 #include "configfs_internal.h" 35 #include "configfs_internal.h"
36 36
37 /* Random magic number */ 37 /* Random magic number */
38 #define CONFIGFS_MAGIC 0x62656570 38 #define CONFIGFS_MAGIC 0x62656570
39 39
40 struct vfsmount * configfs_mount = NULL; 40 struct vfsmount * configfs_mount = NULL;
41 struct super_block * configfs_sb = NULL; 41 struct super_block * configfs_sb = NULL;
42 struct kmem_cache *configfs_dir_cachep; 42 struct kmem_cache *configfs_dir_cachep;
43 static int configfs_mnt_count = 0; 43 static int configfs_mnt_count = 0;
44 44
45 static const struct super_operations configfs_ops = { 45 static const struct super_operations configfs_ops = {
46 .statfs = simple_statfs, 46 .statfs = simple_statfs,
47 .drop_inode = generic_delete_inode, 47 .drop_inode = generic_delete_inode,
48 }; 48 };
49 49
50 static struct config_group configfs_root_group = { 50 static struct config_group configfs_root_group = {
51 .cg_item = { 51 .cg_item = {
52 .ci_namebuf = "root", 52 .ci_namebuf = "root",
53 .ci_name = configfs_root_group.cg_item.ci_namebuf, 53 .ci_name = configfs_root_group.cg_item.ci_namebuf,
54 }, 54 },
55 }; 55 };
56 56
57 int configfs_is_root(struct config_item *item) 57 int configfs_is_root(struct config_item *item)
58 { 58 {
59 return item == &configfs_root_group.cg_item; 59 return item == &configfs_root_group.cg_item;
60 } 60 }
61 61
62 static struct configfs_dirent configfs_root = { 62 static struct configfs_dirent configfs_root = {
63 .s_sibling = LIST_HEAD_INIT(configfs_root.s_sibling), 63 .s_sibling = LIST_HEAD_INIT(configfs_root.s_sibling),
64 .s_children = LIST_HEAD_INIT(configfs_root.s_children), 64 .s_children = LIST_HEAD_INIT(configfs_root.s_children),
65 .s_element = &configfs_root_group.cg_item, 65 .s_element = &configfs_root_group.cg_item,
66 .s_type = CONFIGFS_ROOT, 66 .s_type = CONFIGFS_ROOT,
67 .s_iattr = NULL, 67 .s_iattr = NULL,
68 }; 68 };
69 69
70 static int configfs_fill_super(struct super_block *sb, void *data, int silent) 70 static int configfs_fill_super(struct super_block *sb, void *data, int silent)
71 { 71 {
72 struct inode *inode; 72 struct inode *inode;
73 struct dentry *root; 73 struct dentry *root;
74 74
75 sb->s_blocksize = PAGE_CACHE_SIZE; 75 sb->s_blocksize = PAGE_CACHE_SIZE;
76 sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 76 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
77 sb->s_magic = CONFIGFS_MAGIC; 77 sb->s_magic = CONFIGFS_MAGIC;
78 sb->s_op = &configfs_ops; 78 sb->s_op = &configfs_ops;
79 sb->s_time_gran = 1; 79 sb->s_time_gran = 1;
80 configfs_sb = sb; 80 configfs_sb = sb;
81 81
82 inode = configfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, 82 inode = configfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
83 &configfs_root); 83 &configfs_root);
84 if (inode) { 84 if (inode) {
85 inode->i_op = &configfs_dir_inode_operations; 85 inode->i_op = &configfs_dir_inode_operations;
86 inode->i_fop = &configfs_dir_operations; 86 inode->i_fop = &configfs_dir_operations;
87 /* directory inodes start off with i_nlink == 2 (for "." entry) */ 87 /* directory inodes start off with i_nlink == 2 (for "." entry) */
88 inc_nlink(inode); 88 inc_nlink(inode);
89 } else { 89 } else {
90 pr_debug("configfs: could not get root inode\n"); 90 pr_debug("configfs: could not get root inode\n");
91 return -ENOMEM; 91 return -ENOMEM;
92 } 92 }
93 93
94 root = d_alloc_root(inode); 94 root = d_alloc_root(inode);
95 if (!root) { 95 if (!root) {
96 pr_debug("%s: could not get root dentry!\n",__func__); 96 pr_debug("%s: could not get root dentry!\n",__func__);
97 iput(inode); 97 iput(inode);
98 return -ENOMEM; 98 return -ENOMEM;
99 } 99 }
100 config_group_init(&configfs_root_group); 100 config_group_init(&configfs_root_group);
101 configfs_root_group.cg_item.ci_dentry = root; 101 configfs_root_group.cg_item.ci_dentry = root;
102 root->d_fsdata = &configfs_root; 102 root->d_fsdata = &configfs_root;
103 sb->s_root = root; 103 sb->s_root = root;
104 sb->s_d_op = &configfs_dentry_ops; /* the rest get that */ 104 sb->s_d_op = &configfs_dentry_ops; /* the rest get that */
105 return 0; 105 return 0;
106 } 106 }
107 107
108 static struct dentry *configfs_do_mount(struct file_system_type *fs_type, 108 static struct dentry *configfs_do_mount(struct file_system_type *fs_type,
109 int flags, const char *dev_name, void *data) 109 int flags, const char *dev_name, void *data)
110 { 110 {
111 return mount_single(fs_type, flags, data, configfs_fill_super); 111 return mount_single(fs_type, flags, data, configfs_fill_super);
112 } 112 }
113 113
114 static struct file_system_type configfs_fs_type = { 114 static struct file_system_type configfs_fs_type = {
115 .owner = THIS_MODULE, 115 .owner = THIS_MODULE,
116 .name = "configfs", 116 .name = "configfs",
117 .mount = configfs_do_mount, 117 .mount = configfs_do_mount,
118 .kill_sb = kill_litter_super, 118 .kill_sb = kill_litter_super,
119 }; 119 };
120 120
121 int configfs_pin_fs(void) 121 int configfs_pin_fs(void)
122 { 122 {
123 return simple_pin_fs(&configfs_fs_type, &configfs_mount, 123 return simple_pin_fs(&configfs_fs_type, &configfs_mount,
124 &configfs_mnt_count); 124 &configfs_mnt_count);
125 } 125 }
126 126
127 void configfs_release_fs(void) 127 void configfs_release_fs(void)
128 { 128 {
129 simple_release_fs(&configfs_mount, &configfs_mnt_count); 129 simple_release_fs(&configfs_mount, &configfs_mnt_count);
130 } 130 }
131 131
132 132
133 static struct kobject *config_kobj; 133 static struct kobject *config_kobj;
134 134
135 static int __init configfs_init(void) 135 static int __init configfs_init(void)
136 { 136 {
137 int err = -ENOMEM; 137 int err = -ENOMEM;
138 138
139 configfs_dir_cachep = kmem_cache_create("configfs_dir_cache", 139 configfs_dir_cachep = kmem_cache_create("configfs_dir_cache",
140 sizeof(struct configfs_dirent), 140 sizeof(struct configfs_dirent),
141 0, 0, NULL); 141 0, 0, NULL);
142 if (!configfs_dir_cachep) 142 if (!configfs_dir_cachep)
143 goto out; 143 goto out;
144 144
145 config_kobj = kobject_create_and_add("config", kernel_kobj); 145 config_kobj = kobject_create_and_add("config", kernel_kobj);
146 if (!config_kobj) { 146 if (!config_kobj)
147 kmem_cache_destroy(configfs_dir_cachep); 147 goto out2;
148 configfs_dir_cachep = NULL;
149 goto out;
150 }
151 148
149 err = configfs_inode_init();
150 if (err)
151 goto out3;
152
152 err = register_filesystem(&configfs_fs_type); 153 err = register_filesystem(&configfs_fs_type);
153 if (err) { 154 if (err)
154 printk(KERN_ERR "configfs: Unable to register filesystem!\n"); 155 goto out4;
155 kobject_put(config_kobj);
156 kmem_cache_destroy(configfs_dir_cachep);
157 configfs_dir_cachep = NULL;
158 goto out;
159 }
160 156
161 err = configfs_inode_init(); 157 return 0;
162 if (err) { 158 out4:
163 unregister_filesystem(&configfs_fs_type); 159 printk(KERN_ERR "configfs: Unable to register filesystem!\n");
164 kobject_put(config_kobj); 160 configfs_inode_exit();
165 kmem_cache_destroy(configfs_dir_cachep); 161 out3:
166 configfs_dir_cachep = NULL; 162 kobject_put(config_kobj);
167 } 163 out2:
164 kmem_cache_destroy(configfs_dir_cachep);
165 configfs_dir_cachep = NULL;
168 out: 166 out:
169 return err; 167 return err;
170 } 168 }
171 169
172 static void __exit configfs_exit(void) 170 static void __exit configfs_exit(void)
173 { 171 {
174 unregister_filesystem(&configfs_fs_type); 172 unregister_filesystem(&configfs_fs_type);
175 kobject_put(config_kobj); 173 kobject_put(config_kobj);
176 kmem_cache_destroy(configfs_dir_cachep); 174 kmem_cache_destroy(configfs_dir_cachep);
177 configfs_dir_cachep = NULL; 175 configfs_dir_cachep = NULL;
178 configfs_inode_exit(); 176 configfs_inode_exit();
179 } 177 }
180 178
181 MODULE_AUTHOR("Oracle"); 179 MODULE_AUTHOR("Oracle");
182 MODULE_LICENSE("GPL"); 180 MODULE_LICENSE("GPL");