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)++;
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;
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;
}
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;
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) {
+ 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)
/* 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
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;
}
/* 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;
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. */
/* 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;
}
}
}
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);
}
tdb_off_t subhash,
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;
+ 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) {
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,
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];
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;
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;
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)
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++) {
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)
{
/* 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++) {
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;
ecode = tdb_read_convert(tdb, off, &ret, sizeof(ret));
if (ecode != TDB_SUCCESS) {
- tdb->ecode = ecode;
- return TDB_OFF_ERR;
+ return ecode;
}
return ret;
}
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;
/* 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;
/* 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;
}