diff options
author | Tejun Heo <htejun@gmail.com> | 2007-06-13 21:27:24 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-12 01:09:09 +0200 |
commit | a0edd7c848945a75e2f41673f43bc37d0a5fed15 (patch) | |
tree | c74ea7d7dbc814faef126f97601a16c7118b3099 /fs/sysfs/dir.c | |
parent | sysfs: restructure add/remove paths and fix inode update (diff) | |
download | linux-a0edd7c848945a75e2f41673f43bc37d0a5fed15.tar.xz linux-a0edd7c848945a75e2f41673f43bc37d0a5fed15.zip |
sysfs: move sysfs_drop_dentry() to dir.c and make it static
After add/remove path restructuring, the only user of
sysfs_drop_dentry() is sysfs_addrm_finish(). Move sysfs_drop_dentry()
to dir.c and make it static.
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.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index edb30621b82f..c6f3b697064c 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -435,6 +435,62 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) } /** + * sysfs_drop_dentry - drop dentry for the specified sysfs_dirent + * @sd: target sysfs_dirent + * + * 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; + + /* We're not holding a reference to ->s_dentry dentry but the + * field will stay valid as long as sysfs_assoc_lock is held. + */ + spin_lock(&sysfs_assoc_lock); + 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); + spin_lock(&dentry->d_lock); + __d_drop(dentry); + spin_unlock(&dentry->d_lock); + } + + spin_unlock(&dcache_lock); + spin_unlock(&sysfs_assoc_lock); + + dput(dentry); + /* XXX: unpin if directory, this will go away soon */ + if (sysfs_type(sd) == SYSFS_DIR) + dput(dentry); + + /* adjust nlink and update timestamp */ + inode = ilookup(sysfs_sb, sd->s_ino); + if (inode) { + mutex_lock(&inode->i_mutex); + + inode->i_ctime = CURRENT_TIME; + drop_nlink(inode); + if (sysfs_type(sd) == SYSFS_DIR) + drop_nlink(inode); + + mutex_unlock(&inode->i_mutex); + iput(inode); + } +} + +/** * sysfs_addrm_finish - finish up sysfs_dirent add/remove * @acxt: addrm context to finish up * |