@@ -207,7 +207,17 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent *paren
207207 return ERR_PTR (- ENOENT );
208208 }
209209 sd -> s_frag = get_fragment (frag );
210- list_add (& sd -> s_sibling , & parent_sd -> s_children );
210+
211+ /*
212+ * configfs_lookup scans only for unpinned items. s_children is
213+ * partitioned so that configfs_lookup can bail out early.
214+ * CONFIGFS_PINNED and CONFIGFS_NOT_PINNED are not symmetrical. readdir
215+ * cursors still need to be inserted at the front of the list.
216+ */
217+ if (sd -> s_type & CONFIGFS_PINNED )
218+ list_add_tail (& sd -> s_sibling , & parent_sd -> s_children );
219+ else
220+ list_add (& sd -> s_sibling , & parent_sd -> s_children );
211221 spin_unlock (& configfs_dirent_lock );
212222
213223 return sd ;
@@ -220,10 +230,11 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent *paren
220230 *
221231 * called with parent inode's i_mutex held
222232 */
223- static int configfs_dirent_exists (struct configfs_dirent * parent_sd ,
224- const unsigned char * new )
233+ static int configfs_dirent_exists (struct dentry * dentry )
225234{
226- struct configfs_dirent * sd ;
235+ struct configfs_dirent * parent_sd = dentry -> d_parent -> d_fsdata ;
236+ const unsigned char * new = dentry -> d_name .name ;
237+ struct configfs_dirent * sd ;
227238
228239 list_for_each_entry (sd , & parent_sd -> s_children , s_sibling ) {
229240 if (sd -> s_element ) {
@@ -289,10 +300,6 @@ static int configfs_create_dir(struct config_item *item, struct dentry *dentry,
289300
290301 BUG_ON (!item );
291302
292- error = configfs_dirent_exists (p -> d_fsdata , dentry -> d_name .name );
293- if (unlikely (error ))
294- return error ;
295-
296303 error = configfs_make_dirent (p -> d_fsdata , dentry , item , mode ,
297304 CONFIGFS_DIR | CONFIGFS_USET_CREATING ,
298305 frag );
@@ -451,6 +458,18 @@ static struct dentry * configfs_lookup(struct inode *dir,
451458
452459 spin_lock (& configfs_dirent_lock );
453460 list_for_each_entry (sd , & parent_sd -> s_children , s_sibling ) {
461+
462+ /*
463+ * s_children is partitioned, see configfs_new_dirent. The first
464+ * pinned item indicates we can stop scanning.
465+ */
466+ if (sd -> s_type & CONFIGFS_PINNED )
467+ break ;
468+
469+ /*
470+ * Note: CONFIGFS_PINNED and CONFIGFS_NOT_PINNED are asymmetric.
471+ * there may be a readdir cursor in this list
472+ */
454473 if ((sd -> s_type & CONFIGFS_NOT_PINNED ) &&
455474 !strcmp (configfs_get_name (sd ), dentry -> d_name .name )) {
456475 struct configfs_attribute * attr = sd -> s_element ;
@@ -1885,8 +1904,11 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
18851904 if (dentry ) {
18861905 d_add (dentry , NULL );
18871906
1888- err = configfs_attach_group (sd -> s_element , & group -> cg_item ,
1889- dentry , frag );
1907+ err = configfs_dirent_exists (dentry );
1908+ if (!err )
1909+ err = configfs_attach_group (sd -> s_element ,
1910+ & group -> cg_item ,
1911+ dentry , frag );
18901912 if (err ) {
18911913 BUG_ON (d_inode (dentry ));
18921914 d_drop (dentry );
0 commit comments