]> git.ozlabs.org Git - ccan/blobdiff - ccan/tdb2/hash.c
tdb2: restore file filling code.
[ccan] / ccan / tdb2 / hash.c
index d242d531780d1d41b7e330b0abfcf894012c82de..a52ae4674f529b17daf9c1cdd36c9fed113dbc15 100644 (file)
@@ -229,6 +229,7 @@ tdb_off_t find_and_lock(struct tdb_context *tdb,
 {
        uint32_t i, group;
        tdb_off_t hashtable;
+       enum TDB_ERROR ecode;
 
        h->h = tdb_hash(tdb, key.dptr, key.dsize);
        h->hash_used = 0;
@@ -236,9 +237,12 @@ tdb_off_t find_and_lock(struct tdb_context *tdb,
        h->home_bucket = use_bits(h, TDB_HASH_GROUP_BITS);
 
        h->hlock_start = hlock_range(group, &h->hlock_range);
-       if (tdb_lock_hashes(tdb, h->hlock_start, h->hlock_range, ltype,
-                           TDB_LOCK_WAIT))
+       ecode = tdb_lock_hashes(tdb, h->hlock_start, h->hlock_range, ltype,
+                               TDB_LOCK_WAIT);
+       if (ecode != TDB_SUCCESS) {
+               tdb->ecode = ecode;
                return TDB_OFF_ERR;
+       }
 
        hashtable = offsetof(struct tdb_header, hashtable);
        if (tinfo) {
@@ -678,20 +682,24 @@ again:
 }
 
 /* Return 1 if we find something, 0 if not, -1 on error. */
-int next_in_hash(struct tdb_context *tdb, int ltype,
+int next_in_hash(struct tdb_context *tdb,
                 struct traverse_info *tinfo,
                 TDB_DATA *kbuf, size_t *dlen)
 {
        const unsigned group_bits = TDB_TOPLEVEL_HASH_BITS-TDB_HASH_GROUP_BITS;
        tdb_off_t hl_start, hl_range, off;
+       enum TDB_ERROR ecode;
 
        while (tinfo->toplevel_group < (1 << group_bits)) {
                hl_start = (tdb_off_t)tinfo->toplevel_group
                        << (64 - group_bits);
                hl_range = 1ULL << group_bits;
-               if (tdb_lock_hashes(tdb, hl_start, hl_range, ltype,
-                                   TDB_LOCK_WAIT) != 0)
+               ecode = tdb_lock_hashes(tdb, hl_start, hl_range, F_RDLCK,
+                                       TDB_LOCK_WAIT);
+               if (ecode != TDB_SUCCESS) {
+                       tdb->ecode = ecode;
                        return -1;
+               }
 
                off = iterate_hash(tdb, tinfo);
                if (off) {
@@ -699,12 +707,12 @@ int next_in_hash(struct tdb_context *tdb, int ltype,
 
                        if (tdb_read_convert(tdb, off, &rec, sizeof(rec))) {
                                tdb_unlock_hashes(tdb,
-                                                 hl_start, hl_range, ltype);
+                                                 hl_start, hl_range, F_RDLCK);
                                return -1;
                        }
                        if (rec_magic(&rec) != TDB_USED_MAGIC) {
                                tdb_logerr(tdb, TDB_ERR_CORRUPT,
-                                          TDB_DEBUG_FATAL,
+                                          TDB_LOG_ERROR,
                                           "next_in_hash:"
                                           " corrupt record at %llu",
                                           (long long)off);
@@ -725,11 +733,11 @@ int next_in_hash(struct tdb_context *tdb, int ltype,
                                                            off + sizeof(rec),
                                                            kbuf->dsize);
                        }
-                       tdb_unlock_hashes(tdb, hl_start, hl_range, ltype);
+                       tdb_unlock_hashes(tdb, hl_start, hl_range, F_RDLCK);
                        return kbuf->dptr ? 1 : -1;
                }
 
-               tdb_unlock_hashes(tdb, hl_start, hl_range, ltype);
+               tdb_unlock_hashes(tdb, hl_start, hl_range, F_RDLCK);
 
                tinfo->toplevel_group++;
                tinfo->levels[0].hashtable
@@ -740,7 +748,7 @@ int next_in_hash(struct tdb_context *tdb, int ltype,
 }
 
 /* Return 1 if we find something, 0 if not, -1 on error. */
-int first_in_hash(struct tdb_context *tdb, int ltype,
+int first_in_hash(struct tdb_context *tdb,
                  struct traverse_info *tinfo,
                  TDB_DATA *kbuf, size_t *dlen)
 {
@@ -751,7 +759,7 @@ int first_in_hash(struct tdb_context *tdb, int ltype,
        tinfo->levels[0].entry = 0;
        tinfo->levels[0].total_buckets = (1 << TDB_HASH_GROUP_BITS);
 
-       return next_in_hash(tdb, ltype, tinfo, kbuf, dlen);
+       return next_in_hash(tdb, tinfo, kbuf, dlen);
 }
 
 /* Even if the entry isn't in this hash bucket, you'd have to lock this
@@ -760,7 +768,7 @@ static int chainlock(struct tdb_context *tdb, const TDB_DATA *key,
                     int ltype, enum tdb_lock_flags waitflag,
                     const char *func)
 {
-       int ret;
+       enum TDB_ERROR ecode;
        uint64_t h = tdb_hash(tdb, key->dptr, key->dsize);
        tdb_off_t lockstart, locksize;
        unsigned int group, gbits;
@@ -770,9 +778,13 @@ static int chainlock(struct tdb_context *tdb, const TDB_DATA *key,
 
        lockstart = hlock_range(group, &locksize);
 
-       ret = tdb_lock_hashes(tdb, lockstart, locksize, ltype, waitflag);
+       ecode = tdb_lock_hashes(tdb, lockstart, locksize, ltype, waitflag);
        tdb_trace_1rec(tdb, func, *key);
-       return ret;
+       if (ecode != TDB_SUCCESS) {
+               tdb->ecode = ecode;
+               return -1;
+       }
+       return 0;
 }
 
 /* lock/unlock one hash chain. This is meant to be used to reduce
@@ -787,6 +799,7 @@ int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key)
        uint64_t h = tdb_hash(tdb, key.dptr, key.dsize);
        tdb_off_t lockstart, locksize;
        unsigned int group, gbits;
+       enum TDB_ERROR ecode;
 
        gbits = TDB_TOPLEVEL_HASH_BITS - TDB_HASH_GROUP_BITS;
        group = bits_from(h, 64 - gbits, gbits);
@@ -794,5 +807,10 @@ int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key)
        lockstart = hlock_range(group, &locksize);
 
        tdb_trace_1rec(tdb, "tdb_chainunlock", key);
-       return tdb_unlock_hashes(tdb, lockstart, locksize, F_WRLCK);
+       ecode = tdb_unlock_hashes(tdb, lockstart, locksize, F_WRLCK);
+       if (ecode != TDB_SUCCESS) {
+               tdb->ecode = ecode;
+               return -1;
+       }
+       return 0;
 }