Skip to content

Commit

Permalink
sysfs: simply sysfs_get_dentry
Browse files Browse the repository at this point in the history
Now that we know the sysfs tree structure cannot change under us and
sysfs shadow support is dropped, sysfs_get_dentry() can be simplified
greatly.  It can just look up from the root and there's no need to
retry on failure.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Tejun Heo authored and Greg Kroah-Hartman committed Oct 12, 2007
1 parent 932ea2e commit e0712bb
Showing 1 changed file with 16 additions and 75 deletions.
91 changes: 16 additions & 75 deletions fs/sysfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,8 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
* @sd: sysfs_dirent of interest
*
* Get dentry for @sd. Dentry is looked up if currently not
* present. This function climbs sysfs_dirent tree till it
* reaches a sysfs_dirent with valid dentry attached and descends
* down from there looking up dentry for each step.
* present. This function descends from the root looking up
* dentry for each step.
*
* LOCKING:
* mutex_lock(sysfs_rename_mutex)
Expand All @@ -90,86 +89,28 @@ static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
*/
struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd)
{
struct sysfs_dirent *cur;
struct dentry *parent_dentry, *dentry;
int i, depth;
struct dentry *dentry = dget(sysfs_sb->s_root);

/* Find the first parent which has valid s_dentry and get the
* dentry.
*/
mutex_lock(&sysfs_mutex);
restart0:
spin_lock(&sysfs_assoc_lock);
restart1:
spin_lock(&dcache_lock);

dentry = NULL;
depth = 0;
cur = sd;
while (!cur->s_dentry || !cur->s_dentry->d_inode) {
if (cur->s_flags & SYSFS_FLAG_REMOVED) {
dentry = ERR_PTR(-ENOENT);
depth = 0;
break;
}
cur = cur->s_parent;
depth++;
}
if (!IS_ERR(dentry))
dentry = dget_locked(cur->s_dentry);
while (dentry->d_fsdata != sd) {
struct sysfs_dirent *cur;
struct dentry *parent;

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

/* from the found dentry, look up depth times */
while (depth--) {
/* find and get depth'th ancestor */
for (cur = sd, i = 0; cur && i < depth; i++)
/* find the first ancestor which hasn't been looked up */
cur = sd;
while (cur->s_parent != dentry->d_fsdata)
cur = cur->s_parent;

/* This can happen if tree structure was modified due
* to move/rename. Restart.
*/
if (i != depth) {
dput(dentry);
goto restart0;
}

sysfs_get(cur);

mutex_unlock(&sysfs_mutex);

/* look it up */
parent_dentry = dentry;
mutex_lock(&parent_dentry->d_inode->i_mutex);
dentry = lookup_one_len_kern(cur->s_name, parent_dentry,
parent = dentry;
mutex_lock(&parent->d_inode->i_mutex);
dentry = lookup_one_len_kern(cur->s_name, parent,
strlen(cur->s_name));
mutex_unlock(&parent_dentry->d_inode->i_mutex);
dput(parent_dentry);

if (IS_ERR(dentry)) {
sysfs_put(cur);
return dentry;
}
mutex_unlock(&parent->d_inode->i_mutex);
dput(parent);

mutex_lock(&sysfs_mutex);
spin_lock(&sysfs_assoc_lock);

/* This, again, can happen if tree structure has
* changed and we looked up the wrong thing. Restart.
*/
if (cur->s_dentry != dentry) {
dput(dentry);
sysfs_put(cur);
goto restart1;
}

spin_unlock(&sysfs_assoc_lock);

sysfs_put(cur);
if (IS_ERR(dentry))
break;
}

mutex_unlock(&sysfs_mutex);
return dentry;
}

Expand Down

0 comments on commit e0712bb

Please sign in to comment.