aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/devtmpfs.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2010-01-04 19:17:33 -0500
committerTejun Heo <tj@kernel.org>2010-01-04 19:17:33 -0500
commit32032df6c2f6c9c6b2ada2ce42322231824f70c2 (patch)
treeb1ce838a37044bb38dfc128e2116ca35630e629a /drivers/base/devtmpfs.c
parent22b737f4c75197372d64afc6ed1bccd58c00e549 (diff)
parentc5974b835a909ff15c3b7e6cf6789b5eb919f419 (diff)
Merge branch 'master' into percpu
Conflicts: arch/powerpc/platforms/pseries/hvCall.S include/linux/percpu.h
Diffstat (limited to 'drivers/base/devtmpfs.c')
-rw-r--r--drivers/base/devtmpfs.c101
1 files changed, 51 insertions, 50 deletions
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index a1cb5afe6801..090dd4851301 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -32,6 +32,8 @@ static int dev_mount = 1;
32static int dev_mount; 32static int dev_mount;
33#endif 33#endif
34 34
35static DEFINE_MUTEX(dirlock);
36
35static int __init mount_param(char *str) 37static int __init mount_param(char *str)
36{ 38{
37 dev_mount = simple_strtoul(str, NULL, 0); 39 dev_mount = simple_strtoul(str, NULL, 0);
@@ -74,47 +76,37 @@ static int dev_mkdir(const char *name, mode_t mode)
74 dentry = lookup_create(&nd, 1); 76 dentry = lookup_create(&nd, 1);
75 if (!IS_ERR(dentry)) { 77 if (!IS_ERR(dentry)) {
76 err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); 78 err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
79 if (!err)
80 /* mark as kernel-created inode */
81 dentry->d_inode->i_private = &dev_mnt;
77 dput(dentry); 82 dput(dentry);
78 } else { 83 } else {
79 err = PTR_ERR(dentry); 84 err = PTR_ERR(dentry);
80 } 85 }
81 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
82 86
87 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
83 path_put(&nd.path); 88 path_put(&nd.path);
84 return err; 89 return err;
85} 90}
86 91
87static int create_path(const char *nodepath) 92static int create_path(const char *nodepath)
88{ 93{
89 char *path; 94 int err;
90 struct nameidata nd;
91 int err = 0;
92
93 path = kstrdup(nodepath, GFP_KERNEL);
94 if (!path)
95 return -ENOMEM;
96
97 err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
98 path, LOOKUP_PARENT, &nd);
99 if (err == 0) {
100 struct dentry *dentry;
101
102 /* create directory right away */
103 dentry = lookup_create(&nd, 1);
104 if (!IS_ERR(dentry)) {
105 err = vfs_mkdir(nd.path.dentry->d_inode,
106 dentry, 0755);
107 dput(dentry);
108 }
109 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
110 95
111 path_put(&nd.path); 96 mutex_lock(&dirlock);
112 } else if (err == -ENOENT) { 97 err = dev_mkdir(nodepath, 0755);
98 if (err == -ENOENT) {
99 char *path;
113 char *s; 100 char *s;
114 101
115 /* parent directories do not exist, create them */ 102 /* parent directories do not exist, create them */
103 path = kstrdup(nodepath, GFP_KERNEL);
104 if (!path) {
105 err = -ENOMEM;
106 goto out;
107 }
116 s = path; 108 s = path;
117 while (1) { 109 for (;;) {
118 s = strchr(s, '/'); 110 s = strchr(s, '/');
119 if (!s) 111 if (!s)
120 break; 112 break;
@@ -125,9 +117,10 @@ static int create_path(const char *nodepath)
125 s[0] = '/'; 117 s[0] = '/';
126 s++; 118 s++;
127 } 119 }
120 kfree(path);
128 } 121 }
129 122out:
130 kfree(path); 123 mutex_unlock(&dirlock);
131 return err; 124 return err;
132} 125}
133 126
@@ -156,34 +149,40 @@ int devtmpfs_create_node(struct device *dev)
156 mode |= S_IFCHR; 149 mode |= S_IFCHR;
157 150
158 curr_cred = override_creds(&init_cred); 151 curr_cred = override_creds(&init_cred);
152
159 err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, 153 err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
160 nodename, LOOKUP_PARENT, &nd); 154 nodename, LOOKUP_PARENT, &nd);
161 if (err == -ENOENT) { 155 if (err == -ENOENT) {
162 /* create missing parent directories */
163 create_path(nodename); 156 create_path(nodename);
164 err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt, 157 err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
165 nodename, LOOKUP_PARENT, &nd); 158 nodename, LOOKUP_PARENT, &nd);
166 if (err)
167 goto out;
168 } 159 }
160 if (err)
161 goto out;
169 162
170 dentry = lookup_create(&nd, 0); 163 dentry = lookup_create(&nd, 0);
171 if (!IS_ERR(dentry)) { 164 if (!IS_ERR(dentry)) {
172 int umask;
173
174 umask = sys_umask(0000);
175 err = vfs_mknod(nd.path.dentry->d_inode, 165 err = vfs_mknod(nd.path.dentry->d_inode,
176 dentry, mode, dev->devt); 166 dentry, mode, dev->devt);
177 sys_umask(umask); 167 if (!err) {
178 /* mark as kernel created inode */ 168 struct iattr newattrs;
179 if (!err) 169
170 /* fixup possibly umasked mode */
171 newattrs.ia_mode = mode;
172 newattrs.ia_valid = ATTR_MODE;
173 mutex_lock(&dentry->d_inode->i_mutex);
174 notify_change(dentry, &newattrs);
175 mutex_unlock(&dentry->d_inode->i_mutex);
176
177 /* mark as kernel-created inode */
180 dentry->d_inode->i_private = &dev_mnt; 178 dentry->d_inode->i_private = &dev_mnt;
179 }
181 dput(dentry); 180 dput(dentry);
182 } else { 181 } else {
183 err = PTR_ERR(dentry); 182 err = PTR_ERR(dentry);
184 } 183 }
185 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
186 184
185 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
187 path_put(&nd.path); 186 path_put(&nd.path);
188out: 187out:
189 kfree(tmp); 188 kfree(tmp);
@@ -205,16 +204,21 @@ static int dev_rmdir(const char *name)
205 mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); 204 mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
206 dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len); 205 dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len);
207 if (!IS_ERR(dentry)) { 206 if (!IS_ERR(dentry)) {
208 if (dentry->d_inode) 207 if (dentry->d_inode) {
209 err = vfs_rmdir(nd.path.dentry->d_inode, dentry); 208 if (dentry->d_inode->i_private == &dev_mnt)
210 else 209 err = vfs_rmdir(nd.path.dentry->d_inode,
210 dentry);
211 else
212 err = -EPERM;
213 } else {
211 err = -ENOENT; 214 err = -ENOENT;
215 }
212 dput(dentry); 216 dput(dentry);
213 } else { 217 } else {
214 err = PTR_ERR(dentry); 218 err = PTR_ERR(dentry);
215 } 219 }
216 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
217 220
221 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
218 path_put(&nd.path); 222 path_put(&nd.path);
219 return err; 223 return err;
220} 224}
@@ -228,7 +232,8 @@ static int delete_path(const char *nodepath)
228 if (!path) 232 if (!path)
229 return -ENOMEM; 233 return -ENOMEM;
230 234
231 while (1) { 235 mutex_lock(&dirlock);
236 for (;;) {
232 char *base; 237 char *base;
233 238
234 base = strrchr(path, '/'); 239 base = strrchr(path, '/');
@@ -239,6 +244,7 @@ static int delete_path(const char *nodepath)
239 if (err) 244 if (err)
240 break; 245 break;
241 } 246 }
247 mutex_unlock(&dirlock);
242 248
243 kfree(path); 249 kfree(path);
244 return err; 250 return err;
@@ -322,9 +328,8 @@ out:
322 * If configured, or requested by the commandline, devtmpfs will be 328 * If configured, or requested by the commandline, devtmpfs will be
323 * auto-mounted after the kernel mounted the root filesystem. 329 * auto-mounted after the kernel mounted the root filesystem.
324 */ 330 */
325int devtmpfs_mount(const char *mountpoint) 331int devtmpfs_mount(const char *mntdir)
326{ 332{
327 struct path path;
328 int err; 333 int err;
329 334
330 if (!dev_mount) 335 if (!dev_mount)
@@ -333,15 +338,11 @@ int devtmpfs_mount(const char *mountpoint)
333 if (!dev_mnt) 338 if (!dev_mnt)
334 return 0; 339 return 0;
335 340
336 err = kern_path(mountpoint, LOOKUP_FOLLOW, &path); 341 err = sys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, NULL);
337 if (err)
338 return err;
339 err = do_add_mount(dev_mnt, &path, 0, NULL);
340 if (err) 342 if (err)
341 printk(KERN_INFO "devtmpfs: error mounting %i\n", err); 343 printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
342 else 344 else
343 printk(KERN_INFO "devtmpfs: mounted\n"); 345 printk(KERN_INFO "devtmpfs: mounted\n");
344 path_put(&path);
345 return err; 346 return err;
346} 347}
347 348
@@ -361,7 +362,7 @@ int __init devtmpfs_init(void)
361 return err; 362 return err;
362 } 363 }
363 364
364 mnt = kern_mount(&dev_fs_type); 365 mnt = kern_mount_data(&dev_fs_type, "mode=0755");
365 if (IS_ERR(mnt)) { 366 if (IS_ERR(mnt)) {
366 err = PTR_ERR(mnt); 367 err = PTR_ERR(mnt);
367 printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err); 368 printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err);