Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 67978
b: refs/heads/master
c: 89bec09
h: refs/heads/master
v: v3
  • Loading branch information
Eric W. Biederman authored and Greg Kroah-Hartman committed Oct 12, 2007
1 parent fc7d610 commit 53e1fb5
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3efa65b92d832873ece62b42a4268c2515943977
refs/heads/master: 89bec09705d2033b8b765f3c3ac5093f80bd5bc4
53 changes: 26 additions & 27 deletions trunk/fs/sysfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,50 +565,49 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
* Drop dentry for @sd. @sd must have been unlinked from its
* parent on entry to this function such that it can't be looked
* up anymore.
*
* @sd->s_dentry which is protected with sysfs_assoc_lock points
* to the currently associated dentry but we're not holding a
* reference to it and racing with dput(). Grab dcache_lock and
* verify dentry before dropping it. If @sd->s_dentry is NULL or
* dput() beats us, no need to bother.
*/
static void sysfs_drop_dentry(struct sysfs_dirent *sd)
{
struct dentry *dentry = NULL;
struct inode *inode;
struct dentry *dentry;

inode = ilookup(sysfs_sb, sd->s_ino);
if (!inode)
return;

/* We're not holding a reference to ->s_dentry dentry but the
* field will stay valid as long as sysfs_assoc_lock is held.
/* Drop any existing dentries associated with sd.
*
* For the dentry to be properly freed we need to grab a
* reference to the dentry under the dcache lock, unhash it,
* and then put it. The playing with the dentry count allows
* dput to immediately free the dentry if it is not in use.
*/
spin_lock(&sysfs_assoc_lock);
repeat:
spin_lock(&dcache_lock);

/* drop dentry if it's there and dput() didn't kill it yet */
if (sd->s_dentry && sd->s_dentry->d_inode) {
dentry = dget_locked(sd->s_dentry);
list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
if (d_unhashed(dentry))
continue;
dget_locked(dentry);
spin_lock(&dentry->d_lock);
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
spin_unlock(&dcache_lock);
dput(dentry);
goto repeat;
}

spin_unlock(&dcache_lock);
spin_unlock(&sysfs_assoc_lock);

dput(dentry);

/* adjust nlink and update timestamp */
inode = ilookup(sysfs_sb, sd->s_ino);
if (inode) {
mutex_lock(&inode->i_mutex);
mutex_lock(&inode->i_mutex);

inode->i_ctime = CURRENT_TIME;
inode->i_ctime = CURRENT_TIME;
drop_nlink(inode);
if (sysfs_type(sd) == SYSFS_DIR)
drop_nlink(inode);
if (sysfs_type(sd) == SYSFS_DIR)
drop_nlink(inode);

mutex_unlock(&inode->i_mutex);
iput(inode);
}
mutex_unlock(&inode->i_mutex);

iput(inode);
}

/**
Expand Down

0 comments on commit 53e1fb5

Please sign in to comment.