aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r--fs/sysfs/dir.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 59734ba1ee60..49bd219275db 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -99,7 +99,7 @@ static int create_dir(struct kobject * k, struct dentry * p,
99 int error; 99 int error;
100 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; 100 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
101 101
102 down(&p->d_inode->i_sem); 102 mutex_lock(&p->d_inode->i_mutex);
103 *d = lookup_one_len(n, p, strlen(n)); 103 *d = lookup_one_len(n, p, strlen(n));
104 if (!IS_ERR(*d)) { 104 if (!IS_ERR(*d)) {
105 error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR); 105 error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR);
@@ -112,13 +112,17 @@ static int create_dir(struct kobject * k, struct dentry * p,
112 } 112 }
113 } 113 }
114 if (error && (error != -EEXIST)) { 114 if (error && (error != -EEXIST)) {
115 sysfs_put((*d)->d_fsdata); 115 struct sysfs_dirent *sd = (*d)->d_fsdata;
116 if (sd) {
117 list_del_init(&sd->s_sibling);
118 sysfs_put(sd);
119 }
116 d_drop(*d); 120 d_drop(*d);
117 } 121 }
118 dput(*d); 122 dput(*d);
119 } else 123 } else
120 error = PTR_ERR(*d); 124 error = PTR_ERR(*d);
121 up(&p->d_inode->i_sem); 125 mutex_unlock(&p->d_inode->i_mutex);
122 return error; 126 return error;
123} 127}
124 128
@@ -242,7 +246,7 @@ static void remove_dir(struct dentry * d)
242 struct dentry * parent = dget(d->d_parent); 246 struct dentry * parent = dget(d->d_parent);
243 struct sysfs_dirent * sd; 247 struct sysfs_dirent * sd;
244 248
245 down(&parent->d_inode->i_sem); 249 mutex_lock(&parent->d_inode->i_mutex);
246 d_delete(d); 250 d_delete(d);
247 sd = d->d_fsdata; 251 sd = d->d_fsdata;
248 list_del_init(&sd->s_sibling); 252 list_del_init(&sd->s_sibling);
@@ -253,7 +257,7 @@ static void remove_dir(struct dentry * d)
253 pr_debug(" o %s removing done (%d)\n",d->d_name.name, 257 pr_debug(" o %s removing done (%d)\n",d->d_name.name,
254 atomic_read(&d->d_count)); 258 atomic_read(&d->d_count));
255 259
256 up(&parent->d_inode->i_sem); 260 mutex_unlock(&parent->d_inode->i_mutex);
257 dput(parent); 261 dput(parent);
258} 262}
259 263
@@ -282,7 +286,7 @@ void sysfs_remove_dir(struct kobject * kobj)
282 return; 286 return;
283 287
284 pr_debug("sysfs %s: removing dir\n",dentry->d_name.name); 288 pr_debug("sysfs %s: removing dir\n",dentry->d_name.name);
285 down(&dentry->d_inode->i_sem); 289 mutex_lock(&dentry->d_inode->i_mutex);
286 parent_sd = dentry->d_fsdata; 290 parent_sd = dentry->d_fsdata;
287 list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) { 291 list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
288 if (!sd->s_element || !(sd->s_type & SYSFS_NOT_PINNED)) 292 if (!sd->s_element || !(sd->s_type & SYSFS_NOT_PINNED))
@@ -291,7 +295,7 @@ void sysfs_remove_dir(struct kobject * kobj)
291 sysfs_drop_dentry(sd, dentry); 295 sysfs_drop_dentry(sd, dentry);
292 sysfs_put(sd); 296 sysfs_put(sd);
293 } 297 }
294 up(&dentry->d_inode->i_sem); 298 mutex_unlock(&dentry->d_inode->i_mutex);
295 299
296 remove_dir(dentry); 300 remove_dir(dentry);
297 /** 301 /**
@@ -314,7 +318,7 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
314 down_write(&sysfs_rename_sem); 318 down_write(&sysfs_rename_sem);
315 parent = kobj->parent->dentry; 319 parent = kobj->parent->dentry;
316 320
317 down(&parent->d_inode->i_sem); 321 mutex_lock(&parent->d_inode->i_mutex);
318 322
319 new_dentry = lookup_one_len(new_name, parent, strlen(new_name)); 323 new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
320 if (!IS_ERR(new_dentry)) { 324 if (!IS_ERR(new_dentry)) {
@@ -330,7 +334,7 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
330 error = -EEXIST; 334 error = -EEXIST;
331 dput(new_dentry); 335 dput(new_dentry);
332 } 336 }
333 up(&parent->d_inode->i_sem); 337 mutex_unlock(&parent->d_inode->i_mutex);
334 up_write(&sysfs_rename_sem); 338 up_write(&sysfs_rename_sem);
335 339
336 return error; 340 return error;
@@ -341,9 +345,9 @@ static int sysfs_dir_open(struct inode *inode, struct file *file)
341 struct dentry * dentry = file->f_dentry; 345 struct dentry * dentry = file->f_dentry;
342 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 346 struct sysfs_dirent * parent_sd = dentry->d_fsdata;
343 347
344 down(&dentry->d_inode->i_sem); 348 mutex_lock(&dentry->d_inode->i_mutex);
345 file->private_data = sysfs_new_dirent(parent_sd, NULL); 349 file->private_data = sysfs_new_dirent(parent_sd, NULL);
346 up(&dentry->d_inode->i_sem); 350 mutex_unlock(&dentry->d_inode->i_mutex);
347 351
348 return file->private_data ? 0 : -ENOMEM; 352 return file->private_data ? 0 : -ENOMEM;
349 353
@@ -354,9 +358,9 @@ static int sysfs_dir_close(struct inode *inode, struct file *file)
354 struct dentry * dentry = file->f_dentry; 358 struct dentry * dentry = file->f_dentry;
355 struct sysfs_dirent * cursor = file->private_data; 359 struct sysfs_dirent * cursor = file->private_data;
356 360
357 down(&dentry->d_inode->i_sem); 361 mutex_lock(&dentry->d_inode->i_mutex);
358 list_del_init(&cursor->s_sibling); 362 list_del_init(&cursor->s_sibling);
359 up(&dentry->d_inode->i_sem); 363 mutex_unlock(&dentry->d_inode->i_mutex);
360 364
361 release_sysfs_dirent(cursor); 365 release_sysfs_dirent(cursor);
362 366
@@ -432,7 +436,7 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
432{ 436{
433 struct dentry * dentry = file->f_dentry; 437 struct dentry * dentry = file->f_dentry;
434 438
435 down(&dentry->d_inode->i_sem); 439 mutex_lock(&dentry->d_inode->i_mutex);
436 switch (origin) { 440 switch (origin) {
437 case 1: 441 case 1:
438 offset += file->f_pos; 442 offset += file->f_pos;
@@ -440,7 +444,7 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
440 if (offset >= 0) 444 if (offset >= 0)
441 break; 445 break;
442 default: 446 default:
443 up(&file->f_dentry->d_inode->i_sem); 447 mutex_unlock(&file->f_dentry->d_inode->i_mutex);
444 return -EINVAL; 448 return -EINVAL;
445 } 449 }
446 if (offset != file->f_pos) { 450 if (offset != file->f_pos) {
@@ -464,7 +468,7 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
464 list_add_tail(&cursor->s_sibling, p); 468 list_add_tail(&cursor->s_sibling, p);
465 } 469 }
466 } 470 }
467 up(&dentry->d_inode->i_sem); 471 mutex_unlock(&dentry->d_inode->i_mutex);
468 return offset; 472 return offset;
469} 473}
470 474
@@ -479,4 +483,3 @@ struct file_operations sysfs_dir_operations = {
479EXPORT_SYMBOL_GPL(sysfs_create_dir); 483EXPORT_SYMBOL_GPL(sysfs_create_dir);
480EXPORT_SYMBOL_GPL(sysfs_remove_dir); 484EXPORT_SYMBOL_GPL(sysfs_remove_dir);
481EXPORT_SYMBOL_GPL(sysfs_rename_dir); 485EXPORT_SYMBOL_GPL(sysfs_rename_dir);
482