Commit 323a9473 authored by Rusty Russell's avatar Rusty Russell

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.
parent 1d4d21df
...@@ -136,8 +136,10 @@ static bool check_hash_chain(struct tdb_context *tdb, ...@@ -136,8 +136,10 @@ static bool check_hash_chain(struct tdb_context *tdb,
return false; return false;
off = tdb_read_off(tdb, off + offsetof(struct tdb_chain, next)); 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; return false;
}
if (off == 0) if (off == 0)
return true; return true;
(*num_found)++; (*num_found)++;
...@@ -512,8 +514,10 @@ static bool check_free_table(struct tdb_context *tdb, ...@@ -512,8 +514,10 @@ static bool check_free_table(struct tdb_context *tdb,
h = bucket_off(ftable_off, i); h = bucket_off(ftable_off, i);
for (off = tdb_read_off(tdb, h); off; off = f.next) { 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; return false;
}
ecode = tdb_read_convert(tdb, off, &f, sizeof(f)); ecode = tdb_read_convert(tdb, off, &f, sizeof(f));
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
tdb->ecode = ecode; tdb->ecode = ecode;
...@@ -725,7 +729,7 @@ int tdb_check(struct tdb_context *tdb, ...@@ -725,7 +729,7 @@ int tdb_check(struct tdb_context *tdb,
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
ecode = tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false); ecode = tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false);
if (ecpde != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
tdb->ecode = ecode; tdb->ecode = ecode;
return -1; return -1;
} }
...@@ -745,8 +749,10 @@ int tdb_check(struct tdb_context *tdb, ...@@ -745,8 +749,10 @@ int tdb_check(struct tdb_context *tdb,
goto fail; goto fail;
for (ft = first_ftable(tdb); ft; ft = next_ftable(tdb, ft)) { 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; goto fail;
}
if (!check_free_table(tdb, ft, num_ftables, fr, num_free, if (!check_free_table(tdb, ft, num_ftables, fr, num_free,
&num_found)) &num_found))
goto fail; goto fail;
......
...@@ -69,8 +69,10 @@ int tdb_ftable_init(struct tdb_context *tdb) ...@@ -69,8 +69,10 @@ int tdb_ftable_init(struct tdb_context *tdb)
tdb->ftable = 0; tdb->ftable = 0;
while (off) { while (off) {
if (off == TDB_OFF_ERR) if (TDB_OFF_IS_ERR(off)) {
tdb->ecode = off;
return -1; return -1;
}
rnd = random(); rnd = random();
if (rnd >= max) { if (rnd >= max) {
...@@ -92,7 +94,7 @@ tdb_off_t bucket_off(tdb_off_t ftable_off, unsigned bucket) ...@@ -92,7 +94,7 @@ tdb_off_t bucket_off(tdb_off_t ftable_off, unsigned bucket)
+ bucket * sizeof(tdb_off_t); + 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, static tdb_off_t find_free_head(struct tdb_context *tdb,
tdb_off_t ftable_off, tdb_off_t ftable_off,
tdb_off_t bucket) tdb_off_t bucket)
...@@ -173,8 +175,10 @@ static int enqueue_in_free(struct tdb_context *tdb, ...@@ -173,8 +175,10 @@ static int enqueue_in_free(struct tdb_context *tdb,
/* new->next = head. */ /* new->next = head. */
new.next = tdb_read_off(tdb, b_off); 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; return -1;
}
if (new.next) { if (new.next) {
#ifdef CCAN_TDB2_DEBUG #ifdef CCAN_TDB2_DEBUG
...@@ -275,8 +279,13 @@ static tdb_off_t ftable_offset(struct tdb_context *tdb, unsigned int ftable) ...@@ -275,8 +279,13 @@ static tdb_off_t ftable_offset(struct tdb_context *tdb, unsigned int ftable)
return tdb->ftable_off; return tdb->ftable_off;
off = first_ftable(tdb); 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); off = next_ftable(tdb, off);
}
return off; return off;
} }
...@@ -436,8 +445,10 @@ again: ...@@ -436,8 +445,10 @@ again:
/* Walk the list to see if any are large enough, getting less fussy /* Walk the list to see if any are large enough, getting less fussy
* as we go. */ * as we go. */
off = tdb_read_off(tdb, b_off); 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; goto unlock_err;
}
while (off) { while (off) {
const struct tdb_free_record *r; const struct tdb_free_record *r;
...@@ -540,7 +551,7 @@ static tdb_off_t get_free(struct tdb_context *tdb, ...@@ -540,7 +551,7 @@ static tdb_off_t get_free(struct tdb_context *tdb,
unsigned magic, unsigned hashlow) unsigned magic, unsigned hashlow)
{ {
tdb_off_t off, ftable_off; tdb_off_t off, ftable_off;
unsigned start_b, b, ftable; tdb_off_t start_b, b, ftable;
bool wrapped = false; bool wrapped = false;
/* If they are growing, add 50% to get to higher bucket. */ /* 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, ...@@ -576,13 +587,26 @@ static tdb_off_t get_free(struct tdb_context *tdb,
/* Didn't work. Try next bucket. */ /* Didn't work. Try next bucket. */
} }
if (TDB_OFF_IS_ERR(b)) {
tdb->ecode = b;
return 0;
}
/* Hmm, try next table. */ /* Hmm, try next table. */
ftable_off = next_ftable(tdb, ftable_off); ftable_off = next_ftable(tdb, ftable_off);
if (TDB_OFF_IS_ERR(ftable_off)) {
tdb->ecode = ftable_off;
return 0;
}
ftable++; ftable++;
if (ftable_off == 0) { if (ftable_off == 0) {
wrapped = true; wrapped = true;
ftable_off = first_ftable(tdb); ftable_off = first_ftable(tdb);
if (TDB_OFF_IS_ERR(ftable_off)) {
tdb->ecode = ftable_off;
return 0;
}
ftable = 0; ftable = 0;
} }
} }
......
...@@ -225,8 +225,10 @@ static tdb_off_t COLD find_in_chain(struct tdb_context *tdb, ...@@ -225,8 +225,10 @@ static tdb_off_t COLD find_in_chain(struct tdb_context *tdb,
} }
next = tdb_read_off(tdb, off next = tdb_read_off(tdb, off
+ offsetof(struct tdb_chain, next)); + offsetof(struct tdb_chain, next));
if (next == TDB_OFF_ERR) if (TDB_OFF_IS_ERR(next)) {
tdb->ecode = next;
return TDB_OFF_ERR; return TDB_OFF_ERR;
}
if (next) if (next)
next += sizeof(struct tdb_used_record); next += sizeof(struct tdb_used_record);
} }
...@@ -430,16 +432,24 @@ static int COLD add_to_chain(struct tdb_context *tdb, ...@@ -430,16 +432,24 @@ static int COLD add_to_chain(struct tdb_context *tdb,
tdb_off_t subhash, tdb_off_t subhash,
tdb_off_t new_off) tdb_off_t new_off)
{ {
size_t entry = tdb_find_zero_off(tdb, subhash, 1<<TDB_HASH_GROUP_BITS); tdb_off_t entry;
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
entry = tdb_find_zero_off(tdb, subhash, 1<<TDB_HASH_GROUP_BITS);
if (TDB_OFF_IS_ERR(entry)) {
tdb->ecode = entry;
return -1;
}
if (entry == 1 << TDB_HASH_GROUP_BITS) { if (entry == 1 << TDB_HASH_GROUP_BITS) {
tdb_off_t next; tdb_off_t next;
next = tdb_read_off(tdb, subhash next = tdb_read_off(tdb, subhash
+ offsetof(struct tdb_chain, next)); + offsetof(struct tdb_chain, next));
if (next == TDB_OFF_ERR) if (TDB_OFF_IS_ERR(next)) {
tdb->ecode = next;
return -1; return -1;
}
if (!next) { if (!next) {
next = alloc(tdb, 0, sizeof(struct tdb_chain), 0, 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) ...@@ -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, static tdb_off_t iterate_hash(struct tdb_context *tdb,
struct traverse_info *tinfo) struct traverse_info *tinfo)
{ {
tdb_off_t off, val; tdb_off_t off, val, i;
unsigned int i;
struct traverse_level *tlevel; struct traverse_level *tlevel;
tlevel = &tinfo->levels[tinfo->num_levels-1]; tlevel = &tinfo->levels[tinfo->num_levels-1];
...@@ -704,9 +713,16 @@ again: ...@@ -704,9 +713,16 @@ again:
i != tlevel->total_buckets; i != tlevel->total_buckets;
i = tdb_find_nonzero_off(tdb, tlevel->hashtable, i = tdb_find_nonzero_off(tdb, tlevel->hashtable,
i+1, tlevel->total_buckets)) { 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); 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; return TDB_OFF_ERR;
}
off = val & TDB_OFF_MASK; off = val & TDB_OFF_MASK;
...@@ -746,8 +762,10 @@ again: ...@@ -746,8 +762,10 @@ again:
tlevel->hashtable = tdb_read_off(tdb, tlevel->hashtable tlevel->hashtable = tdb_read_off(tdb, tlevel->hashtable
+ offsetof(struct tdb_chain, + offsetof(struct tdb_chain,
next)); next));
if (tlevel->hashtable == TDB_OFF_ERR) if (TDB_OFF_IS_ERR(tlevel->hashtable)) {
tdb->ecode = tlevel->hashtable;
return TDB_OFF_ERR; return TDB_OFF_ERR;
}
if (tlevel->hashtable) { if (tlevel->hashtable) {
tlevel->hashtable += sizeof(struct tdb_used_record); tlevel->hashtable += sizeof(struct tdb_used_record);
tlevel->entry = 0; tlevel->entry = 0;
......
...@@ -133,6 +133,7 @@ void *tdb_convert(const struct tdb_context *tdb, void *buf, tdb_len_t size) ...@@ -133,6 +133,7 @@ void *tdb_convert(const struct tdb_context *tdb, void *buf, tdb_len_t size)
return buf; return buf;
} }
/* Return first non-zero offset in offset array, or end, or -ve error. */
/* FIXME: Return the off? */ /* FIXME: Return the off? */
uint64_t tdb_find_nonzero_off(struct tdb_context *tdb, uint64_t tdb_find_nonzero_off(struct tdb_context *tdb,
tdb_off_t base, uint64_t start, uint64_t end) tdb_off_t base, uint64_t start, uint64_t end)
...@@ -144,8 +145,7 @@ uint64_t tdb_find_nonzero_off(struct tdb_context *tdb, ...@@ -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), val = tdb_access_read(tdb, base + start * sizeof(tdb_off_t),
(end - start) * sizeof(tdb_off_t), false); (end - start) * sizeof(tdb_off_t), false);
if (TDB_PTR_IS_ERR(val)) { if (TDB_PTR_IS_ERR(val)) {
tdb->ecode = TDB_PTR_ERR(val); return TDB_PTR_ERR(val);
return end;
} }
for (i = 0; i < (end - start); i++) { for (i = 0; i < (end - start); i++) {
...@@ -156,7 +156,7 @@ uint64_t tdb_find_nonzero_off(struct tdb_context *tdb, ...@@ -156,7 +156,7 @@ uint64_t tdb_find_nonzero_off(struct tdb_context *tdb,
return start + i; 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 tdb_find_zero_off(struct tdb_context *tdb, tdb_off_t off,
uint64_t num) uint64_t num)
{ {
...@@ -166,8 +166,7 @@ uint64_t tdb_find_zero_off(struct tdb_context *tdb, tdb_off_t off, ...@@ -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. */ /* Zero vs non-zero is the same unconverted: minor optimization. */
val = tdb_access_read(tdb, off, num * sizeof(tdb_off_t), false); val = tdb_access_read(tdb, off, num * sizeof(tdb_off_t), false);
if (TDB_PTR_IS_ERR(val)) { if (TDB_PTR_IS_ERR(val)) {
tdb->ecode = TDB_PTR_ERR(val); return TDB_PTR_ERR(val);
return num;
} }
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
...@@ -213,8 +212,7 @@ tdb_off_t tdb_read_off(struct tdb_context *tdb, tdb_off_t off) ...@@ -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), tdb_off_t *p = tdb->methods->direct(tdb, off, sizeof(*p),
false); false);
if (TDB_PTR_IS_ERR(p)) { if (TDB_PTR_IS_ERR(p)) {
tdb->ecode = TDB_PTR_ERR(p); return TDB_PTR_ERR(p);
return TDB_OFF_ERR;
} }
if (p) if (p)
return *p; return *p;
...@@ -222,8 +220,7 @@ tdb_off_t tdb_read_off(struct tdb_context *tdb, tdb_off_t off) ...@@ -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)); ecode = tdb_read_convert(tdb, off, &ret, sizeof(ret));
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
tdb->ecode = ecode; return ecode;
return TDB_OFF_ERR;
} }
return ret; return ret;
} }
......
...@@ -642,8 +642,8 @@ static int tdb_recovery_allocate(struct tdb_context *tdb, ...@@ -642,8 +642,8 @@ static int tdb_recovery_allocate(struct tdb_context *tdb,
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
recovery_head = tdb_read_off(tdb, offsetof(struct tdb_header,recovery)); 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_logerr(tdb, tdb->ecode, TDB_LOG_ERROR, tdb_logerr(tdb, recovery_head, TDB_LOG_ERROR,
"tdb_recovery_allocate:" "tdb_recovery_allocate:"
" failed to read recovery head"); " failed to read recovery head");
return -1; return -1;
...@@ -1108,8 +1108,8 @@ int tdb_transaction_recover(struct tdb_context *tdb) ...@@ -1108,8 +1108,8 @@ int tdb_transaction_recover(struct tdb_context *tdb)
/* find the recovery area */ /* find the recovery area */
recovery_head = tdb_read_off(tdb, offsetof(struct tdb_header,recovery)); 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_logerr(tdb, tdb->ecode, TDB_LOG_ERROR, tdb_logerr(tdb, recovery_head, TDB_LOG_ERROR,
"tdb_transaction_recover:" "tdb_transaction_recover:"
" failed to read recovery head"); " failed to read recovery head");
return -1; return -1;
...@@ -1241,7 +1241,8 @@ bool tdb_needs_recovery(struct tdb_context *tdb) ...@@ -1241,7 +1241,8 @@ bool tdb_needs_recovery(struct tdb_context *tdb)
/* find the recovery area */ /* find the recovery area */
recovery_head = tdb_read_off(tdb, offsetof(struct tdb_header,recovery)); 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; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment