From: Rusty Russell Date: Mon, 12 Sep 2011 04:51:40 +0000 (+0930) Subject: tdb2: add error conversion functions. X-Git-Url: https://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=afa6d57b7d93fe4675a952f556eb462951baa257 tdb2: add error conversion functions. This clarifies the code a little, but also provides a more explicit mechanism which can be used to debug error handling (by introducing tdb_err_t and making it a pointer type). --- diff --git a/ccan/tdb2/check.c b/ccan/tdb2/check.c index a8b5b3d5..3003b626 100644 --- a/ccan/tdb2/check.c +++ b/ccan/tdb2/check.c @@ -148,7 +148,7 @@ static enum TDB_ERROR check_hash_chain(struct tdb_context *tdb, off = tdb_read_off(tdb, off + offsetof(struct tdb_chain, next)); if (TDB_OFF_IS_ERR(off)) { - return off; + return TDB_OFF_TO_ERR(off); } if (off == 0) return TDB_SUCCESS; @@ -534,7 +534,7 @@ static enum TDB_ERROR check_free_table(struct tdb_context *tdb, h = bucket_off(ftable_off, i); for (off = tdb_read_off(tdb, h); off; off = f.next) { if (TDB_OFF_IS_ERR(off)) { - return off; + return TDB_OFF_TO_ERR(off); } if (!first) { off &= TDB_OFF_MASK; @@ -589,7 +589,7 @@ tdb_off_t dead_space(struct tdb_context *tdb, tdb_off_t off) char c; ecode = tdb->tdb2.io->tread(tdb, off, &c, 1); if (ecode != TDB_SUCCESS) { - return ecode; + return TDB_ERR_TO_OFF(ecode); } if (c != 0 && c != 0x43) break; @@ -634,7 +634,7 @@ static enum TDB_ERROR check_linear(struct tdb_context *tdb, } else { len = dead_space(tdb, off); if (TDB_OFF_IS_ERR(len)) { - return len; + return TDB_OFF_TO_ERR(len); } if (len < sizeof(rec.r)) { return tdb_logerr(tdb, TDB_ERR_CORRUPT, @@ -811,7 +811,7 @@ enum TDB_ERROR tdb_check_(struct tdb_context *tdb, for (ft = first_ftable(tdb); ft; ft = next_ftable(tdb, ft)) { if (TDB_OFF_IS_ERR(ft)) { - ecode = ft; + ecode = TDB_OFF_TO_ERR(ft); goto out; } ecode = check_free_table(tdb, ft, num_ftables, fr, num_free, diff --git a/ccan/tdb2/free.c b/ccan/tdb2/free.c index 658adec1..1b2c552a 100644 --- a/ccan/tdb2/free.c +++ b/ccan/tdb2/free.c @@ -70,7 +70,7 @@ enum TDB_ERROR tdb_ftable_init(struct tdb_context *tdb) while (off) { if (TDB_OFF_IS_ERR(off)) { - return off; + return TDB_OFF_TO_ERR(off); } rnd = random(); @@ -146,14 +146,14 @@ static enum TDB_ERROR remove_from_list(struct tdb_context *tdb, /* Get prev->next */ prev_next = tdb_read_off(tdb, off); if (TDB_OFF_IS_ERR(prev_next)) - return prev_next; + return TDB_OFF_TO_ERR(prev_next); /* If prev->next == 0, we were head: update bucket to point to next. */ if (prev_next == 0) { /* We must preserve upper bits. */ head = tdb_read_off(tdb, b_off); if (TDB_OFF_IS_ERR(head)) - return head; + return TDB_OFF_TO_ERR(head); if ((head & TDB_OFF_MASK) != r_off) { return tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, @@ -178,7 +178,7 @@ static enum TDB_ERROR remove_from_list(struct tdb_context *tdb, if (r->next == 0) { head = tdb_read_off(tdb, b_off); if (TDB_OFF_IS_ERR(head)) - return head; + return TDB_OFF_TO_ERR(head); head &= TDB_OFF_MASK; off = head + offsetof(struct tdb_free_record, magic_and_prev); } else { @@ -215,7 +215,7 @@ static enum TDB_ERROR enqueue_in_free(struct tdb_context *tdb, head = tdb_read_off(tdb, b_off); if (TDB_OFF_IS_ERR(head)) - return head; + return TDB_OFF_TO_ERR(head); /* We only need to set ftable_and_len; rest is set in enqueue_in_free */ new.ftable_and_len = ((uint64_t)tdb->tdb2.ftable << (64 - TDB_OFF_UPPER_STEAL)) @@ -336,7 +336,7 @@ static tdb_len_t coalesce(struct tdb_context *tdb, nb_off = ftable_offset(tdb, ftable); if (TDB_OFF_IS_ERR(nb_off)) { tdb_access_release(tdb, r); - ecode = nb_off; + ecode = TDB_OFF_TO_ERR(nb_off); goto err; } nb_off = bucket_off(nb_off, bucket); @@ -372,7 +372,7 @@ static tdb_len_t coalesce(struct tdb_context *tdb, /* Did we just mess up a record you were hoping to use? */ if (end == *protect) { tdb->stats.alloc_coalesce_iterate_clash++; - *protect = TDB_ERR_NOEXIST; + *protect = TDB_ERR_TO_OFF(TDB_ERR_NOEXIST); } ecode = remove_from_list(tdb, nb_off, end, &rec); @@ -393,7 +393,7 @@ static tdb_len_t coalesce(struct tdb_context *tdb, /* Before we expand, check this isn't one you wanted protected? */ if (off == *protect) { - *protect = TDB_ERR_EXISTS; + *protect = TDB_ERR_TO_OFF(TDB_ERR_EXISTS); tdb->stats.alloc_coalesce_iterate_clash++; } @@ -421,7 +421,7 @@ static tdb_len_t coalesce(struct tdb_context *tdb, if (ecode != TDB_SUCCESS) { /* Need to drop lock. Can't rely on anything stable. */ tdb->stats.alloc_coalesce_lockfail++; - *protect = TDB_ERR_CORRUPT; + *protect = TDB_ERR_TO_OFF(TDB_ERR_CORRUPT); /* We have to drop this to avoid deadlocks, so make sure record * doesn't get coalesced by someone else! */ @@ -441,7 +441,7 @@ static tdb_len_t coalesce(struct tdb_context *tdb, ecode = add_free_record(tdb, off, end - off, TDB_LOCK_WAIT, false); if (ecode != TDB_SUCCESS) { - return ecode; + return TDB_ERR_TO_OFF(ecode); } } else if (TDB_OFF_IS_ERR(*protect)) { /* For simplicity, we always drop lock if they can't continue */ @@ -455,7 +455,7 @@ static tdb_len_t coalesce(struct tdb_context *tdb, err: /* To unify error paths, we *always* unlock bucket on error. */ tdb_unlock_free_bucket(tdb, b_off); - return ecode; + return TDB_ERR_TO_OFF(ecode); } /* List is locked: we unlock it. */ @@ -469,7 +469,7 @@ static enum TDB_ERROR coalesce_list(struct tdb_context *tdb, off = tdb_read_off(tdb, b_off); if (TDB_OFF_IS_ERR(off)) { - ecode = off; + ecode = TDB_OFF_TO_ERR(off); goto unlock_err; } /* A little bit of paranoia: counter should be 0. */ @@ -488,7 +488,7 @@ static enum TDB_ERROR coalesce_list(struct tdb_context *tdb, coal = coalesce(tdb, off, b_off, frec_len(&rec), &next); if (TDB_OFF_IS_ERR(coal)) { /* This has already unlocked on error. */ - return coal; + return TDB_OFF_TO_ERR(coal); } if (TDB_OFF_IS_ERR(next)) { /* Coalescing had to unlock, so stop. */ @@ -520,7 +520,7 @@ static enum TDB_ERROR coalesce_list(struct tdb_context *tdb, /* Get the old head. */ oldhoff = tdb_read_off(tdb, b_off); if (TDB_OFF_IS_ERR(oldhoff)) { - ecode = oldhoff; + ecode = TDB_OFF_TO_ERR(oldhoff); goto unlock_err; } @@ -661,7 +661,7 @@ static tdb_off_t lock_and_alloc(struct tdb_context *tdb, /* Lock this bucket. */ ecode = tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT); if (ecode != TDB_SUCCESS) { - return ecode; + return TDB_ERR_TO_OFF(ecode); } best.ftable_and_len = -1ULL; @@ -677,7 +677,7 @@ static tdb_off_t lock_and_alloc(struct tdb_context *tdb, * as we go. */ off = tdb_read_off(tdb, b_off); if (TDB_OFF_IS_ERR(off)) { - ecode = off; + ecode = TDB_OFF_TO_ERR(off); goto unlock_err; } off &= TDB_OFF_MASK; @@ -768,7 +768,7 @@ static tdb_off_t lock_and_alloc(struct tdb_context *tdb, + frec_len(&best) - leftover, leftover, TDB_LOCK_WAIT, false); if (ecode != TDB_SUCCESS) { - best_off = ecode; + best_off = TDB_ERR_TO_OFF(ecode); } } tdb_unlock_free_bucket(tdb, b_off); @@ -781,7 +781,7 @@ static tdb_off_t lock_and_alloc(struct tdb_context *tdb, unlock_err: tdb_unlock_free_bucket(tdb, b_off); - return ecode; + return TDB_ERR_TO_OFF(ecode); } /* Get a free block from current free list, or 0 if none, -ve on error. */ @@ -960,7 +960,7 @@ tdb_off_t alloc(struct tdb_context *tdb, size_t keylen, size_t datalen, ecode = tdb_expand(tdb, adjust_size(keylen, datalen)); if (ecode != TDB_SUCCESS) { - return ecode; + return TDB_ERR_TO_OFF(ecode); } } diff --git a/ccan/tdb2/hash.c b/ccan/tdb2/hash.c index 5eee41a8..619d56f8 100644 --- a/ccan/tdb2/hash.c +++ b/ccan/tdb2/hash.c @@ -90,7 +90,7 @@ static tdb_bool_err key_matches(struct tdb_context *tdb, rkey = tdb_access_read(tdb, off + sizeof(*rec), key->dsize, false); if (TDB_PTR_IS_ERR(rkey)) { - return TDB_PTR_ERR(rkey); + return (tdb_bool_err)TDB_PTR_ERR(rkey); } if (memcmp(rkey, key->dptr, key->dsize) == 0) ret = true; @@ -128,7 +128,7 @@ static tdb_bool_err match(struct tdb_context *tdb, off = val & TDB_OFF_MASK; ecode = tdb_read_convert(tdb, off, rec, sizeof(*rec)); if (ecode != TDB_SUCCESS) { - return ecode; + return (tdb_bool_err)ecode; } if ((h->h & ((1 << 11)-1)) != rec_hash(rec)) { @@ -176,7 +176,7 @@ static tdb_off_t COLD find_in_chain(struct tdb_context *tdb, h->group_start = off; ecode = tdb_read_convert(tdb, off, h->group, sizeof(h->group)); if (ecode != TDB_SUCCESS) { - return ecode; + return TDB_ERR_TO_OFF(ecode); } for (i = 0; i < (1 << TDB_HASH_GROUP_BITS); i++) { @@ -193,14 +193,15 @@ static tdb_off_t COLD find_in_chain(struct tdb_context *tdb, ecode = tdb_read_convert(tdb, recoff, rec, sizeof(*rec)); if (ecode != TDB_SUCCESS) { - return ecode; + return TDB_ERR_TO_OFF(ecode); } - ecode = key_matches(tdb, rec, recoff, &key); + ecode = TDB_OFF_TO_ERR(key_matches(tdb, rec, recoff, + &key)); if (ecode < 0) { - return ecode; + return TDB_ERR_TO_OFF(ecode); } - if (ecode == 1) { + if (ecode == (enum TDB_ERROR)1) { h->home_bucket = h->found_bucket = i; if (tinfo) { @@ -252,7 +253,7 @@ tdb_off_t find_and_lock(struct tdb_context *tdb, ecode = tdb_lock_hashes(tdb, h->hlock_start, h->hlock_range, ltype, TDB_LOCK_WAIT); if (ecode != TDB_SUCCESS) { - return ecode; + return TDB_ERR_TO_OFF(ecode); } hashtable = offsetof(struct tdb_header, hashtable); @@ -315,7 +316,7 @@ tdb_off_t find_and_lock(struct tdb_context *tdb, berr = match(tdb, h, &key, h->group[h->found_bucket], rec); if (berr < 0) { - ecode = berr; + ecode = TDB_OFF_TO_ERR(berr); goto fail; } if (berr) { @@ -334,7 +335,7 @@ tdb_off_t find_and_lock(struct tdb_context *tdb, fail: tdb_unlock_hashes(tdb, h->hlock_start, h->hlock_range, ltype); - return ecode; + return TDB_ERR_TO_OFF(ecode); } /* I wrote a simple test, expanding a hash to 2GB, for the following @@ -426,7 +427,7 @@ static enum TDB_ERROR COLD add_to_chain(struct tdb_context *tdb, entry = tdb_find_zero_off(tdb, subhash, 1<tdb2.io->direct(tdb, off, sizeof(*p), false); if (TDB_PTR_IS_ERR(p)) { - return TDB_PTR_ERR(p); + return TDB_ERR_TO_OFF(TDB_PTR_ERR(p)); } if (p) return *p; @@ -237,7 +237,7 @@ tdb_off_t tdb_read_off(struct tdb_context *tdb, tdb_off_t off) ecode = tdb_read_convert(tdb, off, &ret, sizeof(ret)); if (ecode != TDB_SUCCESS) { - return ecode; + return TDB_ERR_TO_OFF(ecode); } return ret; } diff --git a/ccan/tdb2/lock.c b/ccan/tdb2/lock.c index bf62d971..a71c95f6 100644 --- a/ccan/tdb2/lock.c +++ b/ccan/tdb2/lock.c @@ -415,7 +415,7 @@ enum TDB_ERROR tdb_nest_lock(struct tdb_context *tdb, tdb_brunlock(tdb, ltype, offset, 1); if (berr < 0) - return berr; + return TDB_OFF_TO_ERR(berr); ecode = tdb_lock_and_recover(tdb); if (ecode == TDB_SUCCESS) { ecode = tdb_brlock(tdb, ltype, offset, 1, @@ -613,7 +613,7 @@ again: tdb_allrecord_unlock(tdb, ltype); if (berr < 0) - return berr; + return TDB_OFF_TO_ERR(berr); ecode = tdb_lock_and_recover(tdb); if (ecode != TDB_SUCCESS) { return ecode; diff --git a/ccan/tdb2/open.c b/ccan/tdb2/open.c index 3e3b083e..dad35348 100644 --- a/ccan/tdb2/open.c +++ b/ccan/tdb2/open.c @@ -706,7 +706,7 @@ finished: berr = tdb_needs_recovery(tdb); if (unlikely(berr != false)) { if (berr < 0) { - ecode = berr; + ecode = TDB_OFF_TO_ERR(berr); goto fail; } ecode = tdb_lock_and_recover(tdb); @@ -727,18 +727,18 @@ finished: fail: /* Map ecode to some logical errno. */ - switch (ecode) { - case TDB_ERR_CORRUPT: - case TDB_ERR_IO: + switch (TDB_ERR_TO_OFF(ecode)) { + case TDB_ERR_TO_OFF(TDB_ERR_CORRUPT): + case TDB_ERR_TO_OFF(TDB_ERR_IO): saved_errno = EIO; break; - case TDB_ERR_LOCK: + case TDB_ERR_TO_OFF(TDB_ERR_LOCK): saved_errno = EWOULDBLOCK; break; - case TDB_ERR_OOM: + case TDB_ERR_TO_OFF(TDB_ERR_OOM): saved_errno = ENOMEM; break; - case TDB_ERR_EINVAL: + case TDB_ERR_TO_OFF(TDB_ERR_EINVAL): saved_errno = EINVAL; break; default: diff --git a/ccan/tdb2/private.h b/ccan/tdb2/private.h index 75e44ad8..8778dbc3 100644 --- a/ccan/tdb2/private.h +++ b/ccan/tdb2/private.h @@ -65,7 +65,9 @@ typedef uint64_t tdb_off_t; #define TDB_RECOVERY_MAGIC (0xf53bc0e7ad124589ULL) #define TDB_RECOVERY_INVALID_MAGIC (0x0ULL) -#define TDB_OFF_IS_ERR(off) unlikely(off >= (tdb_off_t)TDB_ERR_LAST) +#define TDB_OFF_IS_ERR(off) unlikely(off >= (tdb_off_t)(long)TDB_ERR_LAST) +#define TDB_OFF_TO_ERR(off) ((enum TDB_ERROR)(long)(off)) +#define TDB_ERR_TO_OFF(ecode) ((tdb_off_t)(long)(ecode)) /* Packing errors into pointers and v.v. */ #define TDB_PTR_IS_ERR(ptr) \ diff --git a/ccan/tdb2/summary.c b/ccan/tdb2/summary.c index 3960a20d..4a22f2e5 100644 --- a/ccan/tdb2/summary.c +++ b/ccan/tdb2/summary.c @@ -28,7 +28,7 @@ static tdb_off_t count_hash(struct tdb_context *tdb, h = tdb_access_read(tdb, hash_off, sizeof(*h) << bits, true); if (TDB_PTR_IS_ERR(h)) { - return TDB_PTR_ERR(h); + return TDB_ERR_TO_OFF(TDB_PTR_ERR(h)); } for (i = 0; i < (1 << bits); i++) count += (h[i] != 0); @@ -93,7 +93,7 @@ static enum TDB_ERROR summarize(struct tdb_context *tdb, off + sizeof(p->u), TDB_SUBLEVEL_HASH_BITS); if (TDB_OFF_IS_ERR(count)) { - return count; + return TDB_OFF_TO_ERR(count); } tally_add(hashes, count); tally_add(extra, rec_extra_padding(&p->u)); @@ -115,7 +115,7 @@ static enum TDB_ERROR summarize(struct tdb_context *tdb, } else { len = dead_space(tdb, off); if (TDB_OFF_IS_ERR(len)) { - return len; + return TDB_OFF_TO_ERR(len); } } tdb_access_release(tdb, p); diff --git a/ccan/tdb2/tdb.c b/ccan/tdb2/tdb.c index 53e1de62..e0c7d957 100644 --- a/ccan/tdb2/tdb.c +++ b/ccan/tdb2/tdb.c @@ -50,7 +50,7 @@ static enum TDB_ERROR replace_data(struct tdb_context *tdb, new_off = alloc(tdb, key.dsize, dbuf.dsize, h->h, TDB_USED_MAGIC, growing); if (TDB_OFF_IS_ERR(new_off)) { - return new_off; + return TDB_OFF_TO_ERR(new_off); } /* We didn't like the existing one: remove it. */ @@ -122,7 +122,7 @@ enum TDB_ERROR tdb_store(struct tdb_context *tdb, off = find_and_lock(tdb, key, F_WRLCK, &h, &rec, NULL); if (TDB_OFF_IS_ERR(off)) { - return tdb->last_error = off; + return tdb->last_error = TDB_OFF_TO_ERR(off); } /* Now we have lock on this hash bucket. */ @@ -191,7 +191,7 @@ enum TDB_ERROR tdb_append(struct tdb_context *tdb, off = find_and_lock(tdb, key, F_WRLCK, &h, &rec, NULL); if (TDB_OFF_IS_ERR(off)) { - return tdb->last_error = off; + return tdb->last_error = TDB_OFF_TO_ERR(off); } if (off) { @@ -259,7 +259,7 @@ enum TDB_ERROR tdb_fetch(struct tdb_context *tdb, struct tdb_data key, off = find_and_lock(tdb, key, F_RDLCK, &h, &rec, NULL); if (TDB_OFF_IS_ERR(off)) { - return tdb->last_error = off; + return tdb->last_error = TDB_OFF_TO_ERR(off); } if (!off) { @@ -290,7 +290,7 @@ bool tdb_exists(struct tdb_context *tdb, TDB_DATA key) off = find_and_lock(tdb, key, F_RDLCK, &h, &rec, NULL); if (TDB_OFF_IS_ERR(off)) { - tdb->last_error = off; + tdb->last_error = TDB_OFF_TO_ERR(off); return false; } tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range, F_RDLCK); @@ -314,7 +314,7 @@ enum TDB_ERROR tdb_delete(struct tdb_context *tdb, struct tdb_data key) off = find_and_lock(tdb, key, F_WRLCK, &h, &rec, NULL); if (TDB_OFF_IS_ERR(off)) { - return tdb->last_error = off; + return tdb->last_error = TDB_OFF_TO_ERR(off); } if (!off) { @@ -465,16 +465,16 @@ void tdb_remove_flag(struct tdb_context *tdb, unsigned flag) const char *tdb_errorstr(enum TDB_ERROR ecode) { /* Gcc warns if you miss a case in the switch, so use that. */ - switch (ecode) { - case TDB_SUCCESS: return "Success"; - case TDB_ERR_CORRUPT: return "Corrupt database"; - case TDB_ERR_IO: return "IO Error"; - case TDB_ERR_LOCK: return "Locking error"; - case TDB_ERR_OOM: return "Out of memory"; - case TDB_ERR_EXISTS: return "Record exists"; - case TDB_ERR_EINVAL: return "Invalid parameter"; - case TDB_ERR_NOEXIST: return "Record does not exist"; - case TDB_ERR_RDONLY: return "write not permitted"; + switch (TDB_ERR_TO_OFF(ecode)) { + case TDB_ERR_TO_OFF(TDB_SUCCESS): return "Success"; + case TDB_ERR_TO_OFF(TDB_ERR_CORRUPT): return "Corrupt database"; + case TDB_ERR_TO_OFF(TDB_ERR_IO): return "IO Error"; + case TDB_ERR_TO_OFF(TDB_ERR_LOCK): return "Locking error"; + case TDB_ERR_TO_OFF(TDB_ERR_OOM): return "Out of memory"; + case TDB_ERR_TO_OFF(TDB_ERR_EXISTS): return "Record exists"; + case TDB_ERR_TO_OFF(TDB_ERR_EINVAL): return "Invalid parameter"; + case TDB_ERR_TO_OFF(TDB_ERR_NOEXIST): return "Record does not exist"; + case TDB_ERR_TO_OFF(TDB_ERR_RDONLY): return "write not permitted"; } return "Invalid error code"; } @@ -533,7 +533,7 @@ enum TDB_ERROR tdb_parse_record_(struct tdb_context *tdb, off = find_and_lock(tdb, key, F_RDLCK, &h, &rec, NULL); if (TDB_OFF_IS_ERR(off)) { - return tdb->last_error = off; + return tdb->last_error = TDB_OFF_TO_ERR(off); } if (!off) { @@ -571,14 +571,14 @@ int64_t tdb_get_seqnum(struct tdb_context *tdb) val = tdb1_get_seqnum(tdb); if (tdb->last_error != TDB_SUCCESS) - return tdb->last_error; + return TDB_ERR_TO_OFF(tdb->last_error); else return val; } off = tdb_read_off(tdb, offsetof(struct tdb_header, seqnum)); if (TDB_OFF_IS_ERR(off)) - tdb->last_error = off; + tdb->last_error = TDB_OFF_TO_ERR(off); else tdb->last_error = TDB_SUCCESS; return off; diff --git a/ccan/tdb2/tdb1_transaction.c b/ccan/tdb2/tdb1_transaction.c index 157642a6..411caef3 100644 --- a/ccan/tdb2/tdb1_transaction.c +++ b/ccan/tdb2/tdb1_transaction.c @@ -1318,7 +1318,7 @@ tdb_bool_err tdb1_needs_recovery(struct tdb_context *tdb) /* find the recovery area */ if (tdb1_ofs_read(tdb, TDB1_RECOVERY_HEAD, &recovery_head) == -1) { - return tdb->last_error; + return TDB_ERR_TO_OFF(tdb->last_error); } if (recovery_head == 0) { @@ -1329,7 +1329,7 @@ tdb_bool_err tdb1_needs_recovery(struct tdb_context *tdb) /* read the recovery record */ if (tdb->tdb1.io->tdb1_read(tdb, recovery_head, &rec, sizeof(rec), TDB1_DOCONV()) == -1) { - return tdb->last_error; + return TDB_ERR_TO_OFF(tdb->last_error); } return (rec.magic == TDB1_RECOVERY_MAGIC); diff --git a/ccan/tdb2/transaction.c b/ccan/tdb2/transaction.c index 1f5709bf..1af1c4ac 100644 --- a/ccan/tdb2/transaction.c +++ b/ccan/tdb2/transaction.c @@ -668,7 +668,7 @@ static enum TDB_ERROR tdb_recovery_area(struct tdb_context *tdb, *recovery_offset = tdb_read_off(tdb, offsetof(struct tdb_header, recovery)); if (TDB_OFF_IS_ERR(*recovery_offset)) { - return *recovery_offset; + return TDB_OFF_TO_ERR(*recovery_offset); } if (*recovery_offset == 0) { @@ -852,9 +852,10 @@ static tdb_off_t create_recovery_area(struct tdb_context *tdb, tdb->stats.transaction_expand_file++; ecode = methods->expand_file(tdb, addition); if (ecode != TDB_SUCCESS) { - return tdb_logerr(tdb, ecode, TDB_LOG_ERROR, - "tdb_recovery_allocate:" - " failed to create recovery area"); + tdb_logerr(tdb, ecode, TDB_LOG_ERROR, + "tdb_recovery_allocate:" + " failed to create recovery area"); + return TDB_ERR_TO_OFF(ecode); } /* we have to reset the old map size so that we don't try to @@ -869,9 +870,10 @@ static tdb_off_t create_recovery_area(struct tdb_context *tdb, ecode = methods->twrite(tdb, offsetof(struct tdb_header, recovery), &recovery_off, sizeof(tdb_off_t)); if (ecode != TDB_SUCCESS) { - return tdb_logerr(tdb, ecode, TDB_LOG_ERROR, - "tdb_recovery_allocate:" - " failed to write recovery head"); + tdb_logerr(tdb, ecode, TDB_LOG_ERROR, + "tdb_recovery_allocate:" + " failed to write recovery head"); + return TDB_ERR_TO_OFF(ecode); } transaction_write_existing(tdb, offsetof(struct tdb_header, recovery), &recovery_off, @@ -928,7 +930,7 @@ static enum TDB_ERROR transaction_setup_recovery(struct tdb_context *tdb) recovery); if (TDB_OFF_IS_ERR(recovery_off)) { free(recovery); - return recovery_off; + return TDB_OFF_TO_ERR(recovery_off); } } @@ -1194,7 +1196,8 @@ enum TDB_ERROR tdb_transaction_recover(struct tdb_context *tdb) /* find the recovery area */ recovery_head = tdb_read_off(tdb, offsetof(struct tdb_header,recovery)); if (TDB_OFF_IS_ERR(recovery_head)) { - return tdb_logerr(tdb, recovery_head, TDB_LOG_ERROR, + ecode = TDB_OFF_TO_ERR(recovery_head); + return tdb_logerr(tdb, ecode, TDB_LOG_ERROR, "tdb_transaction_recover:" " failed to read recovery head"); } @@ -1330,7 +1333,7 @@ tdb_bool_err tdb_needs_recovery(struct tdb_context *tdb) /* read the recovery record */ ecode = tdb_read_convert(tdb, recovery_head, &rec, sizeof(rec)); if (ecode != TDB_SUCCESS) { - return ecode; + return TDB_ERR_TO_OFF(ecode); } return (rec.magic == TDB_RECOVERY_MAGIC); diff --git a/ccan/tdb2/traverse.c b/ccan/tdb2/traverse.c index c525fdfe..0bf41899 100644 --- a/ccan/tdb2/traverse.c +++ b/ccan/tdb2/traverse.c @@ -31,7 +31,7 @@ int64_t tdb_traverse_(struct tdb_context *tdb, if (tdb->flags & TDB_VERSION1) { count = tdb1_traverse(tdb, fn, p); if (count == -1) - return tdb->last_error; + return TDB_ERR_TO_OFF(tdb->last_error); return count; } @@ -51,7 +51,7 @@ int64_t tdb_traverse_(struct tdb_context *tdb, } if (ecode != TDB_ERR_NOEXIST) { - return tdb->last_error = ecode; + return TDB_ERR_TO_OFF(tdb->last_error = ecode); } tdb->last_error = TDB_SUCCESS; return count; @@ -96,7 +96,7 @@ enum TDB_ERROR tdb_nextkey(struct tdb_context *tdb, struct tdb_data *key) tinfo.prev = find_and_lock(tdb, *key, F_RDLCK, &h, &rec, &tinfo); free(key->dptr); if (TDB_OFF_IS_ERR(tinfo.prev)) { - return tdb->last_error = tinfo.prev; + return tdb->last_error = TDB_OFF_TO_ERR(tinfo.prev); } tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range, F_RDLCK); @@ -128,7 +128,7 @@ enum TDB_ERROR tdb_wipe_all(struct tdb_context *tdb) /* FIXME: Be smarter. */ count = tdb_traverse(tdb, wipe_one, &ecode); if (count < 0) - ecode = count; + ecode = TDB_OFF_TO_ERR(count); tdb_allrecord_unlock(tdb, F_WRLCK); return tdb->last_error = ecode; }