From: Rusty Russell Date: Tue, 1 Mar 2011 12:49:19 +0000 (+1030) Subject: tdb2: rework remaining io.c functions to return enum TDB_ERROR. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=323a9473c0aef80b8e18ef0c53529c8dfc29ec45 tdb2: rework remaining io.c functions to return enum TDB_ERROR. In particular, we replace the TDB_OFF_ERR ((off_t)-1) with a range of negative error values. --- diff --git a/ccan/tdb2/check.c b/ccan/tdb2/check.c index 1b351672..d4f1d343 100644 --- a/ccan/tdb2/check.c +++ b/ccan/tdb2/check.c @@ -136,8 +136,10 @@ static bool check_hash_chain(struct tdb_context *tdb, return false; off = tdb_read_off(tdb, off + offsetof(struct tdb_chain, next)); - if (off == TDB_OFF_ERR) + if (TDB_OFF_IS_ERR(off)) { + tdb->ecode = off; return false; + } if (off == 0) return true; (*num_found)++; @@ -512,8 +514,10 @@ static bool 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 (off == TDB_OFF_ERR) + if (TDB_OFF_IS_ERR(off)) { + tdb->ecode = off; return false; + } ecode = tdb_read_convert(tdb, off, &f, sizeof(f)); if (ecode != TDB_SUCCESS) { tdb->ecode = ecode; @@ -725,7 +729,7 @@ int tdb_check(struct tdb_context *tdb, enum TDB_ERROR ecode; ecode = tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false); - if (ecpde != TDB_SUCCESS) { + if (ecode != TDB_SUCCESS) { tdb->ecode = ecode; return -1; } @@ -745,8 +749,10 @@ int tdb_check(struct tdb_context *tdb, goto fail; for (ft = first_ftable(tdb); ft; ft = next_ftable(tdb, ft)) { - if (ft == TDB_OFF_ERR) + if (TDB_OFF_IS_ERR(ft)) { + tdb->ecode = ft; goto fail; + } if (!check_free_table(tdb, ft, num_ftables, fr, num_free, &num_found)) goto fail; diff --git a/ccan/tdb2/free.c b/ccan/tdb2/free.c index 4f9a52a1..897d3cbe 100644 --- a/ccan/tdb2/free.c +++ b/ccan/tdb2/free.c @@ -69,8 +69,10 @@ int tdb_ftable_init(struct tdb_context *tdb) tdb->ftable = 0; while (off) { - if (off == TDB_OFF_ERR) + if (TDB_OFF_IS_ERR(off)) { + tdb->ecode = off; return -1; + } rnd = random(); if (rnd >= max) { @@ -92,7 +94,7 @@ tdb_off_t bucket_off(tdb_off_t ftable_off, unsigned bucket) + bucket * sizeof(tdb_off_t); } -/* Returns free_buckets + 1, or list number to search. */ +/* Returns free_buckets + 1, or list number to search, or -ve error. */ static tdb_off_t find_free_head(struct tdb_context *tdb, tdb_off_t ftable_off, tdb_off_t bucket) @@ -173,8 +175,10 @@ static int enqueue_in_free(struct tdb_context *tdb, /* new->next = head. */ new.next = tdb_read_off(tdb, b_off); - if (new.next == TDB_OFF_ERR) + if (TDB_OFF_IS_ERR(new.next)) { + tdb->ecode = new.next; return -1; + } if (new.next) { #ifdef CCAN_TDB2_DEBUG @@ -275,8 +279,13 @@ static tdb_off_t ftable_offset(struct tdb_context *tdb, unsigned int ftable) return tdb->ftable_off; off = first_ftable(tdb); - for (i = 0; i < ftable; i++) + for (i = 0; i < ftable; i++) { + if (TDB_OFF_IS_ERR(off)) { + tdb->ecode = off; + break; + } off = next_ftable(tdb, off); + } return off; } @@ -436,8 +445,10 @@ again: /* Walk the list to see if any are large enough, getting less fussy * as we go. */ off = tdb_read_off(tdb, b_off); - if (unlikely(off == TDB_OFF_ERR)) + if (TDB_OFF_IS_ERR(off)) { + tdb->ecode = off; goto unlock_err; + } while (off) { const struct tdb_free_record *r; @@ -540,7 +551,7 @@ static tdb_off_t get_free(struct tdb_context *tdb, unsigned magic, unsigned hashlow) { tdb_off_t off, ftable_off; - unsigned start_b, b, ftable; + tdb_off_t start_b, b, ftable; bool wrapped = false; /* If they are growing, add 50% to get to higher bucket. */ @@ -576,13 +587,26 @@ static tdb_off_t get_free(struct tdb_context *tdb, /* Didn't work. Try next bucket. */ } + if (TDB_OFF_IS_ERR(b)) { + tdb->ecode = b; + return 0; + } + /* Hmm, try next table. */ ftable_off = next_ftable(tdb, ftable_off); + if (TDB_OFF_IS_ERR(ftable_off)) { + tdb->ecode = ftable_off; + return 0; + } ftable++; if (ftable_off == 0) { wrapped = true; ftable_off = first_ftable(tdb); + if (TDB_OFF_IS_ERR(ftable_off)) { + tdb->ecode = ftable_off; + return 0; + } ftable = 0; } } diff --git a/ccan/tdb2/hash.c b/ccan/tdb2/hash.c index 260c36f2..67bb56f4 100644 --- a/ccan/tdb2/hash.c +++ b/ccan/tdb2/hash.c @@ -225,8 +225,10 @@ static tdb_off_t COLD find_in_chain(struct tdb_context *tdb, } next = tdb_read_off(tdb, off + offsetof(struct tdb_chain, next)); - if (next == TDB_OFF_ERR) + if (TDB_OFF_IS_ERR(next)) { + tdb->ecode = next; return TDB_OFF_ERR; + } if (next) next += sizeof(struct tdb_used_record); } @@ -430,16 +432,24 @@ static int COLD add_to_chain(struct tdb_context *tdb, tdb_off_t subhash, tdb_off_t new_off) { - size_t entry = tdb_find_zero_off(tdb, subhash, 1<ecode = entry; + return -1; + } + if (entry == 1 << TDB_HASH_GROUP_BITS) { tdb_off_t next; next = tdb_read_off(tdb, subhash + offsetof(struct tdb_chain, next)); - if (next == TDB_OFF_ERR) + if (TDB_OFF_IS_ERR(next)) { + tdb->ecode = next; return -1; + } if (!next) { next = alloc(tdb, 0, sizeof(struct tdb_chain), 0, @@ -692,8 +702,7 @@ int add_to_hash(struct tdb_context *tdb, struct hash_info *h, tdb_off_t new_off) static tdb_off_t iterate_hash(struct tdb_context *tdb, struct traverse_info *tinfo) { - tdb_off_t off, val; - unsigned int i; + tdb_off_t off, val, i; struct traverse_level *tlevel; tlevel = &tinfo->levels[tinfo->num_levels-1]; @@ -704,9 +713,16 @@ again: i != tlevel->total_buckets; i = tdb_find_nonzero_off(tdb, tlevel->hashtable, i+1, tlevel->total_buckets)) { + if (TDB_OFF_IS_ERR(i)) { + tdb->ecode = i; + return TDB_OFF_ERR; + } + val = tdb_read_off(tdb, tlevel->hashtable+sizeof(tdb_off_t)*i); - if (unlikely(val == TDB_OFF_ERR)) + if (TDB_OFF_IS_ERR(val)) { + tdb->ecode = val; return TDB_OFF_ERR; + } off = val & TDB_OFF_MASK; @@ -746,8 +762,10 @@ again: tlevel->hashtable = tdb_read_off(tdb, tlevel->hashtable + offsetof(struct tdb_chain, next)); - if (tlevel->hashtable == TDB_OFF_ERR) + if (TDB_OFF_IS_ERR(tlevel->hashtable)) { + tdb->ecode = tlevel->hashtable; return TDB_OFF_ERR; + } if (tlevel->hashtable) { tlevel->hashtable += sizeof(struct tdb_used_record); tlevel->entry = 0; diff --git a/ccan/tdb2/io.c b/ccan/tdb2/io.c index 7d20f46a..a9016c4f 100644 --- a/ccan/tdb2/io.c +++ b/ccan/tdb2/io.c @@ -133,6 +133,7 @@ void *tdb_convert(const struct tdb_context *tdb, void *buf, tdb_len_t size) return buf; } +/* Return first non-zero offset in offset array, or end, or -ve error. */ /* FIXME: Return the off? */ uint64_t tdb_find_nonzero_off(struct tdb_context *tdb, tdb_off_t base, uint64_t start, uint64_t end) @@ -144,8 +145,7 @@ uint64_t tdb_find_nonzero_off(struct tdb_context *tdb, val = tdb_access_read(tdb, base + start * sizeof(tdb_off_t), (end - start) * sizeof(tdb_off_t), false); if (TDB_PTR_IS_ERR(val)) { - tdb->ecode = TDB_PTR_ERR(val); - return end; + return TDB_PTR_ERR(val); } for (i = 0; i < (end - start); i++) { @@ -156,7 +156,7 @@ uint64_t tdb_find_nonzero_off(struct tdb_context *tdb, return start + i; } -/* Return first zero offset in num offset array, or num. */ +/* Return first zero offset in num offset array, or num, or -ve error. */ uint64_t tdb_find_zero_off(struct tdb_context *tdb, tdb_off_t off, uint64_t num) { @@ -166,8 +166,7 @@ uint64_t tdb_find_zero_off(struct tdb_context *tdb, tdb_off_t off, /* Zero vs non-zero is the same unconverted: minor optimization. */ val = tdb_access_read(tdb, off, num * sizeof(tdb_off_t), false); if (TDB_PTR_IS_ERR(val)) { - tdb->ecode = TDB_PTR_ERR(val); - return num; + return TDB_PTR_ERR(val); } for (i = 0; i < num; i++) { @@ -213,8 +212,7 @@ tdb_off_t tdb_read_off(struct tdb_context *tdb, tdb_off_t off) tdb_off_t *p = tdb->methods->direct(tdb, off, sizeof(*p), false); if (TDB_PTR_IS_ERR(p)) { - tdb->ecode = TDB_PTR_ERR(p); - return TDB_OFF_ERR; + return TDB_PTR_ERR(p); } if (p) return *p; @@ -222,8 +220,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) { - tdb->ecode = ecode; - return TDB_OFF_ERR; + return ecode; } return ret; } diff --git a/ccan/tdb2/transaction.c b/ccan/tdb2/transaction.c index e7050bfe..d05b1fef 100644 --- a/ccan/tdb2/transaction.c +++ b/ccan/tdb2/transaction.c @@ -642,8 +642,8 @@ static int tdb_recovery_allocate(struct tdb_context *tdb, enum TDB_ERROR ecode; recovery_head = tdb_read_off(tdb, offsetof(struct tdb_header,recovery)); - if (recovery_head == TDB_OFF_ERR) { - tdb_logerr(tdb, tdb->ecode, TDB_LOG_ERROR, + if (TDB_OFF_IS_ERR(recovery_head)) { + tdb_logerr(tdb, recovery_head, TDB_LOG_ERROR, "tdb_recovery_allocate:" " failed to read recovery head"); return -1; @@ -1108,8 +1108,8 @@ int tdb_transaction_recover(struct tdb_context *tdb) /* find the recovery area */ recovery_head = tdb_read_off(tdb, offsetof(struct tdb_header,recovery)); - if (recovery_head == TDB_OFF_ERR) { - tdb_logerr(tdb, tdb->ecode, TDB_LOG_ERROR, + if (TDB_OFF_IS_ERR(recovery_head)) { + tdb_logerr(tdb, recovery_head, TDB_LOG_ERROR, "tdb_transaction_recover:" " failed to read recovery head"); return -1; @@ -1241,7 +1241,8 @@ bool tdb_needs_recovery(struct tdb_context *tdb) /* find the recovery area */ recovery_head = tdb_read_off(tdb, offsetof(struct tdb_header,recovery)); - if (recovery_head == TDB_OFF_ERR) { + if (TDB_OFF_IS_ERR(recovery_head)) { + tdb->ecode = recovery_head; return true; }