diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 2fbdff6..8f68ecc 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c @@ -1008,17 +1008,22 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) { struct dentry *dentry = filp->f_path.dentry; struct sysfs_dirent * parent_sd = dentry->d_fsdata; - struct sysfs_dirent *pos = filp->private_data; + struct sysfs_dirent *pos; enum kobj_ns_type type; const void *ns; ino_t ino; + int ret; type = sysfs_ns_type(parent_sd); ns = sysfs_info(dentry->d_sb)->ns[type]; + mutex_lock(&sysfs_mutex); if (filp->f_pos == 0) { ino = parent_sd->s_ino; - if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0) + mutex_unlock(&sysfs_mutex); + ret = filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR); + mutex_lock(&sysfs_mutex); + if (!ret) filp->f_pos++; } if (filp->f_pos == 1) { @@ -1026,16 +1031,19 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) ino = parent_sd->s_parent->s_ino; else ino = parent_sd->s_ino; - if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0) + mutex_unlock(&sysfs_mutex); + ret = filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR); + mutex_lock(&sysfs_mutex); + if (!ret) filp->f_pos++; } - mutex_lock(&sysfs_mutex); + pos = filp->private_data; for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos); pos; pos = sysfs_dir_next_pos(ns, parent_sd, filp->f_pos, pos)) { const char * name; unsigned int type; - int len, ret; + int len; name = pos->s_name; len = strlen(name);