5252static struct dentry * eventfs_root_lookup (struct inode * dir ,
5353 struct dentry * dentry ,
5454 unsigned int flags );
55- static int dcache_dir_open_wrapper (struct inode * inode , struct file * file );
56- static int dcache_readdir_wrapper (struct file * file , struct dir_context * ctx );
57- static int eventfs_release (struct inode * inode , struct file * file );
55+ static int eventfs_iterate (struct file * file , struct dir_context * ctx );
5856
5957static void update_attr (struct eventfs_attr * attr , struct iattr * iattr )
6058{
@@ -148,11 +146,9 @@ static const struct inode_operations eventfs_file_inode_operations = {
148146};
149147
150148static const struct file_operations eventfs_file_operations = {
151- .open = dcache_dir_open_wrapper ,
152149 .read = generic_read_dir ,
153- .iterate_shared = dcache_readdir_wrapper ,
150+ .iterate_shared = eventfs_iterate ,
154151 .llseek = generic_file_llseek ,
155- .release = eventfs_release ,
156152};
157153
158154/* Return the evenfs_inode of the "events" directory */
@@ -643,128 +639,87 @@ static struct dentry *eventfs_root_lookup(struct inode *dir,
643639 return ret ;
644640}
645641
646- struct dentry_list {
647- void * cursor ;
648- struct dentry * * dentries ;
649- };
650-
651- /**
652- * eventfs_release - called to release eventfs file/dir
653- * @inode: inode to be released
654- * @file: file to be released (not used)
655- */
656- static int eventfs_release (struct inode * inode , struct file * file )
657- {
658- struct tracefs_inode * ti ;
659- struct dentry_list * dlist = file -> private_data ;
660- void * cursor ;
661- int i ;
662-
663- ti = get_tracefs (inode );
664- if (!(ti -> flags & TRACEFS_EVENT_INODE ))
665- return - EINVAL ;
666-
667- if (WARN_ON_ONCE (!dlist ))
668- return - EINVAL ;
669-
670- for (i = 0 ; dlist -> dentries && dlist -> dentries [i ]; i ++ ) {
671- dput (dlist -> dentries [i ]);
672- }
673-
674- cursor = dlist -> cursor ;
675- kfree (dlist -> dentries );
676- kfree (dlist );
677- file -> private_data = cursor ;
678- return dcache_dir_close (inode , file );
679- }
680-
681- static int add_dentries (struct dentry * * * dentries , struct dentry * d , int cnt )
682- {
683- struct dentry * * tmp ;
684-
685- tmp = krealloc (* dentries , sizeof (d ) * (cnt + 2 ), GFP_NOFS );
686- if (!tmp )
687- return -1 ;
688- tmp [cnt ] = d ;
689- tmp [cnt + 1 ] = NULL ;
690- * dentries = tmp ;
691- return 0 ;
692- }
693-
694- /**
695- * dcache_dir_open_wrapper - eventfs open wrapper
696- * @inode: not used
697- * @file: dir to be opened (to create it's children)
698- *
699- * Used to dynamic create file/dir with-in @file, all the
700- * file/dir will be created. If already created then references
701- * will be increased
642+ /*
643+ * Walk the children of a eventfs_inode to fill in getdents().
702644 */
703- static int dcache_dir_open_wrapper (struct inode * inode , struct file * file )
645+ static int eventfs_iterate (struct file * file , struct dir_context * ctx )
704646{
705647 const struct file_operations * fops ;
648+ struct inode * f_inode = file_inode (file );
706649 const struct eventfs_entry * entry ;
707650 struct eventfs_inode * ei_child ;
708651 struct tracefs_inode * ti ;
709652 struct eventfs_inode * ei ;
710- struct dentry_list * dlist ;
711- struct dentry * * dentries = NULL ;
712- struct dentry * parent = file_dentry (file );
713- struct dentry * d ;
714- struct inode * f_inode = file_inode (file );
715- const char * name = parent -> d_name .name ;
653+ struct dentry * ei_dentry = NULL ;
654+ struct dentry * dentry ;
655+ const char * name ;
716656 umode_t mode ;
717- void * data ;
718- int cnt = 0 ;
719657 int idx ;
720- int ret ;
721- int i ;
722- int r ;
658+ int ret = - EINVAL ;
659+ int ino ;
660+ int i , r , c ;
661+
662+ if (!dir_emit_dots (file , ctx ))
663+ return 0 ;
723664
724665 ti = get_tracefs (f_inode );
725666 if (!(ti -> flags & TRACEFS_EVENT_INODE ))
726667 return - EINVAL ;
727668
728- if (WARN_ON_ONCE (file -> private_data ))
729- return - EINVAL ;
669+ c = ctx -> pos - 2 ;
730670
731671 idx = srcu_read_lock (& eventfs_srcu );
732672
733673 mutex_lock (& eventfs_mutex );
734674 ei = READ_ONCE (ti -> private );
675+ if (ei && !ei -> is_freed )
676+ ei_dentry = READ_ONCE (ei -> dentry );
735677 mutex_unlock (& eventfs_mutex );
736678
737- if (!ei ) {
738- srcu_read_unlock (& eventfs_srcu , idx );
739- return - EINVAL ;
740- }
741-
742-
743- data = ei -> data ;
679+ if (!ei || !ei_dentry )
680+ goto out ;
744681
745- dlist = kmalloc (sizeof (* dlist ), GFP_KERNEL );
746- if (!dlist ) {
747- srcu_read_unlock (& eventfs_srcu , idx );
748- return - ENOMEM ;
749- }
682+ ret = 0 ;
750683
751- inode_lock (parent -> d_inode );
684+ /*
685+ * Need to create the dentries and inodes to have a consistent
686+ * inode number.
687+ */
752688 list_for_each_entry_srcu (ei_child , & ei -> children , list ,
753689 srcu_read_lock_held (& eventfs_srcu )) {
754- d = create_dir_dentry (ei , ei_child , parent );
755- if (d ) {
756- ret = add_dentries (& dentries , d , cnt );
757- dput (d );
758- if (ret < 0 )
759- break ;
760- cnt ++ ;
690+
691+ if (c > 0 ) {
692+ c -- ;
693+ continue ;
761694 }
695+
696+ if (ei_child -> is_freed )
697+ continue ;
698+
699+ name = ei_child -> name ;
700+
701+ dentry = create_dir_dentry (ei , ei_child , ei_dentry );
702+ if (!dentry )
703+ goto out ;
704+ ino = dentry -> d_inode -> i_ino ;
705+ dput (dentry );
706+
707+ if (!dir_emit (ctx , name , strlen (name ), ino , DT_DIR ))
708+ goto out ;
709+ ctx -> pos ++ ;
762710 }
763711
764712 for (i = 0 ; i < ei -> nr_entries ; i ++ ) {
765- void * cdata = data ;
713+ void * cdata = ei -> data ;
714+
715+ if (c > 0 ) {
716+ c -- ;
717+ continue ;
718+ }
719+
766720 entry = & ei -> entries [i ];
767721 name = entry -> name ;
722+
768723 mutex_lock (& eventfs_mutex );
769724 /* If ei->is_freed, then the event itself may be too */
770725 if (!ei -> is_freed )
@@ -774,42 +729,21 @@ static int dcache_dir_open_wrapper(struct inode *inode, struct file *file)
774729 mutex_unlock (& eventfs_mutex );
775730 if (r <= 0 )
776731 continue ;
777- d = create_file_dentry (ei , i , parent , name , mode , cdata , fops );
778- if (d ) {
779- ret = add_dentries (& dentries , d , cnt );
780- dput (d );
781- if (ret < 0 )
782- break ;
783- cnt ++ ;
784- }
785- }
786- inode_unlock (parent -> d_inode );
787- srcu_read_unlock (& eventfs_srcu , idx );
788- ret = dcache_dir_open (inode , file );
789732
790- /*
791- * dcache_dir_open() sets file->private_data to a dentry cursor.
792- * Need to save that but also save all the dentries that were
793- * opened by this function.
794- */
795- dlist -> cursor = file -> private_data ;
796- dlist -> dentries = dentries ;
797- file -> private_data = dlist ;
798- return ret ;
799- }
733+ dentry = create_file_dentry (ei , i , ei_dentry , name , mode , cdata , fops );
734+ if (!dentry )
735+ goto out ;
736+ ino = dentry -> d_inode -> i_ino ;
737+ dput (dentry );
800738
801- /*
802- * This just sets the file->private_data back to the cursor and back.
803- */
804- static int dcache_readdir_wrapper ( struct file * file , struct dir_context * ctx )
805- {
806- struct dentry_list * dlist = file -> private_data ;
807- int ret ;
739+ if (! dir_emit ( ctx , name , strlen ( name ), ino , DT_REG ))
740+ goto out ;
741+ ctx -> pos ++ ;
742+ }
743+ ret = 1 ;
744+ out :
745+ srcu_read_unlock ( & eventfs_srcu , idx ) ;
808746
809- file -> private_data = dlist -> cursor ;
810- ret = dcache_readdir (file , ctx );
811- dlist -> cursor = file -> private_data ;
812- file -> private_data = dlist ;
813747 return ret ;
814748}
815749
0 commit comments