@@ -931,3 +931,90 @@ tdb_htrie_exit(TdbHdr *dbh)
931931{
932932 free_percpu (dbh -> pcpu );
933933}
934+
935+ static int
936+ tdb_bucket_walk (TdbHdr * dbh , TdbBucket * b , int (* fn )(void * ))
937+ {
938+ TdbBucket * b_tmp ;
939+
940+ read_lock_bh (& b -> lock );
941+
942+ do {
943+ TdbRec * r = TDB_HTRIE_BCKT_1ST_REC (b );
944+ do {
945+ size_t rlen = sizeof (* r ) + TDB_HTRIE_RBODYLEN (dbh , r );
946+ rlen = TDB_HTRIE_RALIGN (rlen );
947+ if ((char * )r + rlen - (char * )b > TDB_HTRIE_MINDREC
948+ && r != TDB_HTRIE_BCKT_1ST_REC (b ))
949+ break ;
950+ if (tdb_live_rec (dbh , r )) {
951+ int res = fn (r -> data );
952+ if (unlikely (res )) {
953+ read_unlock_bh (& b -> lock );
954+ return res ;
955+ }
956+ }
957+ r = (TdbRec * )((char * )r + rlen );
958+ } while ((char * )r + sizeof (* r ) - (char * )b
959+ <= TDB_HTRIE_MINDREC );
960+
961+ b_tmp = TDB_HTRIE_BUCKET_NEXT (dbh , b );
962+ if (b_tmp )
963+ read_lock_bh (& b_tmp -> lock );
964+ read_unlock_bh (& b -> lock );
965+ b = b_tmp ;
966+ } while (b );
967+
968+ return 0 ;
969+ }
970+
971+ static int
972+ tdb_node_visit (TdbHdr * dbh , TdbHtrieNode * node , int (* fn )(void * ))
973+ {
974+ int bits ;
975+
976+ for (bits = 0 ; bits < TDB_HTRIE_FANOUT ; ++ bits ) {
977+ unsigned long o ;
978+
979+ BUG_ON (TDB_HTRIE_RESOLVED (bits ));
980+
981+ o = node -> shifts [bits ];
982+
983+ BUG_ON (o
984+ && (TDB_DI2O (o & ~TDB_HTRIE_DBIT )
985+ < TDB_HDR_SZ (dbh ) + sizeof (TdbExt )
986+ || TDB_DI2O (o & ~TDB_HTRIE_DBIT )
987+ > dbh -> dbsz ));
988+
989+ if (o & TDB_HTRIE_DBIT ) {
990+ TdbBucket * b ;
991+ int res ;
992+
993+ /* We're at a data pointer - resolve it. */
994+ o ^= TDB_HTRIE_DBIT ;
995+ BUG_ON (!o );
996+
997+ b = (TdbBucket * )TDB_PTR (dbh , TDB_DI2O (o ));
998+
999+ res = tdb_bucket_walk (dbh , b , fn );
1000+ if (unlikely (res )) {
1001+ read_unlock_bh (& b -> lock );
1002+ return res ;
1003+ }
1004+ } else {
1005+ if (o )
1006+ tdb_node_visit (dbh , TDB_PTR (dbh , TDB_II2O (o )),
1007+ fn );
1008+ }
1009+ }
1010+
1011+ return 0 ;
1012+ }
1013+
1014+ int
1015+ tdb_walk (TdbHdr * dbh , int (* fn )(void * ))
1016+ {
1017+ TdbHtrieNode * node = TDB_HTRIE_ROOT (dbh );
1018+
1019+ return tdb_node_visit (dbh , node , fn );
1020+ }
0 commit comments