aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/dir.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-06-13 14:45:16 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-07-11 19:09:06 -0400
commitdbde0fcf9f8f6d477af3c32d9979e789ee680cde (patch)
tree12a1240213d59c061fec60325c7d5ebb1edebcd7 /fs/sysfs/dir.c
parent198a2a847015805c6f57d8cc732bdaaccb494007 (diff)
sysfs: reimplement sysfs_drop_dentry()
This patch reimplements sysfs_drop_dentry() such that remove_dir() can use it to drop dentry instead of using a separate mechanism. With this change, making directories reclaimable is much easier. This patch used to contain fixes for two race conditions around sd->s_dentry but that part has been separated out and included into mainline early as commit 6aa054aadfea613a437ad0b15d38eca2b963fc0a and dd14cbc994709a1c5a64ed3621f583c49a27e521. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/sysfs/dir.c')
-rw-r--r--fs/sysfs/dir.c18
1 files changed, 5 insertions, 13 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 01eeb4b954b1..bc11a263aa53 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -372,22 +372,19 @@ const struct inode_operations sysfs_dir_inode_operations = {
372 372
373static void remove_dir(struct dentry * d) 373static void remove_dir(struct dentry * d)
374{ 374{
375 struct dentry * parent = dget(d->d_parent); 375 struct dentry *parent = d->d_parent;
376 struct sysfs_dirent * sd; 376 struct sysfs_dirent *sd = d->d_fsdata;
377 377
378 mutex_lock(&parent->d_inode->i_mutex); 378 mutex_lock(&parent->d_inode->i_mutex);
379 d_delete(d); 379
380 sd = d->d_fsdata;
381 list_del_init(&sd->s_sibling); 380 list_del_init(&sd->s_sibling);
382 if (d->d_inode)
383 simple_rmdir(parent->d_inode,d);
384 381
385 pr_debug(" o %s removing done (%d)\n",d->d_name.name, 382 pr_debug(" o %s removing done (%d)\n",d->d_name.name,
386 atomic_read(&d->d_count)); 383 atomic_read(&d->d_count));
387 384
388 mutex_unlock(&parent->d_inode->i_mutex); 385 mutex_unlock(&parent->d_inode->i_mutex);
389 dput(parent);
390 386
387 sysfs_drop_dentry(sd);
391 sysfs_deactivate(sd); 388 sysfs_deactivate(sd);
392 sysfs_put(sd); 389 sysfs_put(sd);
393} 390}
@@ -404,7 +401,6 @@ static void __sysfs_remove_dir(struct dentry *dentry)
404 struct sysfs_dirent * parent_sd; 401 struct sysfs_dirent * parent_sd;
405 struct sysfs_dirent * sd, * tmp; 402 struct sysfs_dirent * sd, * tmp;
406 403
407 dget(dentry);
408 if (!dentry) 404 if (!dentry)
409 return; 405 return;
410 406
@@ -415,21 +411,17 @@ static void __sysfs_remove_dir(struct dentry *dentry)
415 if (!sd->s_type || !(sd->s_type & SYSFS_NOT_PINNED)) 411 if (!sd->s_type || !(sd->s_type & SYSFS_NOT_PINNED))
416 continue; 412 continue;
417 list_move(&sd->s_sibling, &removed); 413 list_move(&sd->s_sibling, &removed);
418 sysfs_drop_dentry(sd, dentry);
419 } 414 }
420 mutex_unlock(&dentry->d_inode->i_mutex); 415 mutex_unlock(&dentry->d_inode->i_mutex);
421 416
422 list_for_each_entry_safe(sd, tmp, &removed, s_sibling) { 417 list_for_each_entry_safe(sd, tmp, &removed, s_sibling) {
423 list_del_init(&sd->s_sibling); 418 list_del_init(&sd->s_sibling);
419 sysfs_drop_dentry(sd);
424 sysfs_deactivate(sd); 420 sysfs_deactivate(sd);
425 sysfs_put(sd); 421 sysfs_put(sd);
426 } 422 }
427 423
428 remove_dir(dentry); 424 remove_dir(dentry);
429 /**
430 * Drop reference from dget() on entrance.
431 */
432 dput(dentry);
433} 425}
434 426
435/** 427/**