configfs: fold configfs_attach_attr into configfs_lookup
authorChristoph Hellwig <hch@lst.de>
Wed, 25 Aug 2021 05:50:32 +0000 (07:50 +0200)
committerChristoph Hellwig <hch@lst.de>
Wed, 25 Aug 2021 05:58:46 +0000 (07:58 +0200)
This makes it more clear what gets added to the dcache and prepares
for an additional locking fix.

Signed-off-by: Christoph Hellwig <hch@lst.de>
fs/configfs/dir.c

index 5d58569..fc20bd8 100644 (file)
@@ -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;
 }
 
 /*