@@ -359,18 +359,17 @@ EXPORT_SYMBOL(radix_tree_insert);
359359 * Returns: the slot corresponding to the position @index in the
360360 * radix tree @root. This is useful for update-if-exists operations.
361361 *
362- * This function cannot be called under rcu_read_lock, it must be
363- * excluded from writers, as must the returned slot for subsequent
364- * use by radix_tree_deref_slot() and radix_tree_replace slot.
365- * Caller must hold tree write locked across slot lookup and
366- * replace.
362+ * This function can be called under rcu_read_lock iff the slot is not
363+ * modified by radix_tree_replace_slot, otherwise it must be called
364+ * exclusive from other writers. Any dereference of the slot must be done
365+ * using radix_tree_deref_slot.
367366 */
368367void * * radix_tree_lookup_slot (struct radix_tree_root * root , unsigned long index )
369368{
370369 unsigned int height , shift ;
371370 struct radix_tree_node * node , * * slot ;
372371
373- node = root -> rnode ;
372+ node = rcu_dereference ( root -> rnode ) ;
374373 if (node == NULL )
375374 return NULL ;
376375
@@ -390,7 +389,7 @@ void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
390389 do {
391390 slot = (struct radix_tree_node * * )
392391 (node -> slots + ((index >>shift ) & RADIX_TREE_MAP_MASK ));
393- node = * slot ;
392+ node = rcu_dereference ( * slot ) ;
394393 if (node == NULL )
395394 return NULL ;
396395
@@ -667,7 +666,7 @@ unsigned long radix_tree_next_hole(struct radix_tree_root *root,
667666EXPORT_SYMBOL (radix_tree_next_hole );
668667
669668static unsigned int
670- __lookup (struct radix_tree_node * slot , void * * results , unsigned long index ,
669+ __lookup (struct radix_tree_node * slot , void * * * results , unsigned long index ,
671670 unsigned int max_items , unsigned long * next_index )
672671{
673672 unsigned int nr_found = 0 ;
@@ -701,11 +700,9 @@ __lookup(struct radix_tree_node *slot, void **results, unsigned long index,
701700
702701 /* Bottom level: grab some items */
703702 for (i = index & RADIX_TREE_MAP_MASK ; i < RADIX_TREE_MAP_SIZE ; i ++ ) {
704- struct radix_tree_node * node ;
705703 index ++ ;
706- node = slot -> slots [i ];
707- if (node ) {
708- results [nr_found ++ ] = rcu_dereference (node );
704+ if (slot -> slots [i ]) {
705+ results [nr_found ++ ] = & (slot -> slots [i ]);
709706 if (nr_found == max_items )
710707 goto out ;
711708 }
@@ -759,13 +756,22 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
759756
760757 ret = 0 ;
761758 while (ret < max_items ) {
762- unsigned int nr_found ;
759+ unsigned int nr_found , slots_found , i ;
763760 unsigned long next_index ; /* Index of next search */
764761
765762 if (cur_index > max_index )
766763 break ;
767- nr_found = __lookup (node , results + ret , cur_index ,
764+ slots_found = __lookup (node , ( void * * * ) results + ret , cur_index ,
768765 max_items - ret , & next_index );
766+ nr_found = 0 ;
767+ for (i = 0 ; i < slots_found ; i ++ ) {
768+ struct radix_tree_node * slot ;
769+ slot = * (((void * * * )results )[ret + i ]);
770+ if (!slot )
771+ continue ;
772+ results [ret + nr_found ] = rcu_dereference (slot );
773+ nr_found ++ ;
774+ }
769775 ret += nr_found ;
770776 if (next_index == 0 )
771777 break ;
@@ -776,12 +782,71 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
776782}
777783EXPORT_SYMBOL (radix_tree_gang_lookup );
778784
785+ /**
786+ * radix_tree_gang_lookup_slot - perform multiple slot lookup on radix tree
787+ * @root: radix tree root
788+ * @results: where the results of the lookup are placed
789+ * @first_index: start the lookup from this key
790+ * @max_items: place up to this many items at *results
791+ *
792+ * Performs an index-ascending scan of the tree for present items. Places
793+ * their slots at *@results and returns the number of items which were
794+ * placed at *@results.
795+ *
796+ * The implementation is naive.
797+ *
798+ * Like radix_tree_gang_lookup as far as RCU and locking goes. Slots must
799+ * be dereferenced with radix_tree_deref_slot, and if using only RCU
800+ * protection, radix_tree_deref_slot may fail requiring a retry.
801+ */
802+ unsigned int
803+ radix_tree_gang_lookup_slot (struct radix_tree_root * root , void * * * results ,
804+ unsigned long first_index , unsigned int max_items )
805+ {
806+ unsigned long max_index ;
807+ struct radix_tree_node * node ;
808+ unsigned long cur_index = first_index ;
809+ unsigned int ret ;
810+
811+ node = rcu_dereference (root -> rnode );
812+ if (!node )
813+ return 0 ;
814+
815+ if (!radix_tree_is_indirect_ptr (node )) {
816+ if (first_index > 0 )
817+ return 0 ;
818+ results [0 ] = (void * * )& root -> rnode ;
819+ return 1 ;
820+ }
821+ node = radix_tree_indirect_to_ptr (node );
822+
823+ max_index = radix_tree_maxindex (node -> height );
824+
825+ ret = 0 ;
826+ while (ret < max_items ) {
827+ unsigned int slots_found ;
828+ unsigned long next_index ; /* Index of next search */
829+
830+ if (cur_index > max_index )
831+ break ;
832+ slots_found = __lookup (node , results + ret , cur_index ,
833+ max_items - ret , & next_index );
834+ ret += slots_found ;
835+ if (next_index == 0 )
836+ break ;
837+ cur_index = next_index ;
838+ }
839+
840+ return ret ;
841+ }
842+ EXPORT_SYMBOL (radix_tree_gang_lookup_slot );
843+
779844/*
780845 * FIXME: the two tag_get()s here should use find_next_bit() instead of
781846 * open-coding the search.
782847 */
783848static unsigned int
784- __lookup_tag (struct radix_tree_node * slot , void * * results , unsigned long index ,
849+ __lookup_tag (struct radix_tree_node * slot , void * * * results , unsigned long index ,
785850 unsigned int max_items , unsigned long * next_index , unsigned int tag )
786851{
787852 unsigned int nr_found = 0 ;
@@ -811,11 +876,9 @@ __lookup_tag(struct radix_tree_node *slot, void **results, unsigned long index,
811876 unsigned long j = index & RADIX_TREE_MAP_MASK ;
812877
813878 for ( ; j < RADIX_TREE_MAP_SIZE ; j ++ ) {
814- struct radix_tree_node * node ;
815879 index ++ ;
816880 if (!tag_get (slot , tag , j ))
817881 continue ;
818- node = slot -> slots [j ];
819882 /*
820883 * Even though the tag was found set, we need to
821884 * recheck that we have a non-NULL node, because
@@ -826,9 +889,8 @@ __lookup_tag(struct radix_tree_node *slot, void **results, unsigned long index,
826889 * lookup ->slots[x] without a lock (ie. can't
827890 * rely on its value remaining the same).
828891 */
829- if (node ) {
830- node = rcu_dereference (node );
831- results [nr_found ++ ] = node ;
892+ if (slot -> slots [j ]) {
893+ results [nr_found ++ ] = & (slot -> slots [j ]);
832894 if (nr_found == max_items )
833895 goto out ;
834896 }
@@ -887,13 +949,22 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
887949
888950 ret = 0 ;
889951 while (ret < max_items ) {
890- unsigned int nr_found ;
952+ unsigned int nr_found , slots_found , i ;
891953 unsigned long next_index ; /* Index of next search */
892954
893955 if (cur_index > max_index )
894956 break ;
895- nr_found = __lookup_tag (node , results + ret , cur_index ,
896- max_items - ret , & next_index , tag );
957+ slots_found = __lookup_tag (node , (void * * * )results + ret ,
958+ cur_index , max_items - ret , & next_index , tag );
959+ nr_found = 0 ;
960+ for (i = 0 ; i < slots_found ; i ++ ) {
961+ struct radix_tree_node * slot ;
962+ slot = * (((void * * * )results )[ret + i ]);
963+ if (!slot )
964+ continue ;
965+ results [ret + nr_found ] = rcu_dereference (slot );
966+ nr_found ++ ;
967+ }
897968 ret += nr_found ;
898969 if (next_index == 0 )
899970 break ;
@@ -904,6 +975,67 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
904975}
905976EXPORT_SYMBOL (radix_tree_gang_lookup_tag );
906977
978+ /**
979+ * radix_tree_gang_lookup_tag_slot - perform multiple slot lookup on a
980+ * radix tree based on a tag
981+ * @root: radix tree root
982+ * @results: where the results of the lookup are placed
983+ * @first_index: start the lookup from this key
984+ * @max_items: place up to this many items at *results
985+ * @tag: the tag index (< RADIX_TREE_MAX_TAGS)
986+ *
987+ * Performs an index-ascending scan of the tree for present items which
988+ * have the tag indexed by @tag set. Places the slots at *@results and
989+ * returns the number of slots which were placed at *@results.
990+ */
991+ unsigned int
992+ radix_tree_gang_lookup_tag_slot (struct radix_tree_root * root , void * * * results ,
993+ unsigned long first_index , unsigned int max_items ,
994+ unsigned int tag )
995+ {
996+ struct radix_tree_node * node ;
997+ unsigned long max_index ;
998+ unsigned long cur_index = first_index ;
999+ unsigned int ret ;
1000+
1001+ /* check the root's tag bit */
1002+ if (!root_tag_get (root , tag ))
1003+ return 0 ;
1004+
1005+ node = rcu_dereference (root -> rnode );
1006+ if (!node )
1007+ return 0 ;
1008+
1009+ if (!radix_tree_is_indirect_ptr (node )) {
1010+ if (first_index > 0 )
1011+ return 0 ;
1012+ results [0 ] = (void * * )& root -> rnode ;
1013+ return 1 ;
1014+ }
1015+ node = radix_tree_indirect_to_ptr (node );
1016+
1017+ max_index = radix_tree_maxindex (node -> height );
1018+
1019+ ret = 0 ;
1020+ while (ret < max_items ) {
1021+ unsigned int slots_found ;
1022+ unsigned long next_index ; /* Index of next search */
1023+
1024+ if (cur_index > max_index )
1025+ break ;
1026+ slots_found = __lookup_tag (node , results + ret ,
1027+ cur_index , max_items - ret , & next_index , tag );
1028+ ret += slots_found ;
1029+ if (next_index == 0 )
1030+ break ;
1031+ cur_index = next_index ;
1032+ }
1033+
1034+ return ret ;
1035+ }
1036+ EXPORT_SYMBOL (radix_tree_gang_lookup_tag_slot );
1037+
1038+
9071039/**
9081040 * radix_tree_shrink - shrink height of a radix tree to minimal
9091041 * @root radix tree root
0 commit comments