- /* Start at exact size bucket, and search up... */
- for (b = find_free_head(tdb, start_b);
- b < TDB_FREE_BUCKETS;
- b = find_free_head(tdb, b + 1)) {
- /* Try getting one from list. */
- off = lock_and_alloc(tdb, tdb->flist_off,
- b, keylen, datalen, want_extra,
- hashlow);
- if (off == TDB_OFF_ERR)
- return TDB_OFF_ERR;
- if (off != 0)
- return off;
- /* Didn't work. Try next bucket. */
+ flist = tdb->flist_off;
+ while (!wrapped || flist != tdb->flist_off) {
+ /* Start at exact size bucket, and search up... */
+ for (b = find_free_head(tdb, flist, start_b);
+ b < TDB_FREE_BUCKETS;
+ b = find_free_head(tdb, flist, b + 1)) {
+ /* Try getting one from list. */
+ off = lock_and_alloc(tdb, flist,
+ b, keylen, datalen, want_extra,
+ hashlow);
+ if (off == TDB_OFF_ERR)
+ return TDB_OFF_ERR;
+ if (off != 0) {
+ /* Worked? Stay using this list. */
+ tdb->flist_off = flist;
+ return off;
+ }
+ /* Didn't work. Try next bucket. */
+ }
+
+ /* Hmm, try next list. */
+ flist = next_flist(tdb, flist);
+ if (flist == 0) {
+ wrapped = true;
+ flist = first_flist(tdb);
+ }