diff options
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r-- | fs/sysfs/dir.c | 73 |
1 files changed, 43 insertions, 30 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index f09626cc568a..b4c482461403 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -207,40 +207,53 @@ static int init_symlink(struct inode * inode) | |||
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | static int create_dir(struct kobject * k, struct dentry * p, | 210 | static int create_dir(struct kobject *kobj, struct dentry *parent, |
211 | const char * n, struct dentry ** d) | 211 | const char *name, struct dentry **p_dentry) |
212 | { | 212 | { |
213 | int error; | 213 | int error; |
214 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; | 214 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; |
215 | struct dentry *dentry; | ||
216 | struct sysfs_dirent *sd; | ||
215 | 217 | ||
216 | mutex_lock(&p->d_inode->i_mutex); | 218 | mutex_lock(&parent->d_inode->i_mutex); |
217 | *d = lookup_one_len(n, p, strlen(n)); | 219 | |
218 | if (!IS_ERR(*d)) { | 220 | dentry = lookup_one_len(name, parent, strlen(name)); |
219 | if (sysfs_dirent_exist(p->d_fsdata, n)) | 221 | if (IS_ERR(dentry)) { |
220 | error = -EEXIST; | 222 | error = PTR_ERR(dentry); |
221 | else | 223 | goto out_unlock; |
222 | error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, | 224 | } |
223 | SYSFS_DIR); | 225 | |
224 | if (!error) { | 226 | error = -EEXIST; |
225 | error = sysfs_create(*d, mode, init_dir); | 227 | if (sysfs_dirent_exist(parent->d_fsdata, name)) |
226 | if (!error) { | 228 | goto out_dput; |
227 | inc_nlink(p->d_inode); | 229 | |
228 | (*d)->d_op = &sysfs_dentry_ops; | 230 | error = sysfs_make_dirent(parent->d_fsdata, dentry, kobj, mode, |
229 | d_rehash(*d); | 231 | SYSFS_DIR); |
230 | } | 232 | if (error) |
231 | } | 233 | goto out_drop; |
232 | if (error && (error != -EEXIST)) { | 234 | |
233 | struct sysfs_dirent *sd = (*d)->d_fsdata; | 235 | error = sysfs_create(dentry, mode, init_dir); |
234 | if (sd) { | 236 | if (error) |
235 | list_del_init(&sd->s_sibling); | 237 | goto out_sput; |
236 | sysfs_put(sd); | 238 | |
237 | } | 239 | inc_nlink(parent->d_inode); |
238 | d_drop(*d); | 240 | dentry->d_op = &sysfs_dentry_ops; |
239 | } | 241 | d_rehash(dentry); |
240 | dput(*d); | 242 | |
241 | } else | 243 | *p_dentry = dentry; |
242 | error = PTR_ERR(*d); | 244 | error = 0; |
243 | mutex_unlock(&p->d_inode->i_mutex); | 245 | goto out_dput; |
246 | |||
247 | out_sput: | ||
248 | sd = dentry->d_fsdata; | ||
249 | list_del_init(&sd->s_sibling); | ||
250 | sysfs_put(sd); | ||
251 | out_drop: | ||
252 | d_drop(dentry); | ||
253 | out_dput: | ||
254 | dput(dentry); | ||
255 | out_unlock: | ||
256 | mutex_unlock(&parent->d_inode->i_mutex); | ||
244 | return error; | 257 | return error; |
245 | } | 258 | } |
246 | 259 | ||