Skip to content

Commit

Permalink
configfs: fold configfs_attach_attr into configfs_lookup
Browse files Browse the repository at this point in the history
This makes it more clear what gets added to the dcache and prepares
for an additional locking fix.

Signed-off-by: Christoph Hellwig <[email protected]>
  • Loading branch information
Christoph Hellwig committed Aug 25, 2021
1 parent 899587c commit d07f132
Showing 1 changed file with 24 additions and 49 deletions.
73 changes: 24 additions & 49 deletions fs/configfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}

/*
Expand Down

0 comments on commit d07f132

Please sign in to comment.