Acked-by: Joel Becker <jlbec@xxxxxxxxxxxx> On Wed, Aug 25, 2021 at 08:49:05AM +0200, Christoph Hellwig wrote: > This makes it more clear what gets added to the dcache and prepares > for an additional locking fix. > > Signed-off-by: Christoph Hellwig <hch@xxxxxx> > --- > fs/configfs/dir.c | 73 ++++++++++++++++------------------------------- > 1 file changed, 24 insertions(+), 49 deletions(-) > > diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c > index 5d58569f0eea..fc20bd8a6337 100644 > --- a/fs/configfs/dir.c > +++ b/fs/configfs/dir.c > @@ -45,7 +45,7 @@ static void configfs_d_iput(struct dentry * dentry, > /* > * Set sd->s_dentry to null only when this dentry is the one > * that is going to be killed. Otherwise configfs_d_iput may > - * run just after configfs_attach_attr and set sd->s_dentry to > + * run just after configfs_lookup and set sd->s_dentry to > * NULL even it's still in use. > */ > if (sd->s_dentry == dentry) > @@ -417,44 +417,13 @@ static void configfs_remove_dir(struct config_item * item) > dput(dentry); > } > > - > -/* attaches attribute's configfs_dirent to the dentry corresponding to the > - * attribute file > - */ > -static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * dentry) > -{ > - struct configfs_attribute * attr = sd->s_element; > - struct inode *inode; > - > - spin_lock(&configfs_dirent_lock); > - dentry->d_fsdata = configfs_get(sd); > - sd->s_dentry = dentry; > - spin_unlock(&configfs_dirent_lock); > - > - inode = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG); > - if (IS_ERR(inode)) { > - configfs_put(sd); > - return PTR_ERR(inode); > - } > - if (sd->s_type & CONFIGFS_ITEM_BIN_ATTR) { > - inode->i_size = 0; > - inode->i_fop = &configfs_bin_file_operations; > - } else { > - inode->i_size = PAGE_SIZE; > - inode->i_fop = &configfs_file_operations; > - } > - d_add(dentry, inode); > - return 0; > -} > - > static struct dentry * configfs_lookup(struct inode *dir, > struct dentry *dentry, > unsigned int flags) > { > struct configfs_dirent * parent_sd = dentry->d_parent->d_fsdata; > struct configfs_dirent * sd; > - int found = 0; > - int err; > + struct inode *inode = NULL; > > if (dentry->d_name.len > NAME_MAX) > return ERR_PTR(-ENAMETOOLONG); > @@ -471,28 +440,34 @@ static struct dentry * configfs_lookup(struct inode *dir, > return ERR_PTR(-ENOENT); > > list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { > - if (sd->s_type & CONFIGFS_NOT_PINNED) { > - const unsigned char * name = configfs_get_name(sd); > + if ((sd->s_type & CONFIGFS_NOT_PINNED) && > + !strcmp(configfs_get_name(sd), dentry->d_name.name)) { > + struct configfs_attribute *attr = sd->s_element; > + umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG; > > - if (strcmp(name, dentry->d_name.name)) > - continue; > + spin_lock(&configfs_dirent_lock); > + dentry->d_fsdata = configfs_get(sd); > + sd->s_dentry = dentry; > + spin_unlock(&configfs_dirent_lock); > > - found = 1; > - err = configfs_attach_attr(sd, dentry); > + inode = configfs_create(dentry, mode); > + if (IS_ERR(inode)) { > + configfs_put(sd); > + return ERR_CAST(inode); > + } > + if (sd->s_type & CONFIGFS_ITEM_BIN_ATTR) { > + inode->i_size = 0; > + inode->i_fop = &configfs_bin_file_operations; > + } else { > + inode->i_size = PAGE_SIZE; > + inode->i_fop = &configfs_file_operations; > + } > break; > } > } > > - if (!found) { > - /* > - * If it doesn't exist and it isn't a NOT_PINNED item, > - * it must be negative. > - */ > - d_add(dentry, NULL); > - return NULL; > - } > - > - return ERR_PTR(err); > + d_add(dentry, inode); > + return NULL; > } > > /* > -- > 2.30.2 > --