Commit bbeb528e authored by Rusty Russell's avatar Rusty Russell

tdb2: merge tdb1_context into tdb_context.

Finally, we split out the tdb2-specific parts of tdb_context, and put
them into a "tdb2" sub-struct; the tdb1 parts go into a "tdb1"
sub-struct.  We get rido of tdb1_context and use tdb_context
everywhere.
parent 4dc29a33
...@@ -478,7 +478,7 @@ static enum TDB_ERROR check_free(struct tdb_context *tdb, ...@@ -478,7 +478,7 @@ static enum TDB_ERROR check_free(struct tdb_context *tdb,
} }
ecode = tdb->methods->oob(tdb, off ecode = tdb->tdb2.io->oob(tdb, off
+ frec_len(frec) + frec_len(frec)
+ sizeof(struct tdb_used_record), + sizeof(struct tdb_used_record),
false); false);
...@@ -587,7 +587,7 @@ tdb_off_t dead_space(struct tdb_context *tdb, tdb_off_t off) ...@@ -587,7 +587,7 @@ tdb_off_t dead_space(struct tdb_context *tdb, tdb_off_t off)
for (len = 0; off + len < tdb->file->map_size; len++) { for (len = 0; off + len < tdb->file->map_size; len++) {
char c; char c;
ecode = tdb->methods->tread(tdb, off, &c, 1); ecode = tdb->tdb2.io->tread(tdb, off, &c, 1);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
return ecode; return ecode;
} }
......
...@@ -65,8 +65,8 @@ enum TDB_ERROR tdb_ftable_init(struct tdb_context *tdb) ...@@ -65,8 +65,8 @@ enum TDB_ERROR tdb_ftable_init(struct tdb_context *tdb)
unsigned int rnd, max = 0, count = 0; unsigned int rnd, max = 0, count = 0;
tdb_off_t off; tdb_off_t off;
tdb->ftable_off = off = first_ftable(tdb); tdb->tdb2.ftable_off = off = first_ftable(tdb);
tdb->ftable = 0; tdb->tdb2.ftable = 0;
while (off) { while (off) {
if (TDB_OFF_IS_ERR(off)) { if (TDB_OFF_IS_ERR(off)) {
...@@ -75,8 +75,8 @@ enum TDB_ERROR tdb_ftable_init(struct tdb_context *tdb) ...@@ -75,8 +75,8 @@ enum TDB_ERROR tdb_ftable_init(struct tdb_context *tdb)
rnd = random(); rnd = random();
if (rnd >= max) { if (rnd >= max) {
tdb->ftable_off = off; tdb->tdb2.ftable_off = off;
tdb->ftable = count; tdb->tdb2.ftable = count;
max = rnd; max = rnd;
} }
...@@ -218,7 +218,7 @@ static enum TDB_ERROR enqueue_in_free(struct tdb_context *tdb, ...@@ -218,7 +218,7 @@ static enum TDB_ERROR enqueue_in_free(struct tdb_context *tdb,
return head; return head;
/* We only need to set ftable_and_len; rest is set in enqueue_in_free */ /* We only need to set ftable_and_len; rest is set in enqueue_in_free */
new.ftable_and_len = ((uint64_t)tdb->ftable << (64 - TDB_OFF_UPPER_STEAL)) new.ftable_and_len = ((uint64_t)tdb->tdb2.ftable << (64 - TDB_OFF_UPPER_STEAL))
| len; | len;
/* new->next = head. */ /* new->next = head. */
...@@ -287,8 +287,8 @@ static tdb_off_t ftable_offset(struct tdb_context *tdb, unsigned int ftable) ...@@ -287,8 +287,8 @@ static tdb_off_t ftable_offset(struct tdb_context *tdb, unsigned int ftable)
tdb_off_t off; tdb_off_t off;
unsigned int i; unsigned int i;
if (likely(tdb->ftable == ftable)) if (likely(tdb->tdb2.ftable == ftable))
return tdb->ftable_off; return tdb->tdb2.ftable_off;
off = first_ftable(tdb); off = first_ftable(tdb);
for (i = 0; i < ftable; i++) { for (i = 0; i < ftable; i++) {
...@@ -595,7 +595,7 @@ enum TDB_ERROR add_free_record(struct tdb_context *tdb, ...@@ -595,7 +595,7 @@ enum TDB_ERROR add_free_record(struct tdb_context *tdb,
len = len_with_header - sizeof(struct tdb_used_record); len = len_with_header - sizeof(struct tdb_used_record);
b_off = bucket_off(tdb->ftable_off, size_to_bucket(len)); b_off = bucket_off(tdb->tdb2.ftable_off, size_to_bucket(len));
ecode = tdb_lock_free_bucket(tdb, b_off, waitflag); ecode = tdb_lock_free_bucket(tdb, b_off, waitflag);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
return ecode; return ecode;
...@@ -606,7 +606,7 @@ enum TDB_ERROR add_free_record(struct tdb_context *tdb, ...@@ -606,7 +606,7 @@ enum TDB_ERROR add_free_record(struct tdb_context *tdb,
/* Coalescing unlocks free list. */ /* Coalescing unlocks free list. */
if (!ecode && coalesce) if (!ecode && coalesce)
ecode = coalesce_list(tdb, tdb->ftable_off, b_off, 2); ecode = coalesce_list(tdb, tdb->tdb2.ftable_off, b_off, 2);
else else
tdb_unlock_free_bucket(tdb, b_off); tdb_unlock_free_bucket(tdb, b_off);
return ecode; return ecode;
...@@ -752,7 +752,7 @@ static tdb_off_t lock_and_alloc(struct tdb_context *tdb, ...@@ -752,7 +752,7 @@ static tdb_off_t lock_and_alloc(struct tdb_context *tdb,
/* For futureproofing, we put a 0 in any unused space. */ /* For futureproofing, we put a 0 in any unused space. */
if (rec_extra_padding(&rec)) { if (rec_extra_padding(&rec)) {
ecode = tdb->methods->twrite(tdb, best_off + sizeof(rec) ecode = tdb->tdb2.io->twrite(tdb, best_off + sizeof(rec)
+ keylen + datalen, "", 1); + keylen + datalen, "", 1);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
goto unlock_err; goto unlock_err;
...@@ -800,9 +800,9 @@ static tdb_off_t get_free(struct tdb_context *tdb, ...@@ -800,9 +800,9 @@ static tdb_off_t get_free(struct tdb_context *tdb,
else else
start_b = size_to_bucket(adjust_size(keylen, datalen)); start_b = size_to_bucket(adjust_size(keylen, datalen));
ftable_off = tdb->ftable_off; ftable_off = tdb->tdb2.ftable_off;
ftable = tdb->ftable; ftable = tdb->tdb2.ftable;
while (!wrapped || ftable_off != tdb->ftable_off) { while (!wrapped || ftable_off != tdb->tdb2.ftable_off) {
/* Start at exact size bucket, and search up... */ /* Start at exact size bucket, and search up... */
for (b = find_free_head(tdb, ftable_off, start_b); for (b = find_free_head(tdb, ftable_off, start_b);
b < TDB_FREE_BUCKETS; b < TDB_FREE_BUCKETS;
...@@ -819,8 +819,8 @@ static tdb_off_t get_free(struct tdb_context *tdb, ...@@ -819,8 +819,8 @@ static tdb_off_t get_free(struct tdb_context *tdb,
if (b == TDB_FREE_BUCKETS - 1) if (b == TDB_FREE_BUCKETS - 1)
tdb->stats.alloc_bucket_max++; tdb->stats.alloc_bucket_max++;
/* Worked? Stay using this list. */ /* Worked? Stay using this list. */
tdb->ftable_off = ftable_off; tdb->tdb2.ftable_off = ftable_off;
tdb->ftable = ftable; tdb->tdb2.ftable = ftable;
return off; return off;
} }
/* Didn't work. Try next bucket. */ /* Didn't work. Try next bucket. */
...@@ -898,7 +898,7 @@ static enum TDB_ERROR tdb_expand(struct tdb_context *tdb, tdb_len_t size) ...@@ -898,7 +898,7 @@ static enum TDB_ERROR tdb_expand(struct tdb_context *tdb, tdb_len_t size)
/* Someone else may have expanded the file, so retry. */ /* Someone else may have expanded the file, so retry. */
old_size = tdb->file->map_size; old_size = tdb->file->map_size;
tdb->methods->oob(tdb, tdb->file->map_size + 1, true); tdb->tdb2.io->oob(tdb, tdb->file->map_size + 1, true);
if (tdb->file->map_size != old_size) { if (tdb->file->map_size != old_size) {
tdb_unlock_expand(tdb, F_WRLCK); tdb_unlock_expand(tdb, F_WRLCK);
return TDB_SUCCESS; return TDB_SUCCESS;
...@@ -930,7 +930,7 @@ static enum TDB_ERROR tdb_expand(struct tdb_context *tdb, tdb_len_t size) ...@@ -930,7 +930,7 @@ static enum TDB_ERROR tdb_expand(struct tdb_context *tdb, tdb_len_t size)
/* We need room for the record header too. */ /* We need room for the record header too. */
wanted = adjust_size(0, sizeof(struct tdb_used_record) + wanted); wanted = adjust_size(0, sizeof(struct tdb_used_record) + wanted);
ecode = tdb->methods->expand_file(tdb, wanted); ecode = tdb->tdb2.io->expand_file(tdb, wanted);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
tdb_unlock_expand(tdb, F_WRLCK); tdb_unlock_expand(tdb, F_WRLCK);
return ecode; return ecode;
...@@ -950,7 +950,7 @@ tdb_off_t alloc(struct tdb_context *tdb, size_t keylen, size_t datalen, ...@@ -950,7 +950,7 @@ tdb_off_t alloc(struct tdb_context *tdb, size_t keylen, size_t datalen,
tdb_off_t off; tdb_off_t off;
/* We can't hold pointers during this: we could unmap! */ /* We can't hold pointers during this: we could unmap! */
assert(!tdb->direct_access); assert(!tdb->tdb2.direct_access);
for (;;) { for (;;) {
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
......
...@@ -88,7 +88,7 @@ static enum TDB_ERROR tdb_oob(struct tdb_context *tdb, tdb_off_t len, ...@@ -88,7 +88,7 @@ static enum TDB_ERROR tdb_oob(struct tdb_context *tdb, tdb_off_t len,
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
/* We can't hold pointers during this: we could unmap! */ /* We can't hold pointers during this: we could unmap! */
assert(!tdb->direct_access assert(!tdb->tdb2.direct_access
|| (tdb->flags & TDB_NOLOCK) || (tdb->flags & TDB_NOLOCK)
|| tdb_has_expansion_lock(tdb)); || tdb_has_expansion_lock(tdb));
...@@ -197,7 +197,7 @@ uint64_t tdb_find_zero_off(struct tdb_context *tdb, tdb_off_t off, ...@@ -197,7 +197,7 @@ uint64_t tdb_find_zero_off(struct tdb_context *tdb, tdb_off_t off,
enum TDB_ERROR zero_out(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len) enum TDB_ERROR zero_out(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len)
{ {
char buf[8192] = { 0 }; char buf[8192] = { 0 };
void *p = tdb->methods->direct(tdb, off, len, true); void *p = tdb->tdb2.io->direct(tdb, off, len, true);
enum TDB_ERROR ecode = TDB_SUCCESS; enum TDB_ERROR ecode = TDB_SUCCESS;
assert(!(tdb->flags & TDB_RDONLY)); assert(!(tdb->flags & TDB_RDONLY));
...@@ -210,7 +210,7 @@ enum TDB_ERROR zero_out(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len) ...@@ -210,7 +210,7 @@ enum TDB_ERROR zero_out(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len)
} }
while (len) { while (len) {
unsigned todo = len < sizeof(buf) ? len : sizeof(buf); unsigned todo = len < sizeof(buf) ? len : sizeof(buf);
ecode = tdb->methods->twrite(tdb, off, buf, todo); ecode = tdb->tdb2.io->twrite(tdb, off, buf, todo);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
break; break;
} }
...@@ -226,7 +226,7 @@ tdb_off_t tdb_read_off(struct tdb_context *tdb, tdb_off_t off) ...@@ -226,7 +226,7 @@ tdb_off_t tdb_read_off(struct tdb_context *tdb, tdb_off_t off)
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
if (likely(!(tdb->flags & TDB_CONVERT))) { if (likely(!(tdb->flags & TDB_CONVERT))) {
tdb_off_t *p = tdb->methods->direct(tdb, off, sizeof(*p), tdb_off_t *p = tdb->tdb2.io->direct(tdb, off, sizeof(*p),
false); false);
if (TDB_PTR_IS_ERR(p)) { if (TDB_PTR_IS_ERR(p)) {
return TDB_PTR_ERR(p); return TDB_PTR_ERR(p);
...@@ -253,7 +253,7 @@ static enum TDB_ERROR tdb_write(struct tdb_context *tdb, tdb_off_t off, ...@@ -253,7 +253,7 @@ static enum TDB_ERROR tdb_write(struct tdb_context *tdb, tdb_off_t off,
"Write to read-only database"); "Write to read-only database");
} }
ecode = tdb->methods->oob(tdb, off + len, false); ecode = tdb->tdb2.io->oob(tdb, off + len, false);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
return ecode; return ecode;
} }
...@@ -283,7 +283,7 @@ static enum TDB_ERROR tdb_read(struct tdb_context *tdb, tdb_off_t off, ...@@ -283,7 +283,7 @@ static enum TDB_ERROR tdb_read(struct tdb_context *tdb, tdb_off_t off,
{ {
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
ecode = tdb->methods->oob(tdb, off + len, false); ecode = tdb->tdb2.io->oob(tdb, off + len, false);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
return ecode; return ecode;
} }
...@@ -317,11 +317,11 @@ enum TDB_ERROR tdb_write_convert(struct tdb_context *tdb, tdb_off_t off, ...@@ -317,11 +317,11 @@ enum TDB_ERROR tdb_write_convert(struct tdb_context *tdb, tdb_off_t off,
" %zu bytes", len); " %zu bytes", len);
} }
memcpy(conv, rec, len); memcpy(conv, rec, len);
ecode = tdb->methods->twrite(tdb, off, ecode = tdb->tdb2.io->twrite(tdb, off,
tdb_convert(tdb, conv, len), len); tdb_convert(tdb, conv, len), len);
free(conv); free(conv);
} else { } else {
ecode = tdb->methods->twrite(tdb, off, rec, len); ecode = tdb->tdb2.io->twrite(tdb, off, rec, len);
} }
return ecode; return ecode;
} }
...@@ -329,7 +329,7 @@ enum TDB_ERROR tdb_write_convert(struct tdb_context *tdb, tdb_off_t off, ...@@ -329,7 +329,7 @@ enum TDB_ERROR tdb_write_convert(struct tdb_context *tdb, tdb_off_t off,
enum TDB_ERROR tdb_read_convert(struct tdb_context *tdb, tdb_off_t off, enum TDB_ERROR tdb_read_convert(struct tdb_context *tdb, tdb_off_t off,
void *rec, size_t len) void *rec, size_t len)
{ {
enum TDB_ERROR ecode = tdb->methods->tread(tdb, off, rec, len); enum TDB_ERROR ecode = tdb->tdb2.io->tread(tdb, off, rec, len);
tdb_convert(tdb, rec, len); tdb_convert(tdb, rec, len);
return ecode; return ecode;
} }
...@@ -343,7 +343,7 @@ enum TDB_ERROR tdb_write_off(struct tdb_context *tdb, ...@@ -343,7 +343,7 @@ enum TDB_ERROR tdb_write_off(struct tdb_context *tdb,
} }
if (likely(!(tdb->flags & TDB_CONVERT))) { if (likely(!(tdb->flags & TDB_CONVERT))) {
tdb_off_t *p = tdb->methods->direct(tdb, off, sizeof(*p), tdb_off_t *p = tdb->tdb2.io->direct(tdb, off, sizeof(*p),
true); true);
if (TDB_PTR_IS_ERR(p)) { if (TDB_PTR_IS_ERR(p)) {
return TDB_PTR_ERR(p); return TDB_PTR_ERR(p);
...@@ -370,7 +370,7 @@ static void *_tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, ...@@ -370,7 +370,7 @@ static void *_tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset,
(size_t)(prefix + len)); (size_t)(prefix + len));
return TDB_ERR_PTR(TDB_ERR_OOM); return TDB_ERR_PTR(TDB_ERR_OOM);
} else { } else {
ecode = tdb->methods->tread(tdb, offset, buf+prefix, len); ecode = tdb->tdb2.io->tread(tdb, offset, buf+prefix, len);
if (unlikely(ecode != TDB_SUCCESS)) { if (unlikely(ecode != TDB_SUCCESS)) {
free(buf); free(buf);
return TDB_ERR_PTR(ecode); return TDB_ERR_PTR(ecode);
...@@ -459,7 +459,7 @@ const void *tdb_access_read(struct tdb_context *tdb, ...@@ -459,7 +459,7 @@ const void *tdb_access_read(struct tdb_context *tdb,
void *ret = NULL; void *ret = NULL;
if (likely(!(tdb->flags & TDB_CONVERT))) { if (likely(!(tdb->flags & TDB_CONVERT))) {
ret = tdb->methods->direct(tdb, off, len, false); ret = tdb->tdb2.io->direct(tdb, off, len, false);
if (TDB_PTR_IS_ERR(ret)) { if (TDB_PTR_IS_ERR(ret)) {
return ret; return ret;
...@@ -471,14 +471,14 @@ const void *tdb_access_read(struct tdb_context *tdb, ...@@ -471,14 +471,14 @@ const void *tdb_access_read(struct tdb_context *tdb,
if (TDB_PTR_IS_ERR(hdr)) { if (TDB_PTR_IS_ERR(hdr)) {
return hdr; return hdr;
} }
hdr->next = tdb->access; hdr->next = tdb->tdb2.access;
tdb->access = hdr; tdb->tdb2.access = hdr;
ret = hdr + 1; ret = hdr + 1;
if (convert) { if (convert) {
tdb_convert(tdb, (void *)ret, len); tdb_convert(tdb, (void *)ret, len);
} }
} else } else
tdb->direct_access++; tdb->tdb2.direct_access++;
return ret; return ret;
} }
...@@ -495,7 +495,7 @@ void *tdb_access_write(struct tdb_context *tdb, ...@@ -495,7 +495,7 @@ void *tdb_access_write(struct tdb_context *tdb,
} }
if (likely(!(tdb->flags & TDB_CONVERT))) { if (likely(!(tdb->flags & TDB_CONVERT))) {
ret = tdb->methods->direct(tdb, off, len, true); ret = tdb->tdb2.io->direct(tdb, off, len, true);
if (TDB_PTR_IS_ERR(ret)) { if (TDB_PTR_IS_ERR(ret)) {
return ret; return ret;
...@@ -508,8 +508,8 @@ void *tdb_access_write(struct tdb_context *tdb, ...@@ -508,8 +508,8 @@ void *tdb_access_write(struct tdb_context *tdb,
if (TDB_PTR_IS_ERR(hdr)) { if (TDB_PTR_IS_ERR(hdr)) {
return hdr; return hdr;
} }
hdr->next = tdb->access; hdr->next = tdb->tdb2.access;
tdb->access = hdr; tdb->tdb2.access = hdr;
hdr->off = off; hdr->off = off;
hdr->len = len; hdr->len = len;
hdr->convert = convert; hdr->convert = convert;
...@@ -517,7 +517,7 @@ void *tdb_access_write(struct tdb_context *tdb, ...@@ -517,7 +517,7 @@ void *tdb_access_write(struct tdb_context *tdb,
if (convert) if (convert)
tdb_convert(tdb, (void *)ret, len); tdb_convert(tdb, (void *)ret, len);
} else } else
tdb->direct_access++; tdb->tdb2.direct_access++;
return ret; return ret;
} }
...@@ -526,7 +526,7 @@ static struct tdb_access_hdr **find_hdr(struct tdb_context *tdb, const void *p) ...@@ -526,7 +526,7 @@ static struct tdb_access_hdr **find_hdr(struct tdb_context *tdb, const void *p)
{ {
struct tdb_access_hdr **hp; struct tdb_access_hdr **hp;
for (hp = &tdb->access; *hp; hp = &(*hp)->next) { for (hp = &tdb->tdb2.access; *hp; hp = &(*hp)->next) {
if (*hp + 1 == p) if (*hp + 1 == p)
return hp; return hp;
} }
...@@ -542,7 +542,7 @@ void tdb_access_release(struct tdb_context *tdb, const void *p) ...@@ -542,7 +542,7 @@ void tdb_access_release(struct tdb_context *tdb, const void *p)
*hp = hdr->next; *hp = hdr->next;
free(hdr); free(hdr);
} else } else
tdb->direct_access--; tdb->tdb2.direct_access--;
} }
enum TDB_ERROR tdb_access_commit(struct tdb_context *tdb, void *p) enum TDB_ERROR tdb_access_commit(struct tdb_context *tdb, void *p)
...@@ -559,7 +559,7 @@ enum TDB_ERROR tdb_access_commit(struct tdb_context *tdb, void *p) ...@@ -559,7 +559,7 @@ enum TDB_ERROR tdb_access_commit(struct tdb_context *tdb, void *p)
*hp = hdr->next; *hp = hdr->next;
free(hdr); free(hdr);
} else { } else {
tdb->direct_access--; tdb->tdb2.direct_access--;
ecode = TDB_SUCCESS; ecode = TDB_SUCCESS;
} }
...@@ -587,7 +587,7 @@ void tdb_inc_seqnum(struct tdb_context *tdb) ...@@ -587,7 +587,7 @@ void tdb_inc_seqnum(struct tdb_context *tdb)
if (likely(!(tdb->flags & TDB_CONVERT))) { if (likely(!(tdb->flags & TDB_CONVERT))) {
int64_t *direct; int64_t *direct;
direct = tdb->methods->direct(tdb, direct = tdb->tdb2.io->direct(tdb,
offsetof(struct tdb_header, offsetof(struct tdb_header,
seqnum), seqnum),
sizeof(*direct), true); sizeof(*direct), true);
...@@ -622,5 +622,5 @@ static const struct tdb_methods io_methods = { ...@@ -622,5 +622,5 @@ static const struct tdb_methods io_methods = {
*/ */
void tdb_io_init(struct tdb_context *tdb) void tdb_io_init(struct tdb_context *tdb)
{ {
tdb->methods = &io_methods; tdb->tdb2.io = &io_methods;
} }
...@@ -363,11 +363,8 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, ...@@ -363,11 +363,8 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
} else { } else {
tdb->name = NULL; tdb->name = NULL;
} }
tdb->direct_access = 0;
tdb->flags = tdb_flags; tdb->flags = tdb_flags;
tdb->log_fn = NULL; tdb->log_fn = NULL;
tdb->transaction = NULL;
tdb->access = NULL;
tdb->open_flags = open_flags; tdb->open_flags = open_flags;
tdb->last_error = TDB_SUCCESS; tdb->last_error = TDB_SUCCESS;
tdb->file = NULL; tdb->file = NULL;
...@@ -379,6 +376,9 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, ...@@ -379,6 +376,9 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
tdb->stats.base.attr = TDB_ATTRIBUTE_STATS; tdb->stats.base.attr = TDB_ATTRIBUTE_STATS;
tdb->stats.size = sizeof(tdb->stats); tdb->stats.size = sizeof(tdb->stats);
tdb_io_init(tdb); tdb_io_init(tdb);
tdb->tdb2.direct_access = 0;
tdb->tdb2.transaction = NULL;
tdb->tdb2.access = NULL;
while (attr) { while (attr) {
switch (attr->base.attr) { switch (attr->base.attr) {
...@@ -573,7 +573,7 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags, ...@@ -573,7 +573,7 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
tdb_unlock_open(tdb, openlock); tdb_unlock_open(tdb, openlock);
/* This make sure we have current map_size and mmap. */ /* This make sure we have current map_size and mmap. */
ecode = tdb->methods->oob(tdb, tdb->file->map_size + 1, true); ecode = tdb->tdb2.io->oob(tdb, tdb->file->map_size + 1, true);
if (unlikely(ecode != TDB_SUCCESS)) if (unlikely(ecode != TDB_SUCCESS))
goto fail; goto fail;
...@@ -655,7 +655,7 @@ int tdb_close(struct tdb_context *tdb) ...@@ -655,7 +655,7 @@ int tdb_close(struct tdb_context *tdb)
tdb_trace(tdb, "tdb_close"); tdb_trace(tdb, "tdb_close");
if (tdb->transaction) { if (tdb->tdb2.transaction) {
tdb_transaction_cancel(tdb); tdb_transaction_cancel(tdb);
} }
......
...@@ -271,6 +271,9 @@ struct traverse_info { ...@@ -271,6 +271,9 @@ struct traverse_info {
tdb_off_t prev; tdb_off_t prev;
}; };
typedef uint32_t tdb1_len_t;
typedef uint32_t tdb1_off_t;
enum tdb_lock_flags { enum tdb_lock_flags {
/* WAIT == F_SETLKW, NOWAIT == F_SETLK */ /* WAIT == F_SETLKW, NOWAIT == F_SETLK */
TDB_LOCK_NOWAIT = 0, TDB_LOCK_NOWAIT = 0,
...@@ -321,68 +324,6 @@ struct tdb_file { ...@@ -321,68 +324,6 @@ struct tdb_file {
ino_t inode; ino_t inode;
}; };
struct tdb_context {
/* Single list of all TDBs, to detect multiple opens. */
struct tdb_context *next;
/* Filename of the database. */
const char *name;
/* Logging function */
void (*log_fn)(struct tdb_context *tdb,
enum tdb_log_level level,
enum TDB_ERROR ecode,
const char *message,
void *data);
void *log_data;
/* Last error we returned. */
enum TDB_ERROR last_error;
/* The actual file information */
struct tdb_file *file;
/* Open flags passed to tdb_open. */
int open_flags;
/* low level (fnctl) lock functions. */
int (*lock_fn)(int fd, int rw, off_t off, off_t len, bool w, void *);
int (*unlock_fn)(int fd, int rw, off_t off, off_t len, void *);
void *lock_data;
/* the flags passed to tdb_open. */
uint32_t flags;
/* Our statistics. */
struct tdb_attribute_stats stats;
/* Hash function. */
uint64_t (*hash_fn)(const void *key, size_t len, uint64_t seed, void *);
void *hash_data;
uint64_t hash_seed;
/* Are we accessing directly? (debugging check). */
int direct_access;
/* Set if we are in a transaction. */
struct tdb_transaction *transaction;
/* What free table are we using? */
tdb_off_t ftable_off;
unsigned int ftable;
/* Our open hook, if any. */
enum TDB_ERROR (*openhook)(int fd, void *data);
void *openhook_data;
/* IO methods: changes for transactions. */
const struct tdb_methods *methods;
/* Direct access information */
struct tdb_access_hdr *access;
};
struct tdb_methods { struct tdb_methods {
enum TDB_ERROR (*tread)(struct tdb_context *, tdb_off_t, void *, enum TDB_ERROR (*tread)(struct tdb_context *, tdb_off_t, void *,
tdb_len_t); tdb_len_t);
...@@ -588,6 +529,102 @@ int tdb_fcntl_unlock(int fd, int rw, off_t off, off_t len, void *); ...@@ -588,6 +529,102 @@ int tdb_fcntl_unlock(int fd, int rw, off_t off, off_t len, void *);
enum TDB_ERROR tdb_transaction_recover(struct tdb_context *tdb); enum TDB_ERROR tdb_transaction_recover(struct tdb_context *tdb);
tdb_bool_err tdb_needs_recovery(struct tdb_context *tdb); tdb_bool_err tdb_needs_recovery(struct tdb_context *tdb);
/* this is stored at the front of every database */
struct tdb1_header {
char magic_food[32]; /* for /etc/magic */
uint32_t version; /* version of the code */
uint32_t hash_size; /* number of hash entries */
tdb1_off_t rwlocks; /* obsolete - kept to detect old formats */
tdb1_off_t recovery_start; /* offset of transaction recovery region */
tdb1_off_t sequence_number; /* used when TDB1_SEQNUM is set */
uint32_t magic1_hash; /* hash of TDB_MAGIC_FOOD. */
uint32_t magic2_hash; /* hash of TDB1_MAGIC. */
tdb1_off_t reserved[27];
};
struct tdb1_traverse_lock {
struct tdb1_traverse_lock *next;
uint32_t off;
uint32_t hash;
int lock_rw;
};
struct tdb_context {
/* Single list of all TDBs, to detect multiple opens. */
struct tdb_context *next;
/* Filename of the database. */
const char *name;
/* Logging function */
void (*log_fn)(struct tdb_context *tdb,
enum tdb_log_level level,
enum TDB_ERROR ecode,
const char *message,
void *data);
void *log_data;
/* Open flags passed to tdb_open. */
int open_flags;
/* low level (fnctl) lock functions. */
int (*lock_fn)(int fd, int rw, off_t off, off_t len, bool w, void *);
int (*unlock_fn)(int fd, int rw, off_t off, off_t len, void *);
void *lock_data;
/* the tdb flags passed to tdb_open. */
uint32_t flags;
/* Our statistics. */
struct tdb_attribute_stats stats;
/* The actual file information */
struct tdb_file *file;
/* Hash function. */
uint64_t (*hash_fn)(const void *key, size_t len, uint64_t seed, void *);
void *hash_data;
uint64_t hash_seed;
/* Our open hook, if any. */
enum TDB_ERROR (*openhook)(int fd, void *data);
void *openhook_data;
/* Last error we returned. */
enum TDB_ERROR last_error;
struct {
/* Are we accessing directly? (debugging check). */
int direct_access;
/* Set if we are in a transaction. */
struct tdb_transaction *transaction;
/* What free table are we using? */
tdb_off_t ftable_off;
unsigned int ftable;
/* IO methods: changes for transactions. */
const struct tdb_methods *io;
/* Direct access information */
struct tdb_access_hdr *access;
} tdb2;
struct {
int traverse_read; /* read-only traversal */
int traverse_write; /* read-write traversal */
struct tdb1_header header; /* a cached copy of the header */
struct tdb1_traverse_lock travlocks; /* current traversal locks */
const struct tdb1_methods *io;
struct tdb1_transaction *transaction;
int page_size;
int max_dead_records;
} tdb1;
};
/* tdb.c: */ /* tdb.c: */
enum TDB_ERROR COLD tdb_logerr(struct tdb_context *tdb, enum TDB_ERROR COLD tdb_logerr(struct tdb_context *tdb,
enum TDB_ERROR ecode, enum TDB_ERROR ecode,
......
...@@ -70,13 +70,13 @@ static enum TDB_ERROR replace_data(struct tdb_context *tdb, ...@@ -70,13 +70,13 @@ static enum TDB_ERROR replace_data(struct tdb_context *tdb,
} }
new_off += sizeof(struct tdb_used_record); new_off += sizeof(struct tdb_used_record);
ecode = tdb->methods->twrite(tdb, new_off, key.dptr, key.dsize); ecode = tdb->tdb2.io->twrite(tdb, new_off, key.dptr, key.dsize);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
return ecode; return ecode;
} }
new_off += key.dsize; new_off += key.dsize;
ecode = tdb->methods->twrite(tdb, new_off, dbuf.dptr, dbuf.dsize); ecode = tdb->tdb2.io->twrite(tdb, new_off, dbuf.dptr, dbuf.dsize);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
return ecode; return ecode;
} }
...@@ -94,10 +94,10 @@ static enum TDB_ERROR update_data(struct tdb_context *tdb, ...@@ -94,10 +94,10 @@ static enum TDB_ERROR update_data(struct tdb_context *tdb,
{ {
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
ecode = tdb->methods->twrite(tdb, off, dbuf.dptr, dbuf.dsize); ecode = tdb->tdb2.io->twrite(tdb, off, dbuf.dptr, dbuf.dsize);
if (ecode == TDB_SUCCESS && extra) { if (ecode == TDB_SUCCESS && extra) {
/* Put a zero in; future versions may append other data. */ /* Put a zero in; future versions may append other data. */
ecode = tdb->methods->twrite(tdb, off + dbuf.dsize, "", 1); ecode = tdb->tdb2.io->twrite(tdb, off + dbuf.dsize, "", 1);
} }
if (tdb->flags & TDB_SEQNUM) if (tdb->flags & TDB_SEQNUM)
tdb_inc_seqnum(tdb); tdb_inc_seqnum(tdb);
...@@ -211,7 +211,7 @@ enum TDB_ERROR tdb_append(struct tdb_context *tdb, ...@@ -211,7 +211,7 @@ enum TDB_ERROR tdb_append(struct tdb_context *tdb,
+ dbuf.dsize)); + dbuf.dsize));
goto out; goto out;
} }
ecode = tdb->methods->tread(tdb, off + sizeof(rec) + key.dsize, ecode = tdb->tdb2.io->tread(tdb, off + sizeof(rec) + key.dsize,
newdata, old_dlen); newdata, old_dlen);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
goto out_free_newdata; goto out_free_newdata;
...@@ -324,9 +324,17 @@ unsigned int tdb_get_flags(struct tdb_context *tdb) ...@@ -324,9 +324,17 @@ unsigned int tdb_get_flags(struct tdb_context *tdb)
return tdb->flags; return tdb->flags;
} }
static bool inside_transaction(const struct tdb_context *tdb)
{
if (tdb->flags & TDB_VERSION1)
return tdb->tdb1.transaction != NULL;
else
return tdb->tdb2.transaction != NULL;
}
static bool readonly_changable(struct tdb_context *tdb, const char *caller) static bool readonly_changable(struct tdb_context *tdb, const char *caller)
{ {
if (tdb->transaction) { if (inside_transaction(tdb)) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL,
TDB_LOG_USE_ERROR, TDB_LOG_USE_ERROR,
"%s: can't change" "%s: can't change"
......
...@@ -36,11 +36,8 @@ ...@@ -36,11 +36,8 @@
#endif #endif
/** This is the context structure that is returned from a db open. */ typedef int (*tdb1_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *);
typedef struct tdb1_context TDB1_CONTEXT; typedef void (*tdb1_log_func)(struct tdb_context *, enum tdb_log_level, enum TDB_ERROR,
typedef int (*tdb1_traverse_func)(struct tdb1_context *, TDB_DATA, TDB_DATA, void *);
typedef void (*tdb1_log_func)(struct tdb1_context *, enum tdb_log_level, enum TDB_ERROR,
const char *, void *); const char *, void *);
typedef uint64_t (*tdb1_hash_func)(const void *key, size_t len, uint64_t seed, typedef uint64_t (*tdb1_hash_func)(const void *key, size_t len, uint64_t seed,
void *data); void *data);
...@@ -50,84 +47,84 @@ struct tdb1_logging_context { ...@@ -50,84 +47,84 @@ struct tdb1_logging_context {
void *log_private; void *log_private;
}; };
struct tdb1_context *tdb1_open(const char *name, int hash_size, int tdb1_flags, struct tdb_context *tdb1_open(const char *name, int hash_size, int tdb1_flags,
int open_flags, mode_t mode); int open_flags, mode_t mode);
struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flags, struct tdb_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flags,
int open_flags, mode_t mode, int open_flags, mode_t mode,
const struct tdb1_logging_context *log_ctx, const struct tdb1_logging_context *log_ctx,
tdb1_hash_func hash_fn); tdb1_hash_func hash_fn);
void tdb1_set_max_dead(struct tdb1_context *tdb, int max_dead); void tdb1_set_max_dead(struct tdb_context *tdb, int max_dead);
TDB_DATA tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key); TDB_DATA tdb1_fetch(struct tdb_context *tdb, TDB_DATA key);
int tdb1_parse_record(struct tdb1_context *tdb, TDB_DATA key, int tdb1_parse_record(struct tdb_context *tdb, TDB_DATA key,
int (*parser)(TDB_DATA key, TDB_DATA data, int (*parser)(TDB_DATA key, TDB_DATA data,
void *private_data), void *private_data),
void *private_data); void *private_data);
int tdb1_delete(struct tdb1_context *tdb, TDB_DATA key); int tdb1_delete(struct tdb_context *tdb, TDB_DATA key);
int tdb1_store(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); int tdb1_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
int tdb1_append(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA new_dbuf); int tdb1_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf);
int tdb1_close(struct tdb1_context *tdb); int tdb1_close(struct tdb_context *tdb);
TDB_DATA tdb1_firstkey(struct tdb1_context *tdb); TDB_DATA tdb1_firstkey(struct tdb_context *tdb);
TDB_DATA tdb1_nextkey(struct tdb1_context *tdb, TDB_DATA key); TDB_DATA tdb1_nextkey(struct tdb_context *tdb, TDB_DATA key);
int tdb1_traverse(struct tdb1_context *tdb, tdb1_traverse_func fn, void *private_data); int tdb1_traverse(struct tdb_context *tdb, tdb1_traverse_func fn, void *private_data);
int tdb1_traverse_read(struct tdb1_context *tdb, tdb1_traverse_func fn, void *private_data); int tdb1_traverse_read(struct tdb_context *tdb, tdb1_traverse_func fn, void *private_data);
int tdb1_exists(struct tdb1_context *tdb, TDB_DATA key); int tdb1_exists(struct tdb_context *tdb, TDB_DATA key);
int tdb1_lockall(struct tdb1_context *tdb); int tdb1_lockall(struct tdb_context *tdb);
int tdb1_unlockall(struct tdb1_context *tdb); int tdb1_unlockall(struct tdb_context *tdb);
int tdb1_lockall_read(struct tdb1_context *tdb); int tdb1_lockall_read(struct tdb_context *tdb);
int tdb1_unlockall_read(struct tdb1_context *tdb); int tdb1_unlockall_read(struct tdb_context *tdb);
int tdb1_transaction_start(struct tdb1_context *tdb); int tdb1_transaction_start(struct tdb_context *tdb);
int tdb1_transaction_prepare_commit(struct tdb1_context *tdb); int tdb1_transaction_prepare_commit(struct tdb_context *tdb);
int tdb1_transaction_commit(struct tdb1_context *tdb); int tdb1_transaction_commit(struct tdb_context *tdb);
int tdb1_transaction_cancel(struct tdb1_context *tdb); int tdb1_transaction_cancel(struct tdb_context *tdb);
int tdb1_get_seqnum(struct tdb1_context *tdb); int tdb1_get_seqnum(struct tdb_context *tdb);
int tdb1_hash_size(struct tdb1_context *tdb); int tdb1_hash_size(struct tdb_context *tdb);
void tdb1_increment_seqnum_nonblock(struct tdb1_context *tdb); void tdb1_increment_seqnum_nonblock(struct tdb_context *tdb);
uint64_t tdb1_incompatible_hash(const void *key, size_t len, uint64_t seed, void *); uint64_t tdb1_incompatible_hash(const void *key, size_t len, uint64_t seed, void *);
int tdb1_check(struct tdb1_context *tdb, int tdb1_check(struct tdb_context *tdb,
int (*check) (TDB_DATA key, TDB_DATA data, void *private_data), int (*check) (TDB_DATA key, TDB_DATA data, void *private_data),
void *private_data); void *private_data);
/* @} ******************************************************************/ /* @} ******************************************************************/
/* Low level locking functions: use with care */ /* Low level locking functions: use with care */
int tdb1_chainlock(struct tdb1_context *tdb, TDB_DATA key); int tdb1_chainlock(struct tdb_context *tdb, TDB_DATA key);
int tdb1_chainunlock(struct tdb1_context *tdb, TDB_DATA key); int tdb1_chainunlock(struct tdb_context *tdb, TDB_DATA key);
int tdb1_chainlock_read(struct tdb1_context *tdb, TDB_DATA key); int tdb1_chainlock_read(struct tdb_context *tdb, TDB_DATA key);
int tdb1_chainunlock_read(struct tdb1_context *tdb, TDB_DATA key); int tdb1_chainunlock_read(struct tdb_context *tdb, TDB_DATA key);
/* wipe and repack */ /* wipe and repack */
int tdb1_wipe_all(struct tdb1_context *tdb); int tdb1_wipe_all(struct tdb_context *tdb);
int tdb1_repack(struct tdb1_context *tdb); int tdb1_repack(struct tdb_context *tdb);
/* Debug functions. Not used in production. */ /* Debug functions. Not used in production. */
char *tdb1_summary(struct tdb1_context *tdb); char *tdb1_summary(struct tdb_context *tdb);
extern TDB_DATA tdb1_null; extern TDB_DATA tdb1_null;
......
...@@ -25,12 +25,12 @@ ...@@ -25,12 +25,12 @@
#include "tdb1_private.h" #include "tdb1_private.h"
/* Since we opened it, these shouldn't fail unless it's recent corruption. */ /* Since we opened it, these shouldn't fail unless it's recent corruption. */
static bool tdb1_check_header(struct tdb1_context *tdb, tdb1_off_t *recovery) static bool tdb1_check_header(struct tdb_context *tdb, tdb1_off_t *recovery)
{ {
struct tdb1_header hdr; struct tdb1_header hdr;
uint32_t h1, h2; uint32_t h1, h2;
if (tdb->methods->tdb1_read(tdb, 0, &hdr, sizeof(hdr), 0) == -1) if (tdb->tdb1.io->tdb1_read(tdb, 0, &hdr, sizeof(hdr), 0) == -1)
return false; return false;
if (strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) if (strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0)
goto corrupt; goto corrupt;
...@@ -50,11 +50,11 @@ static bool tdb1_check_header(struct tdb1_context *tdb, tdb1_off_t *recovery) ...@@ -50,11 +50,11 @@ static bool tdb1_check_header(struct tdb1_context *tdb, tdb1_off_t *recovery)
if (hdr.hash_size == 0) if (hdr.hash_size == 0)
goto corrupt; goto corrupt;
if (hdr.hash_size != tdb->header.hash_size) if (hdr.hash_size != tdb->tdb1.header.hash_size)
goto corrupt; goto corrupt;
if (hdr.recovery_start != 0 && if (hdr.recovery_start != 0 &&
hdr.recovery_start < TDB1_DATA_START(tdb->header.hash_size)) hdr.recovery_start < TDB1_DATA_START(tdb->tdb1.header.hash_size))
goto corrupt; goto corrupt;
*recovery = hdr.recovery_start; *recovery = hdr.recovery_start;
...@@ -67,14 +67,14 @@ corrupt: ...@@ -67,14 +67,14 @@ corrupt:
} }
/* Generic record header check. */ /* Generic record header check. */
static bool tdb1_check_record(struct tdb1_context *tdb, static bool tdb1_check_record(struct tdb_context *tdb,
tdb1_off_t off, tdb1_off_t off,
const struct tdb1_record *rec) const struct tdb1_record *rec)
{ {
tdb1_off_t tailer; tdb1_off_t tailer;
/* Check rec->next: 0 or points to record offset, aligned. */ /* Check rec->next: 0 or points to record offset, aligned. */
if (rec->next > 0 && rec->next < TDB1_DATA_START(tdb->header.hash_size)){ if (rec->next > 0 && rec->next < TDB1_DATA_START(tdb->tdb1.header.hash_size)){
tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
"Record offset %d too small next %d\n", "Record offset %d too small next %d\n",
off, rec->next); off, rec->next);
...@@ -92,7 +92,7 @@ static bool tdb1_check_record(struct tdb1_context *tdb, ...@@ -92,7 +92,7 @@ static bool tdb1_check_record(struct tdb1_context *tdb,
off, rec->next); off, rec->next);
goto corrupt; goto corrupt;
} }
if (tdb->methods->tdb1_oob(tdb, rec->next+sizeof(*rec), 0)) if (tdb->tdb1.io->tdb1_oob(tdb, rec->next+sizeof(*rec), 0))
goto corrupt; goto corrupt;
/* Check rec_len: similar to rec->next, implies next record. */ /* Check rec_len: similar to rec->next, implies next record. */
...@@ -110,7 +110,7 @@ static bool tdb1_check_record(struct tdb1_context *tdb, ...@@ -110,7 +110,7 @@ static bool tdb1_check_record(struct tdb1_context *tdb,
goto corrupt; goto corrupt;
} }
/* OOB allows "right at the end" access, so this works for last rec. */ /* OOB allows "right at the end" access, so this works for last rec. */
if (tdb->methods->tdb1_oob(tdb, off+sizeof(*rec)+rec->rec_len, 0)) if (tdb->tdb1.io->tdb1_oob(tdb, off+sizeof(*rec)+rec->rec_len, 0))
goto corrupt; goto corrupt;
/* Check tailer. */ /* Check tailer. */
...@@ -132,14 +132,14 @@ corrupt: ...@@ -132,14 +132,14 @@ corrupt:
/* Grab some bytes: may copy if can't use mmap. /* Grab some bytes: may copy if can't use mmap.
Caller has already done bounds check. */ Caller has already done bounds check. */
static TDB_DATA get_bytes(struct tdb1_context *tdb, static TDB_DATA get_bytes(struct tdb_context *tdb,
tdb1_off_t off, tdb1_len_t len) tdb1_off_t off, tdb1_len_t len)
{ {
TDB_DATA d; TDB_DATA d;
d.dsize = len; d.dsize = len;
if (tdb->transaction == NULL && tdb->file->map_ptr != NULL) if (tdb->tdb1.transaction == NULL && tdb->file->map_ptr != NULL)
d.dptr = (unsigned char *)tdb->file->map_ptr + off; d.dptr = (unsigned char *)tdb->file->map_ptr + off;
else else
d.dptr = tdb1_alloc_read(tdb, off, d.dsize); d.dptr = tdb1_alloc_read(tdb, off, d.dsize);
...@@ -147,9 +147,9 @@ static TDB_DATA get_bytes(struct tdb1_context *tdb, ...@@ -147,9 +147,9 @@ static TDB_DATA get_bytes(struct tdb1_context *tdb,
} }
/* Frees data if we're not able to simply use mmap. */ /* Frees data if we're not able to simply use mmap. */
static void put_bytes(struct tdb1_context *tdb, TDB_DATA d) static void put_bytes(struct tdb_context *tdb, TDB_DATA d)
{ {
if (tdb->transaction == NULL && tdb->file->map_ptr != NULL) if (tdb->tdb1.transaction == NULL && tdb->file->map_ptr != NULL)
return; return;
free(d.dptr); free(d.dptr);
} }
...@@ -232,7 +232,7 @@ static void record_offset(unsigned char bits[], tdb1_off_t off) ...@@ -232,7 +232,7 @@ static void record_offset(unsigned char bits[], tdb1_off_t off)
} }
/* Check that an in-use record is valid. */ /* Check that an in-use record is valid. */
static bool tdb1_check_used_record(struct tdb1_context *tdb, static bool tdb1_check_used_record(struct tdb_context *tdb,
tdb1_off_t off, tdb1_off_t off,
const struct tdb1_record *rec, const struct tdb1_record *rec,
unsigned char **hashes, unsigned char **hashes,
...@@ -291,7 +291,7 @@ fail_put_key: ...@@ -291,7 +291,7 @@ fail_put_key:
} }
/* Check that an unused record is valid. */ /* Check that an unused record is valid. */
static bool tdb1_check_free_record(struct tdb1_context *tdb, static bool tdb1_check_free_record(struct tdb_context *tdb,
tdb1_off_t off, tdb1_off_t off,
const struct tdb1_record *rec, const struct tdb1_record *rec,
unsigned char **hashes) unsigned char **hashes)
...@@ -308,13 +308,13 @@ static bool tdb1_check_free_record(struct tdb1_context *tdb, ...@@ -308,13 +308,13 @@ static bool tdb1_check_free_record(struct tdb1_context *tdb,
} }
/* Slow, but should be very rare. */ /* Slow, but should be very rare. */
size_t tdb1_dead_space(struct tdb1_context *tdb, tdb1_off_t off) size_t tdb1_dead_space(struct tdb_context *tdb, tdb1_off_t off)
{ {
size_t len; size_t len;
for (len = 0; off + len < tdb->file->map_size; len++) { for (len = 0; off + len < tdb->file->map_size; len++) {
char c; char c;
if (tdb->methods->tdb1_read(tdb, off, &c, 1, 0)) if (tdb->tdb1.io->tdb1_read(tdb, off, &c, 1, 0))
return 0; return 0;
if (c != 0 && c != 0x42) if (c != 0 && c != 0x42)
break; break;
...@@ -322,7 +322,7 @@ size_t tdb1_dead_space(struct tdb1_context *tdb, tdb1_off_t off) ...@@ -322,7 +322,7 @@ size_t tdb1_dead_space(struct tdb1_context *tdb, tdb1_off_t off)
return len; return len;
} }
int tdb1_check(struct tdb1_context *tdb, int tdb1_check(struct tdb_context *tdb,
int (*check)(TDB_DATA key, TDB_DATA data, void *private_data), int (*check)(TDB_DATA key, TDB_DATA data, void *private_data),
void *private_data) void *private_data)
{ {
...@@ -344,14 +344,14 @@ int tdb1_check(struct tdb1_context *tdb, ...@@ -344,14 +344,14 @@ int tdb1_check(struct tdb1_context *tdb,
} }
/* Make sure we know true size of the underlying file. */ /* Make sure we know true size of the underlying file. */
tdb->methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1); tdb->tdb1.io->tdb1_oob(tdb, tdb->file->map_size + 1, 1);
/* Header must be OK: also gets us the recovery ptr, if any. */ /* Header must be OK: also gets us the recovery ptr, if any. */
if (!tdb1_check_header(tdb, &recovery_start)) if (!tdb1_check_header(tdb, &recovery_start))
goto unlock; goto unlock;
/* We should have the whole header, too. */ /* We should have the whole header, too. */
if (tdb->file->map_size < TDB1_DATA_START(tdb->header.hash_size)) { if (tdb->file->map_size < TDB1_DATA_START(tdb->tdb1.header.hash_size)) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
"File too short for hashes\n"); "File too short for hashes\n");
goto unlock; goto unlock;
...@@ -359,20 +359,20 @@ int tdb1_check(struct tdb1_context *tdb, ...@@ -359,20 +359,20 @@ int tdb1_check(struct tdb1_context *tdb,
/* One big malloc: pointers then bit arrays. */ /* One big malloc: pointers then bit arrays. */
hashes = (unsigned char **)calloc( hashes = (unsigned char **)calloc(
1, sizeof(hashes[0]) * (1+tdb->header.hash_size) 1, sizeof(hashes[0]) * (1+tdb->tdb1.header.hash_size)
+ BITMAP_BITS / CHAR_BIT * (1+tdb->header.hash_size)); + BITMAP_BITS / CHAR_BIT * (1+tdb->tdb1.header.hash_size));
if (!hashes) { if (!hashes) {
tdb->last_error = TDB_ERR_OOM; tdb->last_error = TDB_ERR_OOM;
goto unlock; goto unlock;
} }
/* Initialize pointers */ /* Initialize pointers */
hashes[0] = (unsigned char *)(&hashes[1+tdb->header.hash_size]); hashes[0] = (unsigned char *)(&hashes[1+tdb->tdb1.header.hash_size]);
for (h = 1; h < 1+tdb->header.hash_size; h++) for (h = 1; h < 1+tdb->tdb1.header.hash_size; h++)
hashes[h] = hashes[h-1] + BITMAP_BITS / CHAR_BIT; hashes[h] = hashes[h-1] + BITMAP_BITS / CHAR_BIT;
/* Freelist and hash headers are all in a row: read them. */ /* Freelist and hash headers are all in a row: read them. */
for (h = 0; h < 1+tdb->header.hash_size; h++) { for (h = 0; h < 1+tdb->tdb1.header.hash_size; h++) {
if (tdb1_ofs_read(tdb, TDB1_FREELIST_TOP + h*sizeof(tdb1_off_t), if (tdb1_ofs_read(tdb, TDB1_FREELIST_TOP + h*sizeof(tdb1_off_t),
&off) == -1) &off) == -1)
goto free; goto free;
...@@ -381,10 +381,10 @@ int tdb1_check(struct tdb1_context *tdb, ...@@ -381,10 +381,10 @@ int tdb1_check(struct tdb1_context *tdb,
} }
/* For each record, read it in and check it's ok. */ /* For each record, read it in and check it's ok. */
for (off = TDB1_DATA_START(tdb->header.hash_size); for (off = TDB1_DATA_START(tdb->tdb1.header.hash_size);
off < tdb->file->map_size; off < tdb->file->map_size;
off += sizeof(rec) + rec.rec_len) { off += sizeof(rec) + rec.rec_len) {
if (tdb->methods->tdb1_read(tdb, off, &rec, sizeof(rec), if (tdb->tdb1.io->tdb1_read(tdb, off, &rec, sizeof(rec),
TDB1_DOCONV()) == -1) TDB1_DOCONV()) == -1)
goto free; goto free;
switch (rec.magic) { switch (rec.magic) {
...@@ -434,7 +434,7 @@ int tdb1_check(struct tdb1_context *tdb, ...@@ -434,7 +434,7 @@ int tdb1_check(struct tdb1_context *tdb,
/* Now, hashes should all be empty: each record exists and is referred /* Now, hashes should all be empty: each record exists and is referred
* to by one other. */ * to by one other. */
for (h = 0; h < 1+tdb->header.hash_size; h++) { for (h = 0; h < 1+tdb->tdb1.header.hash_size; h++) {
unsigned int i; unsigned int i;
for (i = 0; i < BITMAP_BITS / CHAR_BIT; i++) { for (i = 0; i < BITMAP_BITS / CHAR_BIT; i++) {
if (hashes[h][i] != 0) { if (hashes[h][i] != 0) {
......
...@@ -28,9 +28,9 @@ ...@@ -28,9 +28,9 @@
#include "tdb1_private.h" #include "tdb1_private.h"
/* read a freelist record and check for simple errors */ /* read a freelist record and check for simple errors */
int tdb1_rec_free_read(struct tdb1_context *tdb, tdb1_off_t off, struct tdb1_record *rec) int tdb1_rec_free_read(struct tdb_context *tdb, tdb1_off_t off, struct tdb1_record *rec)
{ {
if (tdb->methods->tdb1_read(tdb, off, rec, sizeof(*rec),TDB1_DOCONV()) == -1) if (tdb->tdb1.io->tdb1_read(tdb, off, rec, sizeof(*rec),TDB1_DOCONV()) == -1)
return -1; return -1;
if (rec->magic == TDB1_MAGIC) { if (rec->magic == TDB1_MAGIC) {
...@@ -40,7 +40,7 @@ int tdb1_rec_free_read(struct tdb1_context *tdb, tdb1_off_t off, struct tdb1_rec ...@@ -40,7 +40,7 @@ int tdb1_rec_free_read(struct tdb1_context *tdb, tdb1_off_t off, struct tdb1_rec
"tdb1_rec_free_read non-free magic 0x%x at offset=%d - fixing\n", "tdb1_rec_free_read non-free magic 0x%x at offset=%d - fixing\n",
rec->magic, off); rec->magic, off);
rec->magic = TDB1_FREE_MAGIC; rec->magic = TDB1_FREE_MAGIC;
if (tdb->methods->tdb1_write(tdb, off, rec, sizeof(*rec)) == -1) if (tdb->tdb1.io->tdb1_write(tdb, off, rec, sizeof(*rec)) == -1)
return -1; return -1;
} }
...@@ -50,14 +50,14 @@ int tdb1_rec_free_read(struct tdb1_context *tdb, tdb1_off_t off, struct tdb1_rec ...@@ -50,14 +50,14 @@ int tdb1_rec_free_read(struct tdb1_context *tdb, tdb1_off_t off, struct tdb1_rec
rec->magic, off); rec->magic, off);
return -1; return -1;
} }
if (tdb->methods->tdb1_oob(tdb, rec->next+sizeof(*rec), 0) != 0) if (tdb->tdb1.io->tdb1_oob(tdb, rec->next+sizeof(*rec), 0) != 0)
return -1; return -1;
return 0; return 0;
} }
/* update a record tailer (must hold allocation lock) */ /* update a record tailer (must hold allocation lock) */
static int update_tailer(struct tdb1_context *tdb, tdb1_off_t offset, static int update_tailer(struct tdb_context *tdb, tdb1_off_t offset,
const struct tdb1_record *rec) const struct tdb1_record *rec)
{ {
tdb1_off_t totalsize; tdb1_off_t totalsize;
...@@ -70,7 +70,7 @@ static int update_tailer(struct tdb1_context *tdb, tdb1_off_t offset, ...@@ -70,7 +70,7 @@ static int update_tailer(struct tdb1_context *tdb, tdb1_off_t offset,
/* Add an element into the freelist. Merge adjacent records if /* Add an element into the freelist. Merge adjacent records if
necessary. */ necessary. */
int tdb1_free(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_record *rec) int tdb1_free(struct tdb_context *tdb, tdb1_off_t offset, struct tdb1_record *rec)
{ {
/* Allocation and tailer lock */ /* Allocation and tailer lock */
if (tdb1_lock(tdb, -1, F_WRLCK) != 0) if (tdb1_lock(tdb, -1, F_WRLCK) != 0)
...@@ -84,7 +84,7 @@ int tdb1_free(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_record *r ...@@ -84,7 +84,7 @@ int tdb1_free(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_record *r
} }
/* Look left */ /* Look left */
if (offset - sizeof(tdb1_off_t) > TDB1_DATA_START(tdb->header.hash_size)) { if (offset - sizeof(tdb1_off_t) > TDB1_DATA_START(tdb->tdb1.header.hash_size)) {
tdb1_off_t left = offset - sizeof(tdb1_off_t); tdb1_off_t left = offset - sizeof(tdb1_off_t);
struct tdb1_record l; struct tdb1_record l;
tdb1_off_t leftsize; tdb1_off_t leftsize;
...@@ -104,12 +104,12 @@ int tdb1_free(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_record *r ...@@ -104,12 +104,12 @@ int tdb1_free(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_record *r
left = offset - leftsize; left = offset - leftsize;
if (leftsize > offset || if (leftsize > offset ||
left < TDB1_DATA_START(tdb->header.hash_size)) { left < TDB1_DATA_START(tdb->tdb1.header.hash_size)) {
goto update; goto update;
} }
/* Now read in the left record */ /* Now read in the left record */
if (tdb->methods->tdb1_read(tdb, left, &l, sizeof(l), TDB1_DOCONV()) == -1) { if (tdb->tdb1.io->tdb1_read(tdb, left, &l, sizeof(l), TDB1_DOCONV()) == -1) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_free: left read failed at %u (%u)", left, leftsize); "tdb1_free: left read failed at %u (%u)", left, leftsize);
goto update; goto update;
...@@ -169,7 +169,7 @@ update: ...@@ -169,7 +169,7 @@ update:
not the beginning. This is so the left merge in a free is more likely to be not the beginning. This is so the left merge in a free is more likely to be
able to free up the record without fragmentation able to free up the record without fragmentation
*/ */
static tdb1_off_t tdb1_allocate_ofs(struct tdb1_context *tdb, static tdb1_off_t tdb1_allocate_ofs(struct tdb_context *tdb,
tdb1_len_t length, tdb1_off_t rec_ptr, tdb1_len_t length, tdb1_off_t rec_ptr,
struct tdb1_record *rec, tdb1_off_t last_ptr) struct tdb1_record *rec, tdb1_off_t last_ptr)
{ {
...@@ -224,7 +224,7 @@ static tdb1_off_t tdb1_allocate_ofs(struct tdb1_context *tdb, ...@@ -224,7 +224,7 @@ static tdb1_off_t tdb1_allocate_ofs(struct tdb1_context *tdb,
0 is returned if the space could not be allocated 0 is returned if the space could not be allocated
*/ */
tdb1_off_t tdb1_allocate(struct tdb1_context *tdb, tdb1_len_t length, struct tdb1_record *rec) tdb1_off_t tdb1_allocate(struct tdb_context *tdb, tdb1_len_t length, struct tdb1_record *rec)
{ {
tdb1_off_t rec_ptr, last_ptr, newrec_ptr; tdb1_off_t rec_ptr, last_ptr, newrec_ptr;
struct { struct {
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
if necessary if necessary
note that "len" is the minimum length needed for the db note that "len" is the minimum length needed for the db
*/ */
static int tdb1_oob(struct tdb1_context *tdb, tdb1_off_t len, int probe) static int tdb1_oob(struct tdb_context *tdb, tdb1_off_t len, int probe)
{ {
struct stat st; struct stat st;
if (len <= tdb->file->map_size) if (len <= tdb->file->map_size)
...@@ -75,19 +75,19 @@ static int tdb1_oob(struct tdb1_context *tdb, tdb1_off_t len, int probe) ...@@ -75,19 +75,19 @@ static int tdb1_oob(struct tdb1_context *tdb, tdb1_off_t len, int probe)
} }
/* write a lump of data at a specified offset */ /* write a lump of data at a specified offset */
static int tdb1_write(struct tdb1_context *tdb, tdb1_off_t off, static int tdb1_write(struct tdb_context *tdb, tdb1_off_t off,
const void *buf, tdb1_len_t len) const void *buf, tdb1_len_t len)
{ {
if (len == 0) { if (len == 0) {
return 0; return 0;
} }
if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) { if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) {
tdb->last_error = TDB_ERR_RDONLY; tdb->last_error = TDB_ERR_RDONLY;
return -1; return -1;
} }
if (tdb->methods->tdb1_oob(tdb, off + len, 0) != 0) if (tdb->tdb1.io->tdb1_oob(tdb, off + len, 0) != 0)
return -1; return -1;
if (tdb->file->map_ptr) { if (tdb->file->map_ptr) {
...@@ -133,10 +133,10 @@ void *tdb1_convert(void *buf, uint32_t size) ...@@ -133,10 +133,10 @@ void *tdb1_convert(void *buf, uint32_t size)
/* read a lump of data at a specified offset, maybe convert */ /* read a lump of data at a specified offset, maybe convert */
static int tdb1_read(struct tdb1_context *tdb, tdb1_off_t off, void *buf, static int tdb1_read(struct tdb_context *tdb, tdb1_off_t off, void *buf,
tdb1_len_t len, int cv) tdb1_len_t len, int cv)
{ {
if (tdb->methods->tdb1_oob(tdb, off + len, 0) != 0) { if (tdb->tdb1.io->tdb1_oob(tdb, off + len, 0) != 0) {
return -1; return -1;
} }
...@@ -167,18 +167,18 @@ static int tdb1_read(struct tdb1_context *tdb, tdb1_off_t off, void *buf, ...@@ -167,18 +167,18 @@ static int tdb1_read(struct tdb1_context *tdb, tdb1_off_t off, void *buf,
do an unlocked scan of the hash table heads to find the next non-zero head. The value do an unlocked scan of the hash table heads to find the next non-zero head. The value
will then be confirmed with the lock held will then be confirmed with the lock held
*/ */
static void tdb1_next_hash_chain(struct tdb1_context *tdb, uint32_t *chain) static void tdb1_next_hash_chain(struct tdb_context *tdb, uint32_t *chain)
{ {
uint32_t h = *chain; uint32_t h = *chain;
if (tdb->file->map_ptr) { if (tdb->file->map_ptr) {
for (;h < tdb->header.hash_size;h++) { for (;h < tdb->tdb1.header.hash_size;h++) {
if (0 != *(uint32_t *)(TDB1_HASH_TOP(h) + (unsigned char *)tdb->file->map_ptr)) { if (0 != *(uint32_t *)(TDB1_HASH_TOP(h) + (unsigned char *)tdb->file->map_ptr)) {
break; break;
} }
} }
} else { } else {
uint32_t off=0; uint32_t off=0;
for (;h < tdb->header.hash_size;h++) { for (;h < tdb->tdb1.header.hash_size;h++) {
if (tdb1_ofs_read(tdb, TDB1_HASH_TOP(h), &off) != 0 || off != 0) { if (tdb1_ofs_read(tdb, TDB1_HASH_TOP(h), &off) != 0 || off != 0) {
break; break;
} }
...@@ -188,7 +188,7 @@ static void tdb1_next_hash_chain(struct tdb1_context *tdb, uint32_t *chain) ...@@ -188,7 +188,7 @@ static void tdb1_next_hash_chain(struct tdb1_context *tdb, uint32_t *chain)
} }
int tdb1_munmap(struct tdb1_context *tdb) int tdb1_munmap(struct tdb_context *tdb)
{ {
if (tdb->flags & TDB_INTERNAL) if (tdb->flags & TDB_INTERNAL)
return 0; return 0;
...@@ -206,7 +206,7 @@ int tdb1_munmap(struct tdb1_context *tdb) ...@@ -206,7 +206,7 @@ int tdb1_munmap(struct tdb1_context *tdb)
return 0; return 0;
} }
void tdb1_mmap(struct tdb1_context *tdb) void tdb1_mmap(struct tdb_context *tdb)
{ {
if (tdb->flags & TDB_INTERNAL) if (tdb->flags & TDB_INTERNAL)
return; return;
...@@ -243,11 +243,11 @@ void tdb1_mmap(struct tdb1_context *tdb) ...@@ -243,11 +243,11 @@ void tdb1_mmap(struct tdb1_context *tdb)
/* expand a file. we prefer to use ftruncate, as that is what posix /* expand a file. we prefer to use ftruncate, as that is what posix
says to use for mmap expansion */ says to use for mmap expansion */
static int tdb1_expand_file(struct tdb1_context *tdb, tdb1_off_t size, tdb1_off_t addition) static int tdb1_expand_file(struct tdb_context *tdb, tdb1_off_t size, tdb1_off_t addition)
{ {
char buf[8192]; char buf[8192];
if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) { if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) {
tdb->last_error = TDB_ERR_RDONLY; tdb->last_error = TDB_ERR_RDONLY;
return -1; return -1;
} }
...@@ -313,7 +313,7 @@ static int tdb1_expand_file(struct tdb1_context *tdb, tdb1_off_t size, tdb1_off_ ...@@ -313,7 +313,7 @@ static int tdb1_expand_file(struct tdb1_context *tdb, tdb1_off_t size, tdb1_off_
/* expand the database at least size bytes by expanding the underlying /* expand the database at least size bytes by expanding the underlying
file and doing the mmap again if necessary */ file and doing the mmap again if necessary */
int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size) int tdb1_expand(struct tdb_context *tdb, tdb1_off_t size)
{ {
struct tdb1_record rec; struct tdb1_record rec;
tdb1_off_t offset, new_size, top_size, map_size; tdb1_off_t offset, new_size, top_size, map_size;
...@@ -325,7 +325,7 @@ int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size) ...@@ -325,7 +325,7 @@ int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size)
} }
/* must know about any previous expansions by another process */ /* must know about any previous expansions by another process */
tdb->methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1); tdb->tdb1.io->tdb1_oob(tdb, tdb->file->map_size + 1, 1);
/* limit size in order to avoid using up huge amounts of memory for /* limit size in order to avoid using up huge amounts of memory for
* in memory tdbs if an oddball huge record creeps in */ * in memory tdbs if an oddball huge record creeps in */
...@@ -346,7 +346,7 @@ int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size) ...@@ -346,7 +346,7 @@ int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size)
/* Round the database up to a multiple of the page size */ /* Round the database up to a multiple of the page size */
new_size = MAX(top_size, map_size); new_size = MAX(top_size, map_size);
size = TDB1_ALIGN(new_size, tdb->page_size) - tdb->file->map_size; size = TDB1_ALIGN(new_size, tdb->tdb1.page_size) - tdb->file->map_size;
if (!(tdb->flags & TDB_INTERNAL)) if (!(tdb->flags & TDB_INTERNAL))
tdb1_munmap(tdb); tdb1_munmap(tdb);
...@@ -359,7 +359,7 @@ int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size) ...@@ -359,7 +359,7 @@ int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size)
/* expand the file itself */ /* expand the file itself */
if (!(tdb->flags & TDB_INTERNAL)) { if (!(tdb->flags & TDB_INTERNAL)) {
if (tdb->methods->tdb1_expand_file(tdb, tdb->file->map_size, size) != 0) if (tdb->tdb1.io->tdb1_expand_file(tdb, tdb->file->map_size, size) != 0)
goto fail; goto fail;
} }
...@@ -401,20 +401,20 @@ int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size) ...@@ -401,20 +401,20 @@ int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size)
} }
/* read/write a tdb1_off_t */ /* read/write a tdb1_off_t */
int tdb1_ofs_read(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_off_t *d) int tdb1_ofs_read(struct tdb_context *tdb, tdb1_off_t offset, tdb1_off_t *d)
{ {
return tdb->methods->tdb1_read(tdb, offset, (char*)d, sizeof(*d), TDB1_DOCONV()); return tdb->tdb1.io->tdb1_read(tdb, offset, (char*)d, sizeof(*d), TDB1_DOCONV());
} }
int tdb1_ofs_write(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_off_t *d) int tdb1_ofs_write(struct tdb_context *tdb, tdb1_off_t offset, tdb1_off_t *d)
{ {
tdb1_off_t off = *d; tdb1_off_t off = *d;
return tdb->methods->tdb1_write(tdb, offset, TDB1_CONV(off), sizeof(*d)); return tdb->tdb1.io->tdb1_write(tdb, offset, TDB1_CONV(off), sizeof(*d));
} }
/* read a lump of data, allocating the space for it */ /* read a lump of data, allocating the space for it */
unsigned char *tdb1_alloc_read(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_len_t len) unsigned char *tdb1_alloc_read(struct tdb_context *tdb, tdb1_off_t offset, tdb1_len_t len)
{ {
unsigned char *buf; unsigned char *buf;
...@@ -427,7 +427,7 @@ unsigned char *tdb1_alloc_read(struct tdb1_context *tdb, tdb1_off_t offset, tdb1 ...@@ -427,7 +427,7 @@ unsigned char *tdb1_alloc_read(struct tdb1_context *tdb, tdb1_off_t offset, tdb1
len, strerror(errno)); len, strerror(errno));
return NULL; return NULL;
} }
if (tdb->methods->tdb1_read(tdb, offset, buf, len, 0) == -1) { if (tdb->tdb1.io->tdb1_read(tdb, offset, buf, len, 0) == -1) {
SAFE_FREE(buf); SAFE_FREE(buf);
return NULL; return NULL;
} }
...@@ -436,7 +436,7 @@ unsigned char *tdb1_alloc_read(struct tdb1_context *tdb, tdb1_off_t offset, tdb1 ...@@ -436,7 +436,7 @@ unsigned char *tdb1_alloc_read(struct tdb1_context *tdb, tdb1_off_t offset, tdb1
/* Give a piece of tdb data to a parser */ /* Give a piece of tdb data to a parser */
int tdb1_parse_data(struct tdb1_context *tdb, TDB_DATA key, int tdb1_parse_data(struct tdb_context *tdb, TDB_DATA key,
tdb1_off_t offset, tdb1_len_t len, tdb1_off_t offset, tdb1_len_t len,
int (*parser)(TDB_DATA key, TDB_DATA data, int (*parser)(TDB_DATA key, TDB_DATA data,
void *private_data), void *private_data),
...@@ -447,12 +447,12 @@ int tdb1_parse_data(struct tdb1_context *tdb, TDB_DATA key, ...@@ -447,12 +447,12 @@ int tdb1_parse_data(struct tdb1_context *tdb, TDB_DATA key,
data.dsize = len; data.dsize = len;
if ((tdb->transaction == NULL) && (tdb->file->map_ptr != NULL)) { if ((tdb->tdb1.transaction == NULL) && (tdb->file->map_ptr != NULL)) {
/* /*
* Optimize by avoiding the malloc/memcpy/free, point the * Optimize by avoiding the malloc/memcpy/free, point the
* parser directly at the mmap area. * parser directly at the mmap area.
*/ */
if (tdb->methods->tdb1_oob(tdb, offset+len, 0) != 0) { if (tdb->tdb1.io->tdb1_oob(tdb, offset+len, 0) != 0) {
return -1; return -1;
} }
data.dptr = offset + (unsigned char *)tdb->file->map_ptr; data.dptr = offset + (unsigned char *)tdb->file->map_ptr;
...@@ -469,9 +469,9 @@ int tdb1_parse_data(struct tdb1_context *tdb, TDB_DATA key, ...@@ -469,9 +469,9 @@ int tdb1_parse_data(struct tdb1_context *tdb, TDB_DATA key,
} }
/* read/write a record */ /* read/write a record */
int tdb1_rec_read(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_record *rec) int tdb1_rec_read(struct tdb_context *tdb, tdb1_off_t offset, struct tdb1_record *rec)
{ {
if (tdb->methods->tdb1_read(tdb, offset, rec, sizeof(*rec),TDB1_DOCONV()) == -1) if (tdb->tdb1.io->tdb1_read(tdb, offset, rec, sizeof(*rec),TDB1_DOCONV()) == -1)
return -1; return -1;
if (TDB1_BAD_MAGIC(rec)) { if (TDB1_BAD_MAGIC(rec)) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
...@@ -479,13 +479,13 @@ int tdb1_rec_read(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_recor ...@@ -479,13 +479,13 @@ int tdb1_rec_read(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_recor
rec->magic, offset); rec->magic, offset);
return -1; return -1;
} }
return tdb->methods->tdb1_oob(tdb, rec->next+sizeof(*rec), 0); return tdb->tdb1.io->tdb1_oob(tdb, rec->next+sizeof(*rec), 0);
} }
int tdb1_rec_write(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_record *rec) int tdb1_rec_write(struct tdb_context *tdb, tdb1_off_t offset, struct tdb1_record *rec)
{ {
struct tdb1_record r = *rec; struct tdb1_record r = *rec;
return tdb->methods->tdb1_write(tdb, offset, TDB1_CONV(r), sizeof(r)); return tdb->tdb1.io->tdb1_write(tdb, offset, TDB1_CONV(r), sizeof(r));
} }
static const struct tdb1_methods io1_methods = { static const struct tdb1_methods io1_methods = {
...@@ -499,7 +499,7 @@ static const struct tdb1_methods io1_methods = { ...@@ -499,7 +499,7 @@ static const struct tdb1_methods io1_methods = {
/* /*
initialise the default methods table initialise the default methods table
*/ */
void tdb1_io_init(struct tdb1_context *tdb) void tdb1_io_init(struct tdb_context *tdb)
{ {
tdb->methods = &io1_methods; tdb->tdb1.io = &io1_methods;
} }
...@@ -41,7 +41,7 @@ static tdb1_off_t lock_offset(int list) ...@@ -41,7 +41,7 @@ static tdb1_off_t lock_offset(int list)
note that a len of zero means lock to end of file note that a len of zero means lock to end of file
*/ */
int tdb1_brlock(struct tdb1_context *tdb, int tdb1_brlock(struct tdb_context *tdb,
int rw_type, tdb1_off_t offset, size_t len, int rw_type, tdb1_off_t offset, size_t len,
enum tdb_lock_flags flags) enum tdb_lock_flags flags)
{ {
...@@ -53,7 +53,7 @@ int tdb1_brlock(struct tdb1_context *tdb, ...@@ -53,7 +53,7 @@ int tdb1_brlock(struct tdb1_context *tdb,
return -1; return -1;
} }
int tdb1_brunlock(struct tdb1_context *tdb, int tdb1_brunlock(struct tdb_context *tdb,
int rw_type, tdb1_off_t offset, size_t len) int rw_type, tdb1_off_t offset, size_t len)
{ {
enum TDB_ERROR ecode = tdb_brunlock(tdb, rw_type, offset, len); enum TDB_ERROR ecode = tdb_brunlock(tdb, rw_type, offset, len);
...@@ -63,7 +63,7 @@ int tdb1_brunlock(struct tdb1_context *tdb, ...@@ -63,7 +63,7 @@ int tdb1_brunlock(struct tdb1_context *tdb,
return -1; return -1;
} }
int tdb1_allrecord_upgrade(struct tdb1_context *tdb) int tdb1_allrecord_upgrade(struct tdb_context *tdb)
{ {
enum TDB_ERROR ecode = tdb_allrecord_upgrade(tdb, TDB1_FREELIST_TOP); enum TDB_ERROR ecode = tdb_allrecord_upgrade(tdb, TDB1_FREELIST_TOP);
if (ecode == TDB_SUCCESS) if (ecode == TDB_SUCCESS)
...@@ -72,7 +72,7 @@ int tdb1_allrecord_upgrade(struct tdb1_context *tdb) ...@@ -72,7 +72,7 @@ int tdb1_allrecord_upgrade(struct tdb1_context *tdb)
return -1; return -1;
} }
static struct tdb_lock *tdb1_find_nestlock(struct tdb1_context *tdb, static struct tdb_lock *tdb1_find_nestlock(struct tdb_context *tdb,
tdb1_off_t offset) tdb1_off_t offset)
{ {
unsigned int i; unsigned int i;
...@@ -86,12 +86,12 @@ static struct tdb_lock *tdb1_find_nestlock(struct tdb1_context *tdb, ...@@ -86,12 +86,12 @@ static struct tdb_lock *tdb1_find_nestlock(struct tdb1_context *tdb,
} }
/* lock an offset in the database. */ /* lock an offset in the database. */
int tdb1_nest_lock(struct tdb1_context *tdb, uint32_t offset, int ltype, int tdb1_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype,
enum tdb_lock_flags flags) enum tdb_lock_flags flags)
{ {
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
if (offset >= lock_offset(tdb->header.hash_size)) { if (offset >= lock_offset(tdb->tdb1.header.hash_size)) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR,
"tdb1_lock: invalid offset %u for" "tdb1_lock: invalid offset %u for"
" ltype=%d", " ltype=%d",
...@@ -107,7 +107,7 @@ int tdb1_nest_lock(struct tdb1_context *tdb, uint32_t offset, int ltype, ...@@ -107,7 +107,7 @@ int tdb1_nest_lock(struct tdb1_context *tdb, uint32_t offset, int ltype,
return 0; return 0;
} }
static int tdb1_lock_and_recover(struct tdb1_context *tdb) static int tdb1_lock_and_recover(struct tdb_context *tdb)
{ {
int ret; int ret;
...@@ -131,7 +131,7 @@ static int tdb1_lock_and_recover(struct tdb1_context *tdb) ...@@ -131,7 +131,7 @@ static int tdb1_lock_and_recover(struct tdb1_context *tdb)
return ret; return ret;
} }
static bool have_data_locks(const struct tdb1_context *tdb) static bool have_data_locks(const struct tdb_context *tdb)
{ {
unsigned int i; unsigned int i;
...@@ -142,7 +142,7 @@ static bool have_data_locks(const struct tdb1_context *tdb) ...@@ -142,7 +142,7 @@ static bool have_data_locks(const struct tdb1_context *tdb)
return false; return false;
} }
static int tdb1_lock_list(struct tdb1_context *tdb, int list, int ltype, static int tdb1_lock_list(struct tdb_context *tdb, int list, int ltype,
enum tdb_lock_flags waitflag) enum tdb_lock_flags waitflag)
{ {
int ret; int ret;
...@@ -175,7 +175,7 @@ static int tdb1_lock_list(struct tdb1_context *tdb, int list, int ltype, ...@@ -175,7 +175,7 @@ static int tdb1_lock_list(struct tdb1_context *tdb, int list, int ltype,
} }
/* lock a list in the database. list -1 is the alloc list */ /* lock a list in the database. list -1 is the alloc list */
int tdb1_lock(struct tdb1_context *tdb, int list, int ltype) int tdb1_lock(struct tdb_context *tdb, int list, int ltype)
{ {
int ret; int ret;
...@@ -189,15 +189,15 @@ int tdb1_lock(struct tdb1_context *tdb, int list, int ltype) ...@@ -189,15 +189,15 @@ int tdb1_lock(struct tdb1_context *tdb, int list, int ltype)
return ret; return ret;
} }
int tdb1_nest_unlock(struct tdb1_context *tdb, uint32_t offset, int ltype) int tdb1_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype)
{ {
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
/* Sanity checks */ /* Sanity checks */
if (offset >= lock_offset(tdb->header.hash_size)) { if (offset >= lock_offset(tdb->tdb1.header.hash_size)) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR,
"tdb1_unlock: offset %u invalid (%d)", "tdb1_unlock: offset %u invalid (%d)",
offset, tdb->header.hash_size); offset, tdb->tdb1.header.hash_size);
return -1; return -1;
} }
...@@ -209,7 +209,7 @@ int tdb1_nest_unlock(struct tdb1_context *tdb, uint32_t offset, int ltype) ...@@ -209,7 +209,7 @@ int tdb1_nest_unlock(struct tdb1_context *tdb, uint32_t offset, int ltype)
return 0; return 0;
} }
int tdb1_unlock(struct tdb1_context *tdb, int list, int ltype) int tdb1_unlock(struct tdb_context *tdb, int list, int ltype)
{ {
/* a global lock allows us to avoid per chain locks */ /* a global lock allows us to avoid per chain locks */
if (tdb->file->allrecord_lock.count && if (tdb->file->allrecord_lock.count &&
...@@ -228,7 +228,7 @@ int tdb1_unlock(struct tdb1_context *tdb, int list, int ltype) ...@@ -228,7 +228,7 @@ int tdb1_unlock(struct tdb1_context *tdb, int list, int ltype)
/* /*
get the transaction lock get the transaction lock
*/ */
int tdb1_transaction_lock(struct tdb1_context *tdb, int ltype, int tdb1_transaction_lock(struct tdb_context *tdb, int ltype,
enum tdb_lock_flags lockflags) enum tdb_lock_flags lockflags)
{ {
return tdb1_nest_lock(tdb, TDB1_TRANSACTION_LOCK, ltype, lockflags); return tdb1_nest_lock(tdb, TDB1_TRANSACTION_LOCK, ltype, lockflags);
...@@ -237,7 +237,7 @@ int tdb1_transaction_lock(struct tdb1_context *tdb, int ltype, ...@@ -237,7 +237,7 @@ int tdb1_transaction_lock(struct tdb1_context *tdb, int ltype,
/* /*
release the transaction lock release the transaction lock
*/ */
int tdb1_transaction_unlock(struct tdb1_context *tdb, int ltype) int tdb1_transaction_unlock(struct tdb_context *tdb, int ltype)
{ {
return tdb1_nest_unlock(tdb, TDB1_TRANSACTION_LOCK, ltype); return tdb1_nest_unlock(tdb, TDB1_TRANSACTION_LOCK, ltype);
} }
...@@ -245,13 +245,13 @@ int tdb1_transaction_unlock(struct tdb1_context *tdb, int ltype) ...@@ -245,13 +245,13 @@ int tdb1_transaction_unlock(struct tdb1_context *tdb, int ltype)
/* lock/unlock entire database. It can only be upgradable if you have some /* lock/unlock entire database. It can only be upgradable if you have some
* other way of guaranteeing exclusivity (ie. transaction write lock). * other way of guaranteeing exclusivity (ie. transaction write lock).
* We do the locking gradually to avoid being starved by smaller locks. */ * We do the locking gradually to avoid being starved by smaller locks. */
int tdb1_allrecord_lock(struct tdb1_context *tdb, int ltype, int tdb1_allrecord_lock(struct tdb_context *tdb, int ltype,
enum tdb_lock_flags flags, bool upgradable) enum tdb_lock_flags flags, bool upgradable)
{ {
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
/* tdb_lock_gradual() doesn't know about tdb->traverse_read. */ /* tdb_lock_gradual() doesn't know about tdb->tdb1.traverse_read. */
if (tdb->traverse_read && !(tdb->flags & TDB_NOLOCK)) { if (tdb->tdb1.traverse_read && !(tdb->flags & TDB_NOLOCK)) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK,
TDB_LOG_USE_ERROR, TDB_LOG_USE_ERROR,
"tdb1_allrecord_lock during" "tdb1_allrecord_lock during"
...@@ -291,17 +291,17 @@ int tdb1_allrecord_lock(struct tdb1_context *tdb, int ltype, ...@@ -291,17 +291,17 @@ int tdb1_allrecord_lock(struct tdb1_context *tdb, int ltype,
* It is (1) which cause the starvation problem, so we're only * It is (1) which cause the starvation problem, so we're only
* gradual for that. */ * gradual for that. */
ecode = tdb_lock_gradual(tdb, ltype, flags | TDB_LOCK_NOCHECK, ecode = tdb_lock_gradual(tdb, ltype, flags | TDB_LOCK_NOCHECK,
TDB1_FREELIST_TOP, tdb->header.hash_size * 4); TDB1_FREELIST_TOP, tdb->tdb1.header.hash_size * 4);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
tdb->last_error = ecode; tdb->last_error = ecode;
return -1; return -1;
} }
/* Grab individual record locks. */ /* Grab individual record locks. */
if (tdb1_brlock(tdb, ltype, lock_offset(tdb->header.hash_size), 0, if (tdb1_brlock(tdb, ltype, lock_offset(tdb->tdb1.header.hash_size), 0,
flags) == -1) { flags) == -1) {
tdb1_brunlock(tdb, ltype, TDB1_FREELIST_TOP, tdb1_brunlock(tdb, ltype, TDB1_FREELIST_TOP,
tdb->header.hash_size * 4); tdb->tdb1.header.hash_size * 4);
return -1; return -1;
} }
...@@ -327,10 +327,10 @@ int tdb1_allrecord_lock(struct tdb1_context *tdb, int ltype, ...@@ -327,10 +327,10 @@ int tdb1_allrecord_lock(struct tdb1_context *tdb, int ltype,
/* unlock entire db */ /* unlock entire db */
int tdb1_allrecord_unlock(struct tdb1_context *tdb, int ltype) int tdb1_allrecord_unlock(struct tdb_context *tdb, int ltype)
{ {
/* Don't try this during r/o traversal! */ /* Don't try this during r/o traversal! */
if (tdb->traverse_read) { if (tdb->tdb1.traverse_read) {
tdb->last_error = TDB_ERR_LOCK; tdb->last_error = TDB_ERR_LOCK;
return -1; return -1;
} }
...@@ -365,32 +365,32 @@ int tdb1_allrecord_unlock(struct tdb1_context *tdb, int ltype) ...@@ -365,32 +365,32 @@ int tdb1_allrecord_unlock(struct tdb1_context *tdb, int ltype)
} }
/* lock entire database with write lock */ /* lock entire database with write lock */
int tdb1_lockall(struct tdb1_context *tdb) int tdb1_lockall(struct tdb_context *tdb)
{ {
return tdb1_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); return tdb1_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false);
} }
/* unlock entire database with write lock */ /* unlock entire database with write lock */
int tdb1_unlockall(struct tdb1_context *tdb) int tdb1_unlockall(struct tdb_context *tdb)
{ {
return tdb1_allrecord_unlock(tdb, F_WRLCK); return tdb1_allrecord_unlock(tdb, F_WRLCK);
} }
/* lock entire database with read lock */ /* lock entire database with read lock */
int tdb1_lockall_read(struct tdb1_context *tdb) int tdb1_lockall_read(struct tdb_context *tdb)
{ {
return tdb1_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false); return tdb1_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false);
} }
/* unlock entire database with read lock */ /* unlock entire database with read lock */
int tdb1_unlockall_read(struct tdb1_context *tdb) int tdb1_unlockall_read(struct tdb_context *tdb)
{ {
return tdb1_allrecord_unlock(tdb, F_RDLCK); return tdb1_allrecord_unlock(tdb, F_RDLCK);
} }
/* lock/unlock one hash chain. This is meant to be used to reduce /* lock/unlock one hash chain. This is meant to be used to reduce
contention - it cannot guarantee how many records will be locked */ contention - it cannot guarantee how many records will be locked */
int tdb1_chainlock(struct tdb1_context *tdb, TDB_DATA key) int tdb1_chainlock(struct tdb_context *tdb, TDB_DATA key)
{ {
int ret = tdb1_lock(tdb, int ret = tdb1_lock(tdb,
TDB1_BUCKET(tdb_hash(tdb, key.dptr, key.dsize)), TDB1_BUCKET(tdb_hash(tdb, key.dptr, key.dsize)),
...@@ -398,13 +398,13 @@ int tdb1_chainlock(struct tdb1_context *tdb, TDB_DATA key) ...@@ -398,13 +398,13 @@ int tdb1_chainlock(struct tdb1_context *tdb, TDB_DATA key)
return ret; return ret;
} }
int tdb1_chainunlock(struct tdb1_context *tdb, TDB_DATA key) int tdb1_chainunlock(struct tdb_context *tdb, TDB_DATA key)
{ {
return tdb1_unlock(tdb, TDB1_BUCKET(tdb_hash(tdb, key.dptr, key.dsize)), return tdb1_unlock(tdb, TDB1_BUCKET(tdb_hash(tdb, key.dptr, key.dsize)),
F_WRLCK); F_WRLCK);
} }
int tdb1_chainlock_read(struct tdb1_context *tdb, TDB_DATA key) int tdb1_chainlock_read(struct tdb_context *tdb, TDB_DATA key)
{ {
int ret; int ret;
ret = tdb1_lock(tdb, TDB1_BUCKET(tdb_hash(tdb, key.dptr, key.dsize)), ret = tdb1_lock(tdb, TDB1_BUCKET(tdb_hash(tdb, key.dptr, key.dsize)),
...@@ -412,14 +412,14 @@ int tdb1_chainlock_read(struct tdb1_context *tdb, TDB_DATA key) ...@@ -412,14 +412,14 @@ int tdb1_chainlock_read(struct tdb1_context *tdb, TDB_DATA key)
return ret; return ret;
} }
int tdb1_chainunlock_read(struct tdb1_context *tdb, TDB_DATA key) int tdb1_chainunlock_read(struct tdb_context *tdb, TDB_DATA key)
{ {
return tdb1_unlock(tdb, TDB1_BUCKET(tdb_hash(tdb, key.dptr, key.dsize)), return tdb1_unlock(tdb, TDB1_BUCKET(tdb_hash(tdb, key.dptr, key.dsize)),
F_RDLCK); F_RDLCK);
} }
/* record lock stops delete underneath */ /* record lock stops delete underneath */
int tdb1_lock_record(struct tdb1_context *tdb, tdb1_off_t off) int tdb1_lock_record(struct tdb_context *tdb, tdb1_off_t off)
{ {
if (tdb->file->allrecord_lock.count) { if (tdb->file->allrecord_lock.count) {
return 0; return 0;
...@@ -432,10 +432,10 @@ int tdb1_lock_record(struct tdb1_context *tdb, tdb1_off_t off) ...@@ -432,10 +432,10 @@ int tdb1_lock_record(struct tdb1_context *tdb, tdb1_off_t off)
Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not
an error to fail to get the lock here. an error to fail to get the lock here.
*/ */
int tdb1_write_lock_record(struct tdb1_context *tdb, tdb1_off_t off) int tdb1_write_lock_record(struct tdb_context *tdb, tdb1_off_t off)
{ {
struct tdb1_traverse_lock *i; struct tdb1_traverse_lock *i;
for (i = &tdb->travlocks; i; i = i->next) for (i = &tdb->tdb1.travlocks; i; i = i->next)
if (i->off == off) if (i->off == off)
return -1; return -1;
if (tdb->file->allrecord_lock.count) { if (tdb->file->allrecord_lock.count) {
...@@ -447,7 +447,7 @@ int tdb1_write_lock_record(struct tdb1_context *tdb, tdb1_off_t off) ...@@ -447,7 +447,7 @@ int tdb1_write_lock_record(struct tdb1_context *tdb, tdb1_off_t off)
return tdb1_brlock(tdb, F_WRLCK, off, 1, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); return tdb1_brlock(tdb, F_WRLCK, off, 1, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE);
} }
int tdb1_write_unlock_record(struct tdb1_context *tdb, tdb1_off_t off) int tdb1_write_unlock_record(struct tdb_context *tdb, tdb1_off_t off)
{ {
if (tdb->file->allrecord_lock.count) { if (tdb->file->allrecord_lock.count) {
return 0; return 0;
...@@ -456,7 +456,7 @@ int tdb1_write_unlock_record(struct tdb1_context *tdb, tdb1_off_t off) ...@@ -456,7 +456,7 @@ int tdb1_write_unlock_record(struct tdb1_context *tdb, tdb1_off_t off)
} }
/* fcntl locks don't stack: avoid unlocking someone else's */ /* fcntl locks don't stack: avoid unlocking someone else's */
int tdb1_unlock_record(struct tdb1_context *tdb, tdb1_off_t off) int tdb1_unlock_record(struct tdb_context *tdb, tdb1_off_t off)
{ {
struct tdb1_traverse_lock *i; struct tdb1_traverse_lock *i;
uint32_t count = 0; uint32_t count = 0;
...@@ -467,18 +467,18 @@ int tdb1_unlock_record(struct tdb1_context *tdb, tdb1_off_t off) ...@@ -467,18 +467,18 @@ int tdb1_unlock_record(struct tdb1_context *tdb, tdb1_off_t off)
if (off == 0) if (off == 0)
return 0; return 0;
for (i = &tdb->travlocks; i; i = i->next) for (i = &tdb->tdb1.travlocks; i; i = i->next)
if (i->off == off) if (i->off == off)
count++; count++;
return (count == 1 ? tdb1_brunlock(tdb, F_RDLCK, off, 1) : 0); return (count == 1 ? tdb1_brunlock(tdb, F_RDLCK, off, 1) : 0);
} }
bool tdb1_have_extra_locks(struct tdb1_context *tdb) bool tdb1_have_extra_locks(struct tdb_context *tdb)
{ {
unsigned int extra = tdb->file->num_lockrecs; unsigned int extra = tdb->file->num_lockrecs;
/* A transaction holds the lock for all records. */ /* A transaction holds the lock for all records. */
if (!tdb->transaction && tdb->file->allrecord_lock.count) { if (!tdb->tdb1.transaction && tdb->file->allrecord_lock.count) {
return true; return true;
} }
...@@ -488,7 +488,7 @@ bool tdb1_have_extra_locks(struct tdb1_context *tdb) ...@@ -488,7 +488,7 @@ bool tdb1_have_extra_locks(struct tdb1_context *tdb)
} }
/* In a transaction, we expect to hold the transaction lock */ /* In a transaction, we expect to hold the transaction lock */
if (tdb->transaction if (tdb->tdb1.transaction
&& tdb1_find_nestlock(tdb, TDB1_TRANSACTION_LOCK)) { && tdb1_find_nestlock(tdb, TDB1_TRANSACTION_LOCK)) {
extra--; extra--;
} }
...@@ -497,7 +497,7 @@ bool tdb1_have_extra_locks(struct tdb1_context *tdb) ...@@ -497,7 +497,7 @@ bool tdb1_have_extra_locks(struct tdb1_context *tdb)
} }
/* The transaction code uses this to remove all locks. */ /* The transaction code uses this to remove all locks. */
void tdb1_release_transaction_locks(struct tdb1_context *tdb) void tdb1_release_transaction_locks(struct tdb_context *tdb)
{ {
unsigned int i, active = 0; unsigned int i, active = 0;
......
...@@ -28,10 +28,10 @@ ...@@ -28,10 +28,10 @@
#include "tdb1_private.h" #include "tdb1_private.h"
/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ /* all contexts, to ensure no double-opens (fcntl locks don't nest!) */
static struct tdb1_context *tdb1s = NULL; static struct tdb_context *tdb1s = NULL;
/* We use two hashes to double-check they're using the right hash function. */ /* We use two hashes to double-check they're using the right hash function. */
void tdb1_header_hash(struct tdb1_context *tdb, void tdb1_header_hash(struct tdb_context *tdb,
uint32_t *magic1_hash, uint32_t *magic2_hash) uint32_t *magic1_hash, uint32_t *magic2_hash)
{ {
uint32_t tdb1_magic = TDB1_MAGIC; uint32_t tdb1_magic = TDB1_MAGIC;
...@@ -45,7 +45,7 @@ void tdb1_header_hash(struct tdb1_context *tdb, ...@@ -45,7 +45,7 @@ void tdb1_header_hash(struct tdb1_context *tdb,
} }
/* initialise a new database with a specified hash size */ /* initialise a new database with a specified hash size */
static int tdb1_new_database(struct tdb1_context *tdb, int hash_size) static int tdb1_new_database(struct tdb_context *tdb, int hash_size)
{ {
struct tdb1_header *newdb; struct tdb1_header *newdb;
size_t size; size_t size;
...@@ -73,7 +73,7 @@ static int tdb1_new_database(struct tdb1_context *tdb, int hash_size) ...@@ -73,7 +73,7 @@ static int tdb1_new_database(struct tdb1_context *tdb, int hash_size)
tdb->file->fd = -1; tdb->file->fd = -1;
tdb->file->map_size = size; tdb->file->map_size = size;
tdb->file->map_ptr = (char *)newdb; tdb->file->map_ptr = (char *)newdb;
memcpy(&tdb->header, newdb, sizeof(tdb->header)); memcpy(&tdb->tdb1.header, newdb, sizeof(tdb->tdb1.header));
/* Convert the `ondisk' version if asked. */ /* Convert the `ondisk' version if asked. */
TDB1_CONV(*newdb); TDB1_CONV(*newdb);
return 0; return 0;
...@@ -86,7 +86,7 @@ static int tdb1_new_database(struct tdb1_context *tdb, int hash_size) ...@@ -86,7 +86,7 @@ static int tdb1_new_database(struct tdb1_context *tdb, int hash_size)
/* This creates an endian-converted header, as if read from disk */ /* This creates an endian-converted header, as if read from disk */
TDB1_CONV(*newdb); TDB1_CONV(*newdb);
memcpy(&tdb->header, newdb, sizeof(tdb->header)); memcpy(&tdb->tdb1.header, newdb, sizeof(tdb->tdb1.header));
/* Don't endian-convert the magic food! */ /* Don't endian-convert the magic food! */
memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
/* we still have "ret == -1" here */ /* we still have "ret == -1" here */
...@@ -103,7 +103,7 @@ static int tdb1_new_database(struct tdb1_context *tdb, int hash_size) ...@@ -103,7 +103,7 @@ static int tdb1_new_database(struct tdb1_context *tdb, int hash_size)
static int tdb1_already_open(dev_t device, static int tdb1_already_open(dev_t device,
ino_t ino) ino_t ino)
{ {
struct tdb1_context *i; struct tdb_context *i;
for (i = tdb1s; i; i = i->next) { for (i = tdb1s; i; i = i->next) {
if (i->file->device == device && i->file->inode == ino) { if (i->file->device == device && i->file->inode == ino) {
...@@ -124,21 +124,21 @@ static int tdb1_already_open(dev_t device, ...@@ -124,21 +124,21 @@ static int tdb1_already_open(dev_t device,
try to call tdb1_error or tdb1_errname, just do strerror(errno). try to call tdb1_error or tdb1_errname, just do strerror(errno).
@param name may be NULL for internal databases. */ @param name may be NULL for internal databases. */
struct tdb1_context *tdb1_open(const char *name, int hash_size, int tdb1_flags, struct tdb_context *tdb1_open(const char *name, int hash_size, int tdb1_flags,
int open_flags, mode_t mode) int open_flags, mode_t mode)
{ {
return tdb1_open_ex(name, hash_size, tdb1_flags, open_flags, mode, NULL, NULL); return tdb1_open_ex(name, hash_size, tdb1_flags, open_flags, mode, NULL, NULL);
} }
static bool hash_correct(struct tdb1_context *tdb, static bool hash_correct(struct tdb_context *tdb,
uint32_t *m1, uint32_t *m2) uint32_t *m1, uint32_t *m2)
{ {
tdb1_header_hash(tdb, m1, m2); tdb1_header_hash(tdb, m1, m2);
return (tdb->header.magic1_hash == *m1 && return (tdb->tdb1.header.magic1_hash == *m1 &&
tdb->header.magic2_hash == *m2); tdb->tdb1.header.magic2_hash == *m2);
} }
static bool check_header_hash(struct tdb1_context *tdb, static bool check_header_hash(struct tdb_context *tdb,
uint32_t *m1, uint32_t *m2) uint32_t *m1, uint32_t *m2)
{ {
if (hash_correct(tdb, m1, m2)) if (hash_correct(tdb, m1, m2))
...@@ -154,19 +154,19 @@ static bool check_header_hash(struct tdb1_context *tdb, ...@@ -154,19 +154,19 @@ static bool check_header_hash(struct tdb1_context *tdb,
return hash_correct(tdb, m1, m2); return hash_correct(tdb, m1, m2);
} }
struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flags, struct tdb_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flags,
int open_flags, mode_t mode, int open_flags, mode_t mode,
const struct tdb1_logging_context *log_ctx, const struct tdb1_logging_context *log_ctx,
tdb1_hash_func hash_fn) tdb1_hash_func hash_fn)
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
struct stat st; struct stat st;
int rev = 0; int rev = 0;
unsigned v; unsigned v;
const char *hash_alg; const char *hash_alg;
uint32_t magic1, magic2; uint32_t magic1, magic2;
if (!(tdb = (struct tdb1_context *)calloc(1, sizeof *tdb))) { if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) {
/* Can't log this */ /* Can't log this */
errno = ENOMEM; errno = ENOMEM;
goto fail; goto fail;
...@@ -231,13 +231,13 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag ...@@ -231,13 +231,13 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag
} }
/* cache the page size */ /* cache the page size */
tdb->page_size = getpagesize(); tdb->tdb1.page_size = getpagesize();
if (tdb->page_size <= 0) { if (tdb->tdb1.page_size <= 0) {
tdb->page_size = 0x2000; tdb->tdb1.page_size = 0x2000;
} }
/* FIXME: Used to be 5 for TDB_VOLATILE. */ /* FIXME: Used to be 5 for TDB_VOLATILE. */
tdb->max_dead_records = 0; tdb->tdb1.max_dead_records = 0;
if ((open_flags & O_ACCMODE) == O_WRONLY) { if ((open_flags & O_ACCMODE) == O_WRONLY) {
tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
...@@ -286,8 +286,8 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag ...@@ -286,8 +286,8 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag
} }
errno = 0; errno = 0;
if (read(tdb->file->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header) if (read(tdb->file->fd, &tdb->tdb1.header, sizeof(tdb->tdb1.header)) != sizeof(tdb->tdb1.header)
|| strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0) { || strcmp(tdb->tdb1.header.magic_food, TDB_MAGIC_FOOD) != 0) {
if (!(open_flags & O_CREAT) || tdb1_new_database(tdb, hash_size) == -1) { if (!(open_flags & O_CREAT) || tdb1_new_database(tdb, hash_size) == -1) {
if (errno == 0) { if (errno == 0) {
errno = EIO; /* ie bad format or something */ errno = EIO; /* ie bad format or something */
...@@ -295,8 +295,8 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag ...@@ -295,8 +295,8 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag
goto fail; goto fail;
} }
rev = (tdb->flags & TDB_CONVERT); rev = (tdb->flags & TDB_CONVERT);
} else if (tdb->header.version != TDB1_VERSION } else if (tdb->tdb1.header.version != TDB1_VERSION
&& !(rev = (tdb->header.version==TDB1_BYTEREV(TDB1_VERSION)))) { && !(rev = (tdb->tdb1.header.version==TDB1_BYTEREV(TDB1_VERSION)))) {
/* wrong version */ /* wrong version */
errno = EIO; errno = EIO;
goto fail; goto fail;
...@@ -305,19 +305,19 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag ...@@ -305,19 +305,19 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag
tdb->flags &= ~TDB_CONVERT; tdb->flags &= ~TDB_CONVERT;
else { else {
tdb->flags |= TDB_CONVERT; tdb->flags |= TDB_CONVERT;
tdb1_convert(&tdb->header, sizeof(tdb->header)); tdb1_convert(&tdb->tdb1.header, sizeof(tdb->tdb1.header));
} }
if (fstat(tdb->file->fd, &st) == -1) if (fstat(tdb->file->fd, &st) == -1)
goto fail; goto fail;
if (tdb->header.rwlocks != 0 && if (tdb->tdb1.header.rwlocks != 0 &&
tdb->header.rwlocks != TDB1_HASH_RWLOCK_MAGIC) { tdb->tdb1.header.rwlocks != TDB1_HASH_RWLOCK_MAGIC) {
tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
"tdb1_open_ex: spinlocks no longer supported"); "tdb1_open_ex: spinlocks no longer supported");
goto fail; goto fail;
} }
if ((tdb->header.magic1_hash == 0) && (tdb->header.magic2_hash == 0)) { if ((tdb->tdb1.header.magic1_hash == 0) && (tdb->tdb1.header.magic2_hash == 0)) {
/* older TDB without magic hash references */ /* older TDB without magic hash references */
tdb->hash_fn = tdb1_old_hash; tdb->hash_fn = tdb1_old_hash;
} else if (!check_header_hash(tdb, &magic1, &magic2)) { } else if (!check_header_hash(tdb, &magic1, &magic2)) {
...@@ -327,11 +327,11 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag ...@@ -327,11 +327,11 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag
"magic1_hash[0x%08X %s 0x%08X] " "magic1_hash[0x%08X %s 0x%08X] "
"magic2_hash[0x%08X %s 0x%08X]", "magic2_hash[0x%08X %s 0x%08X]",
name, hash_alg, name, hash_alg,
tdb->header.magic1_hash, tdb->tdb1.header.magic1_hash,
(tdb->header.magic1_hash == magic1) ? "==" : "!=", (tdb->tdb1.header.magic1_hash == magic1) ? "==" : "!=",
magic1, magic1,
tdb->header.magic2_hash, tdb->tdb1.header.magic2_hash,
(tdb->header.magic2_hash == magic2) ? "==" : "!=", (tdb->tdb1.header.magic2_hash == magic2) ? "==" : "!=",
magic2); magic2);
errno = EINVAL; errno = EINVAL;
goto fail; goto fail;
...@@ -399,9 +399,9 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag ...@@ -399,9 +399,9 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag
* Set the maximum number of dead records per hash chain * Set the maximum number of dead records per hash chain
*/ */
void tdb1_set_max_dead(struct tdb1_context *tdb, int max_dead) void tdb1_set_max_dead(struct tdb_context *tdb, int max_dead)
{ {
tdb->max_dead_records = max_dead; tdb->tdb1.max_dead_records = max_dead;
} }
/** /**
...@@ -409,12 +409,12 @@ void tdb1_set_max_dead(struct tdb1_context *tdb, int max_dead) ...@@ -409,12 +409,12 @@ void tdb1_set_max_dead(struct tdb1_context *tdb, int max_dead)
* *
* @returns -1 for error; 0 for success. * @returns -1 for error; 0 for success.
**/ **/
int tdb1_close(struct tdb1_context *tdb) int tdb1_close(struct tdb_context *tdb)
{ {
struct tdb1_context **i; struct tdb_context **i;
int ret = 0; int ret = 0;
if (tdb->transaction) { if (tdb->tdb1.transaction) {
tdb1_transaction_cancel(tdb); tdb1_transaction_cancel(tdb);
} }
......
...@@ -28,44 +28,6 @@ ...@@ -28,44 +28,6 @@
#include "private.h" #include "private.h"
#include "tdb1.h" #include "tdb1.h"
/**** FIXME: Type overrides for tdb2, for transition! */
#define tdb_logerr(tdb, ecode, level, ...) \
tdb_logerr((struct tdb_context *)(tdb), (ecode), (level), __VA_ARGS__)
#define tdb_error(tdb) \
tdb_error((struct tdb_context *)(tdb))
#define tdb_brlock(tdb1, rw_type, offset, len, flags) \
tdb_brlock((struct tdb_context *)(tdb1), \
(rw_type), (offset), (len), (flags))
#define tdb_brunlock(tdb1, rw_type, offset, len) \
tdb_brunlock((struct tdb_context *)(tdb1), (rw_type), (offset), (len))
#define tdb_nest_lock(tdb1, offset, ltype, flags) \
tdb_nest_lock((struct tdb_context *)(tdb1), (offset), (ltype), (flags))
#define tdb_nest_unlock(tdb1, offset, ltype) \
tdb_nest_unlock((struct tdb_context *)(tdb1), (offset), (ltype))
#define tdb_allrecord_lock(tdb1, offset, flags, upgradable) \
tdb_allrecord_lock((struct tdb_context *)(tdb1), \
(offset), (flags), (upgradable))
#define tdb_allrecord_unlock(tdb1, ltype) \
tdb_allrecord_unlock((struct tdb_context *)(tdb1), (ltype))
#define tdb_allrecord_upgrade(tdb1, start) \
tdb_allrecord_upgrade((struct tdb_context *)(tdb1), (start))
#define tdb_hash(tdb1, ptr, len) \
tdb_hash((struct tdb_context *)(tdb1), (ptr), (len))
#define tdb_lock_gradual(tdb1, ltype, flags, off, len) \
tdb_lock_gradual((struct tdb_context *)(tdb1), \
(ltype), (flags), (off), (len))
/***** END FIXME ***/
#include <limits.h> #include <limits.h>
/* #define TDB_TRACE 1 */ /* #define TDB_TRACE 1 */
...@@ -85,9 +47,6 @@ ...@@ -85,9 +47,6 @@
#define __location__ __FILE__ ":" __STRINGSTRING(__LINE__) #define __location__ __FILE__ ":" __STRINGSTRING(__LINE__)
#endif #endif
typedef uint32_t tdb1_len_t;
typedef uint32_t tdb1_off_t;
#ifndef offsetof #ifndef offsetof
#define offsetof(t,f) ((unsigned int)&((t *)0)->f) #define offsetof(t,f) ((unsigned int)&((t *)0)->f)
#endif #endif
...@@ -107,7 +66,7 @@ typedef uint32_t tdb1_off_t; ...@@ -107,7 +66,7 @@ typedef uint32_t tdb1_off_t;
#define TDB1_DEAD(r) ((r)->magic == TDB1_DEAD_MAGIC) #define TDB1_DEAD(r) ((r)->magic == TDB1_DEAD_MAGIC)
#define TDB1_BAD_MAGIC(r) ((r)->magic != TDB1_MAGIC && !TDB1_DEAD(r)) #define TDB1_BAD_MAGIC(r) ((r)->magic != TDB1_MAGIC && !TDB1_DEAD(r))
#define TDB1_HASH_TOP(hash) (TDB1_FREELIST_TOP + (TDB1_BUCKET(hash)+1)*sizeof(tdb1_off_t)) #define TDB1_HASH_TOP(hash) (TDB1_FREELIST_TOP + (TDB1_BUCKET(hash)+1)*sizeof(tdb1_off_t))
#define TDB1_HASHTABLE_SIZE(tdb) ((tdb->header.hash_size+1)*sizeof(tdb1_off_t)) #define TDB1_HASHTABLE_SIZE(tdb) ((tdb->tdb1.header.hash_size+1)*sizeof(tdb1_off_t))
#define TDB1_DATA_START(hash_size) (TDB1_HASH_TOP(hash_size-1) + sizeof(tdb1_off_t)) #define TDB1_DATA_START(hash_size) (TDB1_HASH_TOP(hash_size-1) + sizeof(tdb1_off_t))
#define TDB1_RECOVERY_HEAD offsetof(struct tdb1_header, recovery_start) #define TDB1_RECOVERY_HEAD offsetof(struct tdb1_header, recovery_start)
#define TDB1_SEQNUM_OFS offsetof(struct tdb1_header, sequence_number) #define TDB1_SEQNUM_OFS offsetof(struct tdb1_header, sequence_number)
...@@ -121,10 +80,10 @@ typedef uint32_t tdb1_off_t; ...@@ -121,10 +80,10 @@ typedef uint32_t tdb1_off_t;
/* free memory if the pointer is valid and zero the pointer */ /* free memory if the pointer is valid and zero the pointer */
#ifndef SAFE_FREE #ifndef SAFE_FREE
#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) #define SAFE_FREE(x) do { if ((x) != NULL) {free((void *)x); (x)=NULL;} } while(0)
#endif #endif
#define TDB1_BUCKET(hash) ((hash) % tdb->header.hash_size) #define TDB1_BUCKET(hash) ((hash) % tdb->tdb1.header.hash_size)
#define TDB1_DOCONV() (tdb->flags & TDB_CONVERT) #define TDB1_DOCONV() (tdb->flags & TDB_CONVERT)
#define TDB1_CONV(x) (TDB1_DOCONV() ? tdb1_convert(&x, sizeof(x)) : &x) #define TDB1_CONV(x) (TDB1_DOCONV() ? tdb1_convert(&x, sizeof(x)) : &x)
...@@ -151,141 +110,74 @@ struct tdb1_record { ...@@ -151,141 +110,74 @@ struct tdb1_record {
}; };
/* this is stored at the front of every database */
struct tdb1_header {
char magic_food[32]; /* for /etc/magic */
uint32_t version; /* version of the code */
uint32_t hash_size; /* number of hash entries */
tdb1_off_t rwlocks; /* obsolete - kept to detect old formats */
tdb1_off_t recovery_start; /* offset of transaction recovery region */
tdb1_off_t sequence_number; /* used when TDB1_SEQNUM is set */
uint32_t magic1_hash; /* hash of TDB_MAGIC_FOOD. */
uint32_t magic2_hash; /* hash of TDB1_MAGIC. */
tdb1_off_t reserved[27];
};
struct tdb1_traverse_lock {
struct tdb1_traverse_lock *next;
uint32_t off;
uint32_t hash;
int lock_rw;
};
struct tdb1_context;
struct tdb1_methods { struct tdb1_methods {
int (*tdb1_read)(struct tdb1_context *, tdb1_off_t , void *, tdb1_len_t , int ); int (*tdb1_read)(struct tdb_context *, tdb1_off_t , void *, tdb1_len_t , int );
int (*tdb1_write)(struct tdb1_context *, tdb1_off_t, const void *, tdb1_len_t); int (*tdb1_write)(struct tdb_context *, tdb1_off_t, const void *, tdb1_len_t);
void (*next_hash_chain)(struct tdb1_context *, uint32_t *); void (*next_hash_chain)(struct tdb_context *, uint32_t *);
int (*tdb1_oob)(struct tdb1_context *, tdb1_off_t , int ); int (*tdb1_oob)(struct tdb_context *, tdb1_off_t , int );
int (*tdb1_expand_file)(struct tdb1_context *, tdb1_off_t , tdb1_off_t ); int (*tdb1_expand_file)(struct tdb_context *, tdb1_off_t , tdb1_off_t );
}; };
struct tdb1_context {
struct tdb1_context *next;
char *name; /* the name of the database */
/* Logging function */
void (*log_fn)(struct tdb1_context *tdb,
enum tdb_log_level level,
enum TDB_ERROR ecode,
const char *message,
void *data);
void *log_data;
/* Last error we returned. */
enum TDB_ERROR last_error; /* error code for last tdb error */
/* The actual file information */
struct tdb_file *file;
int open_flags; /* flags used in the open - needed by reopen */
/* low level (fnctl) lock functions. */
int (*lock_fn)(int fd, int rw, off_t off, off_t len, bool w, void *);
int (*unlock_fn)(int fd, int rw, off_t off, off_t len, void *);
void *lock_data;
uint32_t flags; /* the flags passed to tdb1_open */
/* Our statistics. */
struct tdb_attribute_stats stats;
/* Hash function. */
uint64_t (*hash_fn)(const void *key, size_t len, uint64_t seed, void *);
void *hash_data;
uint64_t hash_seed;
int traverse_read; /* read-only traversal */
int traverse_write; /* read-write traversal */
struct tdb1_header header; /* a cached copy of the header */
struct tdb1_traverse_lock travlocks; /* current traversal locks */
const struct tdb1_methods *methods;
struct tdb1_transaction *transaction;
int page_size;
int max_dead_records;
};
/* /*
internal prototypes internal prototypes
*/ */
int tdb1_munmap(struct tdb1_context *tdb); int tdb1_munmap(struct tdb_context *tdb);
void tdb1_mmap(struct tdb1_context *tdb); void tdb1_mmap(struct tdb_context *tdb);
int tdb1_lock(struct tdb1_context *tdb, int list, int ltype); int tdb1_lock(struct tdb_context *tdb, int list, int ltype);
int tdb1_nest_lock(struct tdb1_context *tdb, uint32_t offset, int ltype, int tdb1_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype,
enum tdb_lock_flags flags); enum tdb_lock_flags flags);
int tdb1_nest_unlock(struct tdb1_context *tdb, uint32_t offset, int ltype); int tdb1_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype);
int tdb1_unlock(struct tdb1_context *tdb, int list, int ltype); int tdb1_unlock(struct tdb_context *tdb, int list, int ltype);
int tdb1_brlock(struct tdb1_context *tdb, int tdb1_brlock(struct tdb_context *tdb,
int rw_type, tdb1_off_t offset, size_t len, int rw_type, tdb1_off_t offset, size_t len,
enum tdb_lock_flags flags); enum tdb_lock_flags flags);
int tdb1_brunlock(struct tdb1_context *tdb, int tdb1_brunlock(struct tdb_context *tdb,
int rw_type, tdb1_off_t offset, size_t len); int rw_type, tdb1_off_t offset, size_t len);
bool tdb1_have_extra_locks(struct tdb1_context *tdb); bool tdb1_have_extra_locks(struct tdb_context *tdb);
void tdb1_release_transaction_locks(struct tdb1_context *tdb); void tdb1_release_transaction_locks(struct tdb_context *tdb);
int tdb1_transaction_lock(struct tdb1_context *tdb, int ltype, int tdb1_transaction_lock(struct tdb_context *tdb, int ltype,
enum tdb_lock_flags lockflags); enum tdb_lock_flags lockflags);
int tdb1_transaction_unlock(struct tdb1_context *tdb, int ltype); int tdb1_transaction_unlock(struct tdb_context *tdb, int ltype);
int tdb1_recovery_area(struct tdb1_context *tdb, int tdb1_recovery_area(struct tdb_context *tdb,
const struct tdb1_methods *methods, const struct tdb1_methods *methods,
tdb1_off_t *recovery_offset, tdb1_off_t *recovery_offset,
struct tdb1_record *rec); struct tdb1_record *rec);
int tdb1_allrecord_lock(struct tdb1_context *tdb, int ltype, int tdb1_allrecord_lock(struct tdb_context *tdb, int ltype,
enum tdb_lock_flags flags, bool upgradable); enum tdb_lock_flags flags, bool upgradable);
int tdb1_allrecord_unlock(struct tdb1_context *tdb, int ltype); int tdb1_allrecord_unlock(struct tdb_context *tdb, int ltype);
int tdb1_allrecord_upgrade(struct tdb1_context *tdb); int tdb1_allrecord_upgrade(struct tdb_context *tdb);
int tdb1_write_lock_record(struct tdb1_context *tdb, tdb1_off_t off); int tdb1_write_lock_record(struct tdb_context *tdb, tdb1_off_t off);
int tdb1_write_unlock_record(struct tdb1_context *tdb, tdb1_off_t off); int tdb1_write_unlock_record(struct tdb_context *tdb, tdb1_off_t off);
int tdb1_ofs_read(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_off_t *d); int tdb1_ofs_read(struct tdb_context *tdb, tdb1_off_t offset, tdb1_off_t *d);
int tdb1_ofs_write(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_off_t *d); int tdb1_ofs_write(struct tdb_context *tdb, tdb1_off_t offset, tdb1_off_t *d);
void *tdb1_convert(void *buf, uint32_t size); void *tdb1_convert(void *buf, uint32_t size);
int tdb1_free(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_record *rec); int tdb1_free(struct tdb_context *tdb, tdb1_off_t offset, struct tdb1_record *rec);
tdb1_off_t tdb1_allocate(struct tdb1_context *tdb, tdb1_len_t length, struct tdb1_record *rec); tdb1_off_t tdb1_allocate(struct tdb_context *tdb, tdb1_len_t length, struct tdb1_record *rec);
int tdb1_ofs_read(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_off_t *d); int tdb1_ofs_read(struct tdb_context *tdb, tdb1_off_t offset, tdb1_off_t *d);
int tdb1_ofs_write(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_off_t *d); int tdb1_ofs_write(struct tdb_context *tdb, tdb1_off_t offset, tdb1_off_t *d);
int tdb1_lock_record(struct tdb1_context *tdb, tdb1_off_t off); int tdb1_lock_record(struct tdb_context *tdb, tdb1_off_t off);
int tdb1_unlock_record(struct tdb1_context *tdb, tdb1_off_t off); int tdb1_unlock_record(struct tdb_context *tdb, tdb1_off_t off);
bool tdb1_needs_recovery(struct tdb1_context *tdb); bool tdb1_needs_recovery(struct tdb_context *tdb);
int tdb1_rec_read(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_record *rec); int tdb1_rec_read(struct tdb_context *tdb, tdb1_off_t offset, struct tdb1_record *rec);
int tdb1_rec_write(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_record *rec); int tdb1_rec_write(struct tdb_context *tdb, tdb1_off_t offset, struct tdb1_record *rec);
int tdb1_do_delete(struct tdb1_context *tdb, tdb1_off_t rec_ptr, struct tdb1_record *rec); int tdb1_do_delete(struct tdb_context *tdb, tdb1_off_t rec_ptr, struct tdb1_record *rec);
unsigned char *tdb1_alloc_read(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_len_t len); unsigned char *tdb1_alloc_read(struct tdb_context *tdb, tdb1_off_t offset, tdb1_len_t len);
int tdb1_parse_data(struct tdb1_context *tdb, TDB_DATA key, int tdb1_parse_data(struct tdb_context *tdb, TDB_DATA key,
tdb1_off_t offset, tdb1_len_t len, tdb1_off_t offset, tdb1_len_t len,
int (*parser)(TDB_DATA key, TDB_DATA data, int (*parser)(TDB_DATA key, TDB_DATA data,
void *private_data), void *private_data),
void *private_data); void *private_data);
tdb1_off_t tdb1_find_lock_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t hash, int locktype, tdb1_off_t tdb1_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype,
struct tdb1_record *rec); struct tdb1_record *rec);
void tdb1_io_init(struct tdb1_context *tdb); void tdb1_io_init(struct tdb_context *tdb);
int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size); int tdb1_expand(struct tdb_context *tdb, tdb1_off_t size);
int tdb1_rec_free_read(struct tdb1_context *tdb, tdb1_off_t off, int tdb1_rec_free_read(struct tdb_context *tdb, tdb1_off_t off,
struct tdb1_record *rec); struct tdb1_record *rec);
bool tdb1_write_all(int fd, const void *buf, size_t count); bool tdb1_write_all(int fd, const void *buf, size_t count);
int tdb1_transaction_recover(struct tdb1_context *tdb); int tdb1_transaction_recover(struct tdb_context *tdb);
void tdb1_header_hash(struct tdb1_context *tdb, void tdb1_header_hash(struct tdb_context *tdb,
uint32_t *magic1_hash, uint32_t *magic2_hash); uint32_t *magic1_hash, uint32_t *magic2_hash);
uint64_t tdb1_old_hash(const void *key, size_t len, uint64_t seed, void *); uint64_t tdb1_old_hash(const void *key, size_t len, uint64_t seed, void *);
size_t tdb1_dead_space(struct tdb1_context *tdb, tdb1_off_t off); size_t tdb1_dead_space(struct tdb_context *tdb, tdb1_off_t off);
#endif /* CCAN_TDB2_TDB1_PRIVATE_H */ #endif /* CCAN_TDB2_TDB1_PRIVATE_H */
...@@ -65,7 +65,7 @@ static size_t tally1_mean(const struct tally *tally) ...@@ -65,7 +65,7 @@ static size_t tally1_mean(const struct tally *tally)
return tally->total / tally->num; return tally->total / tally->num;
} }
static size_t get_hash_length(struct tdb1_context *tdb, unsigned int i) static size_t get_hash_length(struct tdb_context *tdb, unsigned int i)
{ {
tdb1_off_t rec_ptr; tdb1_off_t rec_ptr;
size_t count = 0; size_t count = 0;
...@@ -84,7 +84,7 @@ static size_t get_hash_length(struct tdb1_context *tdb, unsigned int i) ...@@ -84,7 +84,7 @@ static size_t get_hash_length(struct tdb1_context *tdb, unsigned int i)
return count; return count;
} }
char *tdb1_summary(struct tdb1_context *tdb) char *tdb1_summary(struct tdb_context *tdb)
{ {
tdb1_off_t off, rec_off; tdb1_off_t off, rec_off;
struct tally freet, keys, data, dead, extra, hash, uncoal; struct tally freet, keys, data, dead, extra, hash, uncoal;
...@@ -103,7 +103,7 @@ char *tdb1_summary(struct tdb1_context *tdb) ...@@ -103,7 +103,7 @@ char *tdb1_summary(struct tdb1_context *tdb)
locked = true; locked = true;
} }
if (tdb1_recovery_area(tdb, tdb->methods, &rec_off, &recovery) != 0) { if (tdb1_recovery_area(tdb, tdb->tdb1.io, &rec_off, &recovery) != 0) {
goto unlock; goto unlock;
} }
...@@ -115,10 +115,10 @@ char *tdb1_summary(struct tdb1_context *tdb) ...@@ -115,10 +115,10 @@ char *tdb1_summary(struct tdb1_context *tdb)
tally1_init(&hash); tally1_init(&hash);
tally1_init(&uncoal); tally1_init(&uncoal);
for (off = TDB1_DATA_START(tdb->header.hash_size); for (off = TDB1_DATA_START(tdb->tdb1.header.hash_size);
off < tdb->file->map_size - 1; off < tdb->file->map_size - 1;
off += sizeof(rec) + rec.rec_len) { off += sizeof(rec) + rec.rec_len) {
if (tdb->methods->tdb1_read(tdb, off, &rec, sizeof(rec), if (tdb->tdb1.io->tdb1_read(tdb, off, &rec, sizeof(rec),
TDB1_DOCONV()) == -1) TDB1_DOCONV()) == -1)
goto unlock; goto unlock;
switch (rec.magic) { switch (rec.magic) {
...@@ -160,7 +160,7 @@ char *tdb1_summary(struct tdb1_context *tdb) ...@@ -160,7 +160,7 @@ char *tdb1_summary(struct tdb1_context *tdb)
if (unc > 1) if (unc > 1)
tally1_add(&uncoal, unc - 1); tally1_add(&uncoal, unc - 1);
for (off = 0; off < tdb->header.hash_size; off++) for (off = 0; off < tdb->tdb1.header.hash_size; off++)
tally1_add(&hash, get_hash_length(tdb, off)); tally1_add(&hash, get_hash_length(tdb, off));
/* 20 is max length of a %zu. */ /* 20 is max length of a %zu. */
...@@ -191,7 +191,7 @@ char *tdb1_summary(struct tdb1_context *tdb) ...@@ -191,7 +191,7 @@ char *tdb1_summary(struct tdb1_context *tdb)
(keys.num + freet.num + dead.num) (keys.num + freet.num + dead.num)
* (sizeof(struct tdb1_record) + sizeof(uint32_t)) * (sizeof(struct tdb1_record) + sizeof(uint32_t))
* 100.0 / tdb->file->map_size, * 100.0 / tdb->file->map_size,
tdb->header.hash_size * sizeof(tdb1_off_t) tdb->tdb1.header.hash_size * sizeof(tdb1_off_t)
* 100.0 / (tdb1_len_t)tdb->file->map_size); * 100.0 / (tdb1_len_t)tdb->file->map_size);
unlock: unlock:
......
...@@ -33,7 +33,7 @@ TDB_DATA tdb1_null; ...@@ -33,7 +33,7 @@ TDB_DATA tdb1_null;
non-blocking increment of the tdb sequence number if the tdb has been opened using non-blocking increment of the tdb sequence number if the tdb has been opened using
the TDB_SEQNUM flag the TDB_SEQNUM flag
*/ */
void tdb1_increment_seqnum_nonblock(struct tdb1_context *tdb) void tdb1_increment_seqnum_nonblock(struct tdb_context *tdb)
{ {
tdb1_off_t seqnum=0; tdb1_off_t seqnum=0;
...@@ -53,7 +53,7 @@ void tdb1_increment_seqnum_nonblock(struct tdb1_context *tdb) ...@@ -53,7 +53,7 @@ void tdb1_increment_seqnum_nonblock(struct tdb1_context *tdb)
increment the tdb sequence number if the tdb has been opened using increment the tdb sequence number if the tdb has been opened using
the TDB_SEQNUM flag the TDB_SEQNUM flag
*/ */
static void tdb1_increment_seqnum(struct tdb1_context *tdb) static void tdb1_increment_seqnum(struct tdb_context *tdb)
{ {
if (!(tdb->flags & TDB_SEQNUM)) { if (!(tdb->flags & TDB_SEQNUM)) {
return; return;
...@@ -76,7 +76,7 @@ static int tdb1_key_compare(TDB_DATA key, TDB_DATA data, void *private_data) ...@@ -76,7 +76,7 @@ static int tdb1_key_compare(TDB_DATA key, TDB_DATA data, void *private_data)
/* Returns 0 on fail. On success, return offset of record, and fills /* Returns 0 on fail. On success, return offset of record, and fills
in rec */ in rec */
static tdb1_off_t tdb1_find(struct tdb1_context *tdb, TDB_DATA key, uint32_t hash, static tdb1_off_t tdb1_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash,
struct tdb1_record *r) struct tdb1_record *r)
{ {
tdb1_off_t rec_ptr; tdb1_off_t rec_ptr;
...@@ -111,7 +111,7 @@ static tdb1_off_t tdb1_find(struct tdb1_context *tdb, TDB_DATA key, uint32_t has ...@@ -111,7 +111,7 @@ static tdb1_off_t tdb1_find(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
} }
/* As tdb1_find, but if you succeed, keep the lock */ /* As tdb1_find, but if you succeed, keep the lock */
tdb1_off_t tdb1_find_lock_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t hash, int locktype, tdb1_off_t tdb1_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype,
struct tdb1_record *rec) struct tdb1_record *rec)
{ {
uint32_t rec_ptr; uint32_t rec_ptr;
...@@ -123,13 +123,13 @@ tdb1_off_t tdb1_find_lock_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t ...@@ -123,13 +123,13 @@ tdb1_off_t tdb1_find_lock_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t
return rec_ptr; return rec_ptr;
} }
static TDB_DATA _tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key); static TDB_DATA _tdb1_fetch(struct tdb_context *tdb, TDB_DATA key);
/* update an entry in place - this only works if the new data size /* update an entry in place - this only works if the new data size
is <= the old data size and the key exists. is <= the old data size and the key exists.
on failure return -1. on failure return -1.
*/ */
static int tdb1_update_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t hash, TDB_DATA dbuf) static int tdb1_update_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, TDB_DATA dbuf)
{ {
struct tdb1_record rec; struct tdb1_record rec;
tdb1_off_t rec_ptr; tdb1_off_t rec_ptr;
...@@ -162,7 +162,7 @@ static int tdb1_update_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has ...@@ -162,7 +162,7 @@ static int tdb1_update_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
return -1; return -1;
} }
if (tdb->methods->tdb1_write(tdb, rec_ptr + sizeof(rec) + rec.key_len, if (tdb->tdb1.io->tdb1_write(tdb, rec_ptr + sizeof(rec) + rec.key_len,
dbuf.dptr, dbuf.dsize) == -1) dbuf.dptr, dbuf.dsize) == -1)
return -1; return -1;
...@@ -181,7 +181,7 @@ static int tdb1_update_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has ...@@ -181,7 +181,7 @@ static int tdb1_update_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
* then the TDB_DATA will have zero length but * then the TDB_DATA will have zero length but
* a non-zero pointer * a non-zero pointer
*/ */
static TDB_DATA _tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key) static TDB_DATA _tdb1_fetch(struct tdb_context *tdb, TDB_DATA key)
{ {
tdb1_off_t rec_ptr; tdb1_off_t rec_ptr;
struct tdb1_record rec; struct tdb1_record rec;
...@@ -200,7 +200,7 @@ static TDB_DATA _tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key) ...@@ -200,7 +200,7 @@ static TDB_DATA _tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key)
return ret; return ret;
} }
TDB_DATA tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key) TDB_DATA tdb1_fetch(struct tdb_context *tdb, TDB_DATA key)
{ {
TDB_DATA ret = _tdb1_fetch(tdb, key); TDB_DATA ret = _tdb1_fetch(tdb, key);
...@@ -225,7 +225,7 @@ TDB_DATA tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key) ...@@ -225,7 +225,7 @@ TDB_DATA tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key)
* Return -1 if the record was not found. * Return -1 if the record was not found.
*/ */
int tdb1_parse_record(struct tdb1_context *tdb, TDB_DATA key, int tdb1_parse_record(struct tdb_context *tdb, TDB_DATA key,
int (*parser)(TDB_DATA key, TDB_DATA data, int (*parser)(TDB_DATA key, TDB_DATA data,
void *private_data), void *private_data),
void *private_data) void *private_data)
...@@ -258,7 +258,7 @@ int tdb1_parse_record(struct tdb1_context *tdb, TDB_DATA key, ...@@ -258,7 +258,7 @@ int tdb1_parse_record(struct tdb1_context *tdb, TDB_DATA key,
this doesn't match the conventions in the rest of this module, but is this doesn't match the conventions in the rest of this module, but is
compatible with gdbm compatible with gdbm
*/ */
static int tdb1_exists_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t hash) static int tdb1_exists_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash)
{ {
struct tdb1_record rec; struct tdb1_record rec;
...@@ -268,7 +268,7 @@ static int tdb1_exists_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has ...@@ -268,7 +268,7 @@ static int tdb1_exists_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
return 1; return 1;
} }
int tdb1_exists(struct tdb1_context *tdb, TDB_DATA key) int tdb1_exists(struct tdb_context *tdb, TDB_DATA key)
{ {
uint32_t hash = tdb_hash(tdb, key.dptr, key.dsize); uint32_t hash = tdb_hash(tdb, key.dptr, key.dsize);
int ret; int ret;
...@@ -278,14 +278,14 @@ int tdb1_exists(struct tdb1_context *tdb, TDB_DATA key) ...@@ -278,14 +278,14 @@ int tdb1_exists(struct tdb1_context *tdb, TDB_DATA key)
} }
/* actually delete an entry in the database given the offset */ /* actually delete an entry in the database given the offset */
int tdb1_do_delete(struct tdb1_context *tdb, tdb1_off_t rec_ptr, struct tdb1_record *rec) int tdb1_do_delete(struct tdb_context *tdb, tdb1_off_t rec_ptr, struct tdb1_record *rec)
{ {
tdb1_off_t last_ptr, i; tdb1_off_t last_ptr, i;
struct tdb1_record lastrec; struct tdb1_record lastrec;
if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) return -1; if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) return -1;
if (((tdb->traverse_write != 0) && (!TDB1_DEAD(rec))) || if (((tdb->tdb1.traverse_write != 0) && (!TDB1_DEAD(rec))) ||
tdb1_write_lock_record(tdb, rec_ptr) == -1) { tdb1_write_lock_record(tdb, rec_ptr) == -1) {
/* Someone traversing here: mark it as dead */ /* Someone traversing here: mark it as dead */
rec->magic = TDB1_DEAD_MAGIC; rec->magic = TDB1_DEAD_MAGIC;
...@@ -313,7 +313,7 @@ int tdb1_do_delete(struct tdb1_context *tdb, tdb1_off_t rec_ptr, struct tdb1_rec ...@@ -313,7 +313,7 @@ int tdb1_do_delete(struct tdb1_context *tdb, tdb1_off_t rec_ptr, struct tdb1_rec
return 0; return 0;
} }
static int tdb1_count_dead(struct tdb1_context *tdb, uint32_t hash) static int tdb1_count_dead(struct tdb_context *tdb, uint32_t hash)
{ {
int res = 0; int res = 0;
tdb1_off_t rec_ptr; tdb1_off_t rec_ptr;
...@@ -338,7 +338,7 @@ static int tdb1_count_dead(struct tdb1_context *tdb, uint32_t hash) ...@@ -338,7 +338,7 @@ static int tdb1_count_dead(struct tdb1_context *tdb, uint32_t hash)
/* /*
* Purge all DEAD records from a hash chain * Purge all DEAD records from a hash chain
*/ */
static int tdb1_purge_dead(struct tdb1_context *tdb, uint32_t hash) static int tdb1_purge_dead(struct tdb_context *tdb, uint32_t hash)
{ {
int res = -1; int res = -1;
struct tdb1_record rec; struct tdb1_record rec;
...@@ -374,13 +374,13 @@ static int tdb1_purge_dead(struct tdb1_context *tdb, uint32_t hash) ...@@ -374,13 +374,13 @@ static int tdb1_purge_dead(struct tdb1_context *tdb, uint32_t hash)
} }
/* delete an entry in the database given a key */ /* delete an entry in the database given a key */
static int tdb1_delete_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t hash) static int tdb1_delete_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash)
{ {
tdb1_off_t rec_ptr; tdb1_off_t rec_ptr;
struct tdb1_record rec; struct tdb1_record rec;
int ret; int ret;
if (tdb->max_dead_records != 0) { if (tdb->tdb1.max_dead_records != 0) {
/* /*
* Allow for some dead records per hash chain, mainly for * Allow for some dead records per hash chain, mainly for
...@@ -390,7 +390,7 @@ static int tdb1_delete_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has ...@@ -390,7 +390,7 @@ static int tdb1_delete_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
if (tdb1_lock(tdb, TDB1_BUCKET(hash), F_WRLCK) == -1) if (tdb1_lock(tdb, TDB1_BUCKET(hash), F_WRLCK) == -1)
return -1; return -1;
if (tdb1_count_dead(tdb, hash) >= tdb->max_dead_records) { if (tdb1_count_dead(tdb, hash) >= tdb->tdb1.max_dead_records) {
/* /*
* Don't let the per-chain freelist grow too large, * Don't let the per-chain freelist grow too large,
* delete all existing dead records * delete all existing dead records
...@@ -427,7 +427,7 @@ static int tdb1_delete_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has ...@@ -427,7 +427,7 @@ static int tdb1_delete_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
return ret; return ret;
} }
int tdb1_delete(struct tdb1_context *tdb, TDB_DATA key) int tdb1_delete(struct tdb_context *tdb, TDB_DATA key)
{ {
uint32_t hash = tdb_hash(tdb, key.dptr, key.dsize); uint32_t hash = tdb_hash(tdb, key.dptr, key.dsize);
int ret; int ret;
...@@ -439,7 +439,7 @@ int tdb1_delete(struct tdb1_context *tdb, TDB_DATA key) ...@@ -439,7 +439,7 @@ int tdb1_delete(struct tdb1_context *tdb, TDB_DATA key)
/* /*
* See if we have a dead record around with enough space * See if we have a dead record around with enough space
*/ */
static tdb1_off_t tdb1_find_dead(struct tdb1_context *tdb, uint32_t hash, static tdb1_off_t tdb1_find_dead(struct tdb_context *tdb, uint32_t hash,
struct tdb1_record *r, tdb1_len_t length) struct tdb1_record *r, tdb1_len_t length)
{ {
tdb1_off_t rec_ptr; tdb1_off_t rec_ptr;
...@@ -465,7 +465,7 @@ static tdb1_off_t tdb1_find_dead(struct tdb1_context *tdb, uint32_t hash, ...@@ -465,7 +465,7 @@ static tdb1_off_t tdb1_find_dead(struct tdb1_context *tdb, uint32_t hash,
return 0; return 0;
} }
static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key, static int _tdb1_store(struct tdb_context *tdb, TDB_DATA key,
TDB_DATA dbuf, int flag, uint32_t hash) TDB_DATA dbuf, int flag, uint32_t hash)
{ {
struct tdb1_record rec; struct tdb1_record rec;
...@@ -512,7 +512,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key, ...@@ -512,7 +512,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
if (dbuf.dsize) if (dbuf.dsize)
memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize); memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize);
if (tdb->max_dead_records != 0) { if (tdb->tdb1.max_dead_records != 0) {
/* /*
* Allow for some dead records per hash chain, look if we can * Allow for some dead records per hash chain, look if we can
* find one that can hold the new record. We need enough space * find one that can hold the new record. We need enough space
...@@ -529,7 +529,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key, ...@@ -529,7 +529,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
rec.full_hash = hash; rec.full_hash = hash;
rec.magic = TDB1_MAGIC; rec.magic = TDB1_MAGIC;
if (tdb1_rec_write(tdb, rec_ptr, &rec) == -1 if (tdb1_rec_write(tdb, rec_ptr, &rec) == -1
|| tdb->methods->tdb1_write( || tdb->tdb1.io->tdb1_write(
tdb, rec_ptr + sizeof(rec), tdb, rec_ptr + sizeof(rec),
p, key.dsize + dbuf.dsize) == -1) { p, key.dsize + dbuf.dsize) == -1) {
goto fail; goto fail;
...@@ -548,7 +548,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key, ...@@ -548,7 +548,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
goto fail; goto fail;
} }
if ((tdb->max_dead_records != 0) if ((tdb->tdb1.max_dead_records != 0)
&& (tdb1_purge_dead(tdb, hash) == -1)) { && (tdb1_purge_dead(tdb, hash) == -1)) {
tdb1_unlock(tdb, -1, F_WRLCK); tdb1_unlock(tdb, -1, F_WRLCK);
goto fail; goto fail;
...@@ -574,7 +574,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key, ...@@ -574,7 +574,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
/* write out and point the top of the hash chain at it */ /* write out and point the top of the hash chain at it */
if (tdb1_rec_write(tdb, rec_ptr, &rec) == -1 if (tdb1_rec_write(tdb, rec_ptr, &rec) == -1
|| tdb->methods->tdb1_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1 || tdb->tdb1.io->tdb1_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1
|| tdb1_ofs_write(tdb, TDB1_HASH_TOP(hash), &rec_ptr) == -1) { || tdb1_ofs_write(tdb, TDB1_HASH_TOP(hash), &rec_ptr) == -1) {
/* Need to tdb1_unallocate() here */ /* Need to tdb1_unallocate() here */
goto fail; goto fail;
...@@ -596,12 +596,12 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key, ...@@ -596,12 +596,12 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
return 0 on success, -1 on failure return 0 on success, -1 on failure
*/ */
int tdb1_store(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) int tdb1_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
{ {
uint32_t hash; uint32_t hash;
int ret; int ret;
if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) { if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) {
tdb->last_error = TDB_ERR_RDONLY; tdb->last_error = TDB_ERR_RDONLY;
return -1; return -1;
} }
...@@ -617,7 +617,7 @@ int tdb1_store(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) ...@@ -617,7 +617,7 @@ int tdb1_store(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
} }
/* Append to an entry. Create if not exist. */ /* Append to an entry. Create if not exist. */
int tdb1_append(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA new_dbuf) int tdb1_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf)
{ {
uint32_t hash; uint32_t hash;
TDB_DATA dbuf; TDB_DATA dbuf;
...@@ -673,7 +673,7 @@ failed: ...@@ -673,7 +673,7 @@ failed:
The aim of this sequence number is to allow for a very lightweight The aim of this sequence number is to allow for a very lightweight
test of a possible tdb change. test of a possible tdb change.
*/ */
int tdb1_get_seqnum(struct tdb1_context *tdb) int tdb1_get_seqnum(struct tdb_context *tdb)
{ {
tdb1_off_t seqnum=0; tdb1_off_t seqnum=0;
...@@ -681,9 +681,9 @@ int tdb1_get_seqnum(struct tdb1_context *tdb) ...@@ -681,9 +681,9 @@ int tdb1_get_seqnum(struct tdb1_context *tdb)
return seqnum; return seqnum;
} }
int tdb1_hash_size(struct tdb1_context *tdb) int tdb1_hash_size(struct tdb_context *tdb)
{ {
return tdb->header.hash_size; return tdb->tdb1.header.hash_size;
} }
...@@ -691,7 +691,7 @@ int tdb1_hash_size(struct tdb1_context *tdb) ...@@ -691,7 +691,7 @@ int tdb1_hash_size(struct tdb1_context *tdb)
add a region of the file to the freelist. Length is the size of the region in bytes, add a region of the file to the freelist. Length is the size of the region in bytes,
which includes the free list header that needs to be added which includes the free list header that needs to be added
*/ */
static int tdb1_free_region(struct tdb1_context *tdb, tdb1_off_t offset, ssize_t length) static int tdb1_free_region(struct tdb_context *tdb, tdb1_off_t offset, ssize_t length)
{ {
struct tdb1_record rec; struct tdb1_record rec;
if (length <= sizeof(rec)) { if (length <= sizeof(rec)) {
...@@ -721,7 +721,7 @@ static int tdb1_free_region(struct tdb1_context *tdb, tdb1_off_t offset, ssize_t ...@@ -721,7 +721,7 @@ static int tdb1_free_region(struct tdb1_context *tdb, tdb1_off_t offset, ssize_t
This code carefully steps around the recovery area, leaving it alone This code carefully steps around the recovery area, leaving it alone
*/ */
int tdb1_wipe_all(struct tdb1_context *tdb) int tdb1_wipe_all(struct tdb_context *tdb)
{ {
int i; int i;
tdb1_off_t offset = 0; tdb1_off_t offset = 0;
...@@ -746,7 +746,7 @@ int tdb1_wipe_all(struct tdb1_context *tdb) ...@@ -746,7 +746,7 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
if (recovery_head != 0) { if (recovery_head != 0) {
struct tdb1_record rec; struct tdb1_record rec;
if (tdb->methods->tdb1_read(tdb, recovery_head, &rec, sizeof(rec), TDB1_DOCONV()) == -1) { if (tdb->tdb1.io->tdb1_read(tdb, recovery_head, &rec, sizeof(rec), TDB1_DOCONV()) == -1) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_wipe_all: failed to read recovery record"); "tdb1_wipe_all: failed to read recovery record");
return -1; return -1;
...@@ -755,7 +755,7 @@ int tdb1_wipe_all(struct tdb1_context *tdb) ...@@ -755,7 +755,7 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
} }
/* wipe the hashes */ /* wipe the hashes */
for (i=0;i<tdb->header.hash_size;i++) { for (i=0;i<tdb->tdb1.header.hash_size;i++) {
if (tdb1_ofs_write(tdb, TDB1_HASH_TOP(i), &offset) == -1) { if (tdb1_ofs_write(tdb, TDB1_HASH_TOP(i), &offset) == -1) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_wipe_all: failed to write hash %d", i); "tdb1_wipe_all: failed to write hash %d", i);
...@@ -774,8 +774,8 @@ int tdb1_wipe_all(struct tdb1_context *tdb) ...@@ -774,8 +774,8 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
for the recovery area */ for the recovery area */
if (recovery_size == 0) { if (recovery_size == 0) {
/* the simple case - the whole file can be used as a freelist */ /* the simple case - the whole file can be used as a freelist */
data_len = (tdb->file->map_size - TDB1_DATA_START(tdb->header.hash_size)); data_len = (tdb->file->map_size - TDB1_DATA_START(tdb->tdb1.header.hash_size));
if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->header.hash_size), data_len) != 0) { if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->tdb1.header.hash_size), data_len) != 0) {
goto failed; goto failed;
} }
} else { } else {
...@@ -787,8 +787,8 @@ int tdb1_wipe_all(struct tdb1_context *tdb) ...@@ -787,8 +787,8 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
move the recovery area or we risk subtle data move the recovery area or we risk subtle data
corruption corruption
*/ */
data_len = (recovery_head - TDB1_DATA_START(tdb->header.hash_size)); data_len = (recovery_head - TDB1_DATA_START(tdb->tdb1.header.hash_size));
if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->header.hash_size), data_len) != 0) { if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->tdb1.header.hash_size), data_len) != 0) {
goto failed; goto failed;
} }
/* and the 2nd free list entry after the recovery area - if any */ /* and the 2nd free list entry after the recovery area - if any */
...@@ -813,13 +813,13 @@ failed: ...@@ -813,13 +813,13 @@ failed:
struct traverse_state { struct traverse_state {
enum TDB_ERROR error; enum TDB_ERROR error;
struct tdb1_context *dest_db; struct tdb_context *dest_db;
}; };
/* /*
traverse function for repacking traverse function for repacking
*/ */
static int repack_traverse(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data) static int repack_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data)
{ {
struct traverse_state *state = (struct traverse_state *)private_data; struct traverse_state *state = (struct traverse_state *)private_data;
if (tdb1_store(state->dest_db, key, data, TDB_INSERT) != 0) { if (tdb1_store(state->dest_db, key, data, TDB_INSERT) != 0) {
...@@ -832,9 +832,9 @@ static int repack_traverse(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data ...@@ -832,9 +832,9 @@ static int repack_traverse(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data
/* /*
repack a tdb repack a tdb
*/ */
int tdb1_repack(struct tdb1_context *tdb) int tdb1_repack(struct tdb_context *tdb)
{ {
struct tdb1_context *tmp_db; struct tdb_context *tmp_db;
struct traverse_state state; struct traverse_state state;
if (tdb1_transaction_start(tdb) != 0) { if (tdb1_transaction_start(tdb) != 0) {
......
...@@ -138,14 +138,14 @@ struct tdb1_transaction { ...@@ -138,14 +138,14 @@ struct tdb1_transaction {
read while in a transaction. We need to check first if the data is in our list read while in a transaction. We need to check first if the data is in our list
of transaction elements, then if not do a real read of transaction elements, then if not do a real read
*/ */
static int transaction1_read(struct tdb1_context *tdb, tdb1_off_t off, void *buf, static int transaction1_read(struct tdb_context *tdb, tdb1_off_t off, void *buf,
tdb1_len_t len, int cv) tdb1_len_t len, int cv)
{ {
uint32_t blk; uint32_t blk;
/* break it down into block sized ops */ /* break it down into block sized ops */
while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { while (len + (off % tdb->tdb1.transaction->block_size) > tdb->tdb1.transaction->block_size) {
tdb1_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); tdb1_len_t len2 = tdb->tdb1.transaction->block_size - (off % tdb->tdb1.transaction->block_size);
if (transaction1_read(tdb, off, buf, len2, cv) != 0) { if (transaction1_read(tdb, off, buf, len2, cv) != 0) {
return -1; return -1;
} }
...@@ -158,27 +158,27 @@ static int transaction1_read(struct tdb1_context *tdb, tdb1_off_t off, void *buf ...@@ -158,27 +158,27 @@ static int transaction1_read(struct tdb1_context *tdb, tdb1_off_t off, void *buf
return 0; return 0;
} }
blk = off / tdb->transaction->block_size; blk = off / tdb->tdb1.transaction->block_size;
/* see if we have it in the block list */ /* see if we have it in the block list */
if (tdb->transaction->num_blocks <= blk || if (tdb->tdb1.transaction->num_blocks <= blk ||
tdb->transaction->blocks[blk] == NULL) { tdb->tdb1.transaction->blocks[blk] == NULL) {
/* nope, do a real read */ /* nope, do a real read */
if (tdb->transaction->io_methods->tdb1_read(tdb, off, buf, len, cv) != 0) { if (tdb->tdb1.transaction->io_methods->tdb1_read(tdb, off, buf, len, cv) != 0) {
goto fail; goto fail;
} }
return 0; return 0;
} }
/* it is in the block list. Now check for the last block */ /* it is in the block list. Now check for the last block */
if (blk == tdb->transaction->num_blocks-1) { if (blk == tdb->tdb1.transaction->num_blocks-1) {
if (len > tdb->transaction->last_block_size) { if (len > tdb->tdb1.transaction->last_block_size) {
goto fail; goto fail;
} }
} }
/* now copy it out of this block */ /* now copy it out of this block */
memcpy(buf, tdb->transaction->blocks[blk] + (off % tdb->transaction->block_size), len); memcpy(buf, tdb->tdb1.transaction->blocks[blk] + (off % tdb->tdb1.transaction->block_size), len);
if (cv) { if (cv) {
tdb1_convert(buf, len); tdb1_convert(buf, len);
} }
...@@ -188,7 +188,7 @@ fail: ...@@ -188,7 +188,7 @@ fail:
tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR,
"transaction_read: failed at off=%d len=%d", "transaction_read: failed at off=%d len=%d",
off, len); off, len);
tdb->transaction->transaction_error = 1; tdb->tdb1.transaction->transaction_error = 1;
return -1; return -1;
} }
...@@ -196,17 +196,17 @@ fail: ...@@ -196,17 +196,17 @@ fail:
/* /*
write while in a transaction write while in a transaction
*/ */
static int transaction1_write(struct tdb1_context *tdb, tdb1_off_t off, static int transaction1_write(struct tdb_context *tdb, tdb1_off_t off,
const void *buf, tdb1_len_t len) const void *buf, tdb1_len_t len)
{ {
uint32_t blk; uint32_t blk;
/* Only a commit is allowed on a prepared transaction */ /* Only a commit is allowed on a prepared transaction */
if (tdb->transaction->prepared) { if (tdb->tdb1.transaction->prepared) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"transaction_write: transaction already" "transaction_write: transaction already"
" prepared, write not allowed"); " prepared, write not allowed");
tdb->transaction->transaction_error = 1; tdb->tdb1.transaction->transaction_error = 1;
return -1; return -1;
} }
...@@ -215,12 +215,12 @@ static int transaction1_write(struct tdb1_context *tdb, tdb1_off_t off, ...@@ -215,12 +215,12 @@ static int transaction1_write(struct tdb1_context *tdb, tdb1_off_t off,
if (len == sizeof(tdb1_off_t) && off >= TDB1_FREELIST_TOP && if (len == sizeof(tdb1_off_t) && off >= TDB1_FREELIST_TOP &&
off < TDB1_FREELIST_TOP+TDB1_HASHTABLE_SIZE(tdb)) { off < TDB1_FREELIST_TOP+TDB1_HASHTABLE_SIZE(tdb)) {
uint32_t chain = (off-TDB1_FREELIST_TOP) / sizeof(tdb1_off_t); uint32_t chain = (off-TDB1_FREELIST_TOP) / sizeof(tdb1_off_t);
memcpy(&tdb->transaction->hash_heads[chain], buf, len); memcpy(&tdb->tdb1.transaction->hash_heads[chain], buf, len);
} }
/* break it up into block sized chunks */ /* break it up into block sized chunks */
while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { while (len + (off % tdb->tdb1.transaction->block_size) > tdb->tdb1.transaction->block_size) {
tdb1_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); tdb1_len_t len2 = tdb->tdb1.transaction->block_size - (off % tdb->tdb1.transaction->block_size);
if (transaction1_write(tdb, off, buf, len2) != 0) { if (transaction1_write(tdb, off, buf, len2) != 0) {
return -1; return -1;
} }
...@@ -235,66 +235,66 @@ static int transaction1_write(struct tdb1_context *tdb, tdb1_off_t off, ...@@ -235,66 +235,66 @@ static int transaction1_write(struct tdb1_context *tdb, tdb1_off_t off,
return 0; return 0;
} }
blk = off / tdb->transaction->block_size; blk = off / tdb->tdb1.transaction->block_size;
off = off % tdb->transaction->block_size; off = off % tdb->tdb1.transaction->block_size;
if (tdb->transaction->num_blocks <= blk) { if (tdb->tdb1.transaction->num_blocks <= blk) {
uint8_t **new_blocks; uint8_t **new_blocks;
/* expand the blocks array */ /* expand the blocks array */
if (tdb->transaction->blocks == NULL) { if (tdb->tdb1.transaction->blocks == NULL) {
new_blocks = (uint8_t **)malloc( new_blocks = (uint8_t **)malloc(
(blk+1)*sizeof(uint8_t *)); (blk+1)*sizeof(uint8_t *));
} else { } else {
new_blocks = (uint8_t **)realloc( new_blocks = (uint8_t **)realloc(
tdb->transaction->blocks, tdb->tdb1.transaction->blocks,
(blk+1)*sizeof(uint8_t *)); (blk+1)*sizeof(uint8_t *));
} }
if (new_blocks == NULL) { if (new_blocks == NULL) {
tdb->last_error = TDB_ERR_OOM; tdb->last_error = TDB_ERR_OOM;
goto fail; goto fail;
} }
memset(&new_blocks[tdb->transaction->num_blocks], 0, memset(&new_blocks[tdb->tdb1.transaction->num_blocks], 0,
(1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *)); (1+(blk - tdb->tdb1.transaction->num_blocks))*sizeof(uint8_t *));
tdb->transaction->blocks = new_blocks; tdb->tdb1.transaction->blocks = new_blocks;
tdb->transaction->num_blocks = blk+1; tdb->tdb1.transaction->num_blocks = blk+1;
tdb->transaction->last_block_size = 0; tdb->tdb1.transaction->last_block_size = 0;
} }
/* allocate and fill a block? */ /* allocate and fill a block? */
if (tdb->transaction->blocks[blk] == NULL) { if (tdb->tdb1.transaction->blocks[blk] == NULL) {
tdb->transaction->blocks[blk] = (uint8_t *)calloc(tdb->transaction->block_size, 1); tdb->tdb1.transaction->blocks[blk] = (uint8_t *)calloc(tdb->tdb1.transaction->block_size, 1);
if (tdb->transaction->blocks[blk] == NULL) { if (tdb->tdb1.transaction->blocks[blk] == NULL) {
tdb->last_error = TDB_ERR_OOM; tdb->last_error = TDB_ERR_OOM;
tdb->transaction->transaction_error = 1; tdb->tdb1.transaction->transaction_error = 1;
return -1; return -1;
} }
if (tdb->transaction->old_map_size > blk * tdb->transaction->block_size) { if (tdb->tdb1.transaction->old_map_size > blk * tdb->tdb1.transaction->block_size) {
tdb1_len_t len2 = tdb->transaction->block_size; tdb1_len_t len2 = tdb->tdb1.transaction->block_size;
if (len2 + (blk * tdb->transaction->block_size) > tdb->transaction->old_map_size) { if (len2 + (blk * tdb->tdb1.transaction->block_size) > tdb->tdb1.transaction->old_map_size) {
len2 = tdb->transaction->old_map_size - (blk * tdb->transaction->block_size); len2 = tdb->tdb1.transaction->old_map_size - (blk * tdb->tdb1.transaction->block_size);
} }
if (tdb->transaction->io_methods->tdb1_read(tdb, blk * tdb->transaction->block_size, if (tdb->tdb1.transaction->io_methods->tdb1_read(tdb, blk * tdb->tdb1.transaction->block_size,
tdb->transaction->blocks[blk], tdb->tdb1.transaction->blocks[blk],
len2, 0) != 0) { len2, 0) != 0) {
SAFE_FREE(tdb->transaction->blocks[blk]); SAFE_FREE(tdb->tdb1.transaction->blocks[blk]);
tdb->last_error = TDB_ERR_IO; tdb->last_error = TDB_ERR_IO;
goto fail; goto fail;
} }
if (blk == tdb->transaction->num_blocks-1) { if (blk == tdb->tdb1.transaction->num_blocks-1) {
tdb->transaction->last_block_size = len2; tdb->tdb1.transaction->last_block_size = len2;
} }
} }
} }
/* overwrite part of an existing block */ /* overwrite part of an existing block */
if (buf == NULL) { if (buf == NULL) {
memset(tdb->transaction->blocks[blk] + off, 0, len); memset(tdb->tdb1.transaction->blocks[blk] + off, 0, len);
} else { } else {
memcpy(tdb->transaction->blocks[blk] + off, buf, len); memcpy(tdb->tdb1.transaction->blocks[blk] + off, buf, len);
} }
if (blk == tdb->transaction->num_blocks-1) { if (blk == tdb->tdb1.transaction->num_blocks-1) {
if (len + off > tdb->transaction->last_block_size) { if (len + off > tdb->tdb1.transaction->last_block_size) {
tdb->transaction->last_block_size = len + off; tdb->tdb1.transaction->last_block_size = len + off;
} }
} }
...@@ -303,8 +303,8 @@ static int transaction1_write(struct tdb1_context *tdb, tdb1_off_t off, ...@@ -303,8 +303,8 @@ static int transaction1_write(struct tdb1_context *tdb, tdb1_off_t off,
fail: fail:
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"transaction_write: failed at off=%d len=%d", "transaction_write: failed at off=%d len=%d",
(blk*tdb->transaction->block_size) + off, len); (blk*tdb->tdb1.transaction->block_size) + off, len);
tdb->transaction->transaction_error = 1; tdb->tdb1.transaction->transaction_error = 1;
return -1; return -1;
} }
...@@ -313,14 +313,14 @@ fail: ...@@ -313,14 +313,14 @@ fail:
write while in a transaction - this varient never expands the transaction blocks, it only write while in a transaction - this varient never expands the transaction blocks, it only
updates existing blocks. This means it cannot change the recovery size updates existing blocks. This means it cannot change the recovery size
*/ */
static int transaction1_write_existing(struct tdb1_context *tdb, tdb1_off_t off, static int transaction1_write_existing(struct tdb_context *tdb, tdb1_off_t off,
const void *buf, tdb1_len_t len) const void *buf, tdb1_len_t len)
{ {
uint32_t blk; uint32_t blk;
/* break it up into block sized chunks */ /* break it up into block sized chunks */
while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { while (len + (off % tdb->tdb1.transaction->block_size) > tdb->tdb1.transaction->block_size) {
tdb1_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); tdb1_len_t len2 = tdb->tdb1.transaction->block_size - (off % tdb->tdb1.transaction->block_size);
if (transaction1_write_existing(tdb, off, buf, len2) != 0) { if (transaction1_write_existing(tdb, off, buf, len2) != 0) {
return -1; return -1;
} }
...@@ -335,24 +335,24 @@ static int transaction1_write_existing(struct tdb1_context *tdb, tdb1_off_t off, ...@@ -335,24 +335,24 @@ static int transaction1_write_existing(struct tdb1_context *tdb, tdb1_off_t off,
return 0; return 0;
} }
blk = off / tdb->transaction->block_size; blk = off / tdb->tdb1.transaction->block_size;
off = off % tdb->transaction->block_size; off = off % tdb->tdb1.transaction->block_size;
if (tdb->transaction->num_blocks <= blk || if (tdb->tdb1.transaction->num_blocks <= blk ||
tdb->transaction->blocks[blk] == NULL) { tdb->tdb1.transaction->blocks[blk] == NULL) {
return 0; return 0;
} }
if (blk == tdb->transaction->num_blocks-1 && if (blk == tdb->tdb1.transaction->num_blocks-1 &&
off + len > tdb->transaction->last_block_size) { off + len > tdb->tdb1.transaction->last_block_size) {
if (off >= tdb->transaction->last_block_size) { if (off >= tdb->tdb1.transaction->last_block_size) {
return 0; return 0;
} }
len = tdb->transaction->last_block_size - off; len = tdb->tdb1.transaction->last_block_size - off;
} }
/* overwrite part of an existing block */ /* overwrite part of an existing block */
memcpy(tdb->transaction->blocks[blk] + off, buf, len); memcpy(tdb->tdb1.transaction->blocks[blk] + off, buf, len);
return 0; return 0;
} }
...@@ -361,12 +361,12 @@ static int transaction1_write_existing(struct tdb1_context *tdb, tdb1_off_t off, ...@@ -361,12 +361,12 @@ static int transaction1_write_existing(struct tdb1_context *tdb, tdb1_off_t off,
/* /*
accelerated hash chain head search, using the cached hash heads accelerated hash chain head search, using the cached hash heads
*/ */
static void transaction1_next_hash_chain(struct tdb1_context *tdb, uint32_t *chain) static void transaction1_next_hash_chain(struct tdb_context *tdb, uint32_t *chain)
{ {
uint32_t h = *chain; uint32_t h = *chain;
for (;h < tdb->header.hash_size;h++) { for (;h < tdb->tdb1.header.hash_size;h++) {
/* the +1 takes account of the freelist */ /* the +1 takes account of the freelist */
if (0 != tdb->transaction->hash_heads[h+1]) { if (0 != tdb->tdb1.transaction->hash_heads[h+1]) {
break; break;
} }
} }
...@@ -376,7 +376,7 @@ static void transaction1_next_hash_chain(struct tdb1_context *tdb, uint32_t *cha ...@@ -376,7 +376,7 @@ static void transaction1_next_hash_chain(struct tdb1_context *tdb, uint32_t *cha
/* /*
out of bounds check during a transaction out of bounds check during a transaction
*/ */
static int transaction1_oob(struct tdb1_context *tdb, tdb1_off_t len, int probe) static int transaction1_oob(struct tdb_context *tdb, tdb1_off_t len, int probe)
{ {
if (len <= tdb->file->map_size) { if (len <= tdb->file->map_size) {
return 0; return 0;
...@@ -388,7 +388,7 @@ static int transaction1_oob(struct tdb1_context *tdb, tdb1_off_t len, int probe) ...@@ -388,7 +388,7 @@ static int transaction1_oob(struct tdb1_context *tdb, tdb1_off_t len, int probe)
/* /*
transaction version of tdb1_expand(). transaction version of tdb1_expand().
*/ */
static int transaction1_expand_file(struct tdb1_context *tdb, tdb1_off_t size, static int transaction1_expand_file(struct tdb_context *tdb, tdb1_off_t size,
tdb1_off_t addition) tdb1_off_t addition)
{ {
/* add a write to the transaction elements, so subsequent /* add a write to the transaction elements, so subsequent
...@@ -397,7 +397,7 @@ static int transaction1_expand_file(struct tdb1_context *tdb, tdb1_off_t size, ...@@ -397,7 +397,7 @@ static int transaction1_expand_file(struct tdb1_context *tdb, tdb1_off_t size,
return -1; return -1;
} }
tdb->transaction->expanded = true; tdb->tdb1.transaction->expanded = true;
return 0; return 0;
} }
...@@ -413,12 +413,12 @@ static const struct tdb1_methods transaction1_methods = { ...@@ -413,12 +413,12 @@ static const struct tdb1_methods transaction1_methods = {
/* /*
start a tdb transaction. No token is returned, as only a single start a tdb transaction. No token is returned, as only a single
transaction is allowed to be pending per tdb1_context transaction is allowed to be pending per tdb_context
*/ */
static int _tdb1_transaction_start(struct tdb1_context *tdb) static int _tdb1_transaction_start(struct tdb_context *tdb)
{ {
/* some sanity checks */ /* some sanity checks */
if ((tdb->flags & TDB_RDONLY) || (tdb->flags & TDB_INTERNAL) || tdb->traverse_read) { if ((tdb->flags & TDB_RDONLY) || (tdb->flags & TDB_INTERNAL) || tdb->tdb1.traverse_read) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb1_transaction_start: cannot start a" "tdb1_transaction_start: cannot start a"
" transaction on a read-only or" " transaction on a read-only or"
...@@ -427,12 +427,12 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb) ...@@ -427,12 +427,12 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb)
} }
/* cope with nested tdb1_transaction_start() calls */ /* cope with nested tdb1_transaction_start() calls */
if (tdb->transaction != NULL) { if (tdb->tdb1.transaction != NULL) {
if (!(tdb->flags & TDB_ALLOW_NESTING)) { if (!(tdb->flags & TDB_ALLOW_NESTING)) {
tdb->last_error = TDB_ERR_EINVAL; tdb->last_error = TDB_ERR_EINVAL;
return -1; return -1;
} }
tdb->transaction->nesting++; tdb->tdb1.transaction->nesting++;
return 0; return 0;
} }
...@@ -446,7 +446,7 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb) ...@@ -446,7 +446,7 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb)
return -1; return -1;
} }
if (tdb->travlocks.next != NULL) { if (tdb->tdb1.travlocks.next != NULL) {
/* you cannot use transactions inside a traverse (although you can use /* you cannot use transactions inside a traverse (although you can use
traverse inside a transaction) as otherwise you can end up with traverse inside a transaction) as otherwise you can end up with
deadlock */ deadlock */
...@@ -456,22 +456,22 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb) ...@@ -456,22 +456,22 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb)
return -1; return -1;
} }
tdb->transaction = (struct tdb1_transaction *) tdb->tdb1.transaction = (struct tdb1_transaction *)
calloc(sizeof(struct tdb1_transaction), 1); calloc(sizeof(struct tdb1_transaction), 1);
if (tdb->transaction == NULL) { if (tdb->tdb1.transaction == NULL) {
tdb->last_error = TDB_ERR_OOM; tdb->last_error = TDB_ERR_OOM;
return -1; return -1;
} }
/* a page at a time seems like a reasonable compromise between compactness and efficiency */ /* a page at a time seems like a reasonable compromise between compactness and efficiency */
tdb->transaction->block_size = tdb->page_size; tdb->tdb1.transaction->block_size = tdb->tdb1.page_size;
/* get the transaction write lock. This is a blocking lock. As /* get the transaction write lock. This is a blocking lock. As
discussed with Volker, there are a number of ways we could discussed with Volker, there are a number of ways we could
make this async, which we will probably do in the future */ make this async, which we will probably do in the future */
if (tdb1_transaction_lock(tdb, F_WRLCK, TDB_LOCK_WAIT) == -1) { if (tdb1_transaction_lock(tdb, F_WRLCK, TDB_LOCK_WAIT) == -1) {
SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->tdb1.transaction->blocks);
SAFE_FREE(tdb->transaction); SAFE_FREE(tdb->tdb1.transaction);
return -1; return -1;
} }
...@@ -488,13 +488,13 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb) ...@@ -488,13 +488,13 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb)
/* setup a copy of the hash table heads so the hash scan in /* setup a copy of the hash table heads so the hash scan in
traverse can be fast */ traverse can be fast */
tdb->transaction->hash_heads = (uint32_t *) tdb->tdb1.transaction->hash_heads = (uint32_t *)
calloc(tdb->header.hash_size+1, sizeof(uint32_t)); calloc(tdb->tdb1.header.hash_size+1, sizeof(uint32_t));
if (tdb->transaction->hash_heads == NULL) { if (tdb->tdb1.transaction->hash_heads == NULL) {
tdb->last_error = TDB_ERR_OOM; tdb->last_error = TDB_ERR_OOM;
goto fail; goto fail;
} }
if (tdb->methods->tdb1_read(tdb, TDB1_FREELIST_TOP, tdb->transaction->hash_heads, if (tdb->tdb1.io->tdb1_read(tdb, TDB1_FREELIST_TOP, tdb->tdb1.transaction->hash_heads,
TDB1_HASHTABLE_SIZE(tdb), 0) != 0) { TDB1_HASHTABLE_SIZE(tdb), 0) != 0) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_start: failed to read hash heads"); "tdb1_transaction_start: failed to read hash heads");
...@@ -503,13 +503,13 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb) ...@@ -503,13 +503,13 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb)
/* make sure we know about any file expansions already done by /* make sure we know about any file expansions already done by
anyone else */ anyone else */
tdb->methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1); tdb->tdb1.io->tdb1_oob(tdb, tdb->file->map_size + 1, 1);
tdb->transaction->old_map_size = tdb->file->map_size; tdb->tdb1.transaction->old_map_size = tdb->file->map_size;
/* finally hook the io methods, replacing them with /* finally hook the io methods, replacing them with
transaction specific methods */ transaction specific methods */
tdb->transaction->io_methods = tdb->methods; tdb->tdb1.transaction->io_methods = tdb->tdb1.io;
tdb->methods = &transaction1_methods; tdb->tdb1.io = &transaction1_methods;
return 0; return 0;
...@@ -517,13 +517,13 @@ fail: ...@@ -517,13 +517,13 @@ fail:
tdb1_allrecord_unlock(tdb, F_RDLCK); tdb1_allrecord_unlock(tdb, F_RDLCK);
fail_allrecord_lock: fail_allrecord_lock:
tdb1_transaction_unlock(tdb, F_WRLCK); tdb1_transaction_unlock(tdb, F_WRLCK);
SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->tdb1.transaction->blocks);
SAFE_FREE(tdb->transaction->hash_heads); SAFE_FREE(tdb->tdb1.transaction->hash_heads);
SAFE_FREE(tdb->transaction); SAFE_FREE(tdb->tdb1.transaction);
return -1; return -1;
} }
int tdb1_transaction_start(struct tdb1_context *tdb) int tdb1_transaction_start(struct tdb_context *tdb)
{ {
return _tdb1_transaction_start(tdb); return _tdb1_transaction_start(tdb);
} }
...@@ -531,7 +531,7 @@ int tdb1_transaction_start(struct tdb1_context *tdb) ...@@ -531,7 +531,7 @@ int tdb1_transaction_start(struct tdb1_context *tdb)
/* /*
sync to disk sync to disk
*/ */
static int transaction1_sync(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_len_t length) static int transaction1_sync(struct tdb_context *tdb, tdb1_off_t offset, tdb1_len_t length)
{ {
if (tdb->flags & TDB_NOSYNC) { if (tdb->flags & TDB_NOSYNC) {
return 0; return 0;
...@@ -548,7 +548,7 @@ static int transaction1_sync(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_l ...@@ -548,7 +548,7 @@ static int transaction1_sync(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_l
} }
#if HAVE_MMAP #if HAVE_MMAP
if (tdb->file->map_ptr) { if (tdb->file->map_ptr) {
tdb1_off_t moffset = offset & ~(tdb->page_size-1); tdb1_off_t moffset = offset & ~(tdb->tdb1.page_size-1);
if (msync(moffset + (char *)tdb->file->map_ptr, if (msync(moffset + (char *)tdb->file->map_ptr,
length + (offset - moffset), MS_SYNC) != 0) { length + (offset - moffset), MS_SYNC) != 0) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR,
...@@ -563,40 +563,40 @@ static int transaction1_sync(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_l ...@@ -563,40 +563,40 @@ static int transaction1_sync(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_l
} }
static int _tdb1_transaction_cancel(struct tdb1_context *tdb) static int _tdb1_transaction_cancel(struct tdb_context *tdb)
{ {
int i, ret = 0; int i, ret = 0;
if (tdb->transaction == NULL) { if (tdb->tdb1.transaction == NULL) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb1_transaction_cancel:" "tdb1_transaction_cancel:"
" no transaction"); " no transaction");
return -1; return -1;
} }
if (tdb->transaction->nesting != 0) { if (tdb->tdb1.transaction->nesting != 0) {
tdb->transaction->transaction_error = 1; tdb->tdb1.transaction->transaction_error = 1;
tdb->transaction->nesting--; tdb->tdb1.transaction->nesting--;
return 0; return 0;
} }
tdb->file->map_size = tdb->transaction->old_map_size; tdb->file->map_size = tdb->tdb1.transaction->old_map_size;
/* free all the transaction blocks */ /* free all the transaction blocks */
for (i=0;i<tdb->transaction->num_blocks;i++) { for (i=0;i<tdb->tdb1.transaction->num_blocks;i++) {
if (tdb->transaction->blocks[i] != NULL) { if (tdb->tdb1.transaction->blocks[i] != NULL) {
free(tdb->transaction->blocks[i]); free(tdb->tdb1.transaction->blocks[i]);
} }
} }
SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->tdb1.transaction->blocks);
if (tdb->transaction->magic_offset) { if (tdb->tdb1.transaction->magic_offset) {
const struct tdb1_methods *methods = tdb->transaction->io_methods; const struct tdb1_methods *methods = tdb->tdb1.transaction->io_methods;
const uint32_t invalid = TDB1_RECOVERY_INVALID_MAGIC; const uint32_t invalid = TDB1_RECOVERY_INVALID_MAGIC;
/* remove the recovery marker */ /* remove the recovery marker */
if (methods->tdb1_write(tdb, tdb->transaction->magic_offset, &invalid, 4) == -1 || if (methods->tdb1_write(tdb, tdb->tdb1.transaction->magic_offset, &invalid, 4) == -1 ||
transaction1_sync(tdb, tdb->transaction->magic_offset, 4) == -1) { transaction1_sync(tdb, tdb->tdb1.transaction->magic_offset, 4) == -1) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_cancel: failed to" "tdb1_transaction_cancel: failed to"
" remove recovery magic"); " remove recovery magic");
...@@ -608,10 +608,10 @@ static int _tdb1_transaction_cancel(struct tdb1_context *tdb) ...@@ -608,10 +608,10 @@ static int _tdb1_transaction_cancel(struct tdb1_context *tdb)
tdb1_release_transaction_locks(tdb); tdb1_release_transaction_locks(tdb);
/* restore the normal io methods */ /* restore the normal io methods */
tdb->methods = tdb->transaction->io_methods; tdb->tdb1.io = tdb->tdb1.transaction->io_methods;
SAFE_FREE(tdb->transaction->hash_heads); SAFE_FREE(tdb->tdb1.transaction->hash_heads);
SAFE_FREE(tdb->transaction); SAFE_FREE(tdb->tdb1.transaction);
return ret; return ret;
} }
...@@ -619,7 +619,7 @@ static int _tdb1_transaction_cancel(struct tdb1_context *tdb) ...@@ -619,7 +619,7 @@ static int _tdb1_transaction_cancel(struct tdb1_context *tdb)
/* /*
cancel the current transaction cancel the current transaction
*/ */
int tdb1_transaction_cancel(struct tdb1_context *tdb) int tdb1_transaction_cancel(struct tdb_context *tdb)
{ {
return _tdb1_transaction_cancel(tdb); return _tdb1_transaction_cancel(tdb);
} }
...@@ -627,31 +627,31 @@ int tdb1_transaction_cancel(struct tdb1_context *tdb) ...@@ -627,31 +627,31 @@ int tdb1_transaction_cancel(struct tdb1_context *tdb)
/* /*
work out how much space the linearised recovery data will consume work out how much space the linearised recovery data will consume
*/ */
static tdb1_len_t tdb1_recovery_size(struct tdb1_context *tdb) static tdb1_len_t tdb1_recovery_size(struct tdb_context *tdb)
{ {
tdb1_len_t recovery_size = 0; tdb1_len_t recovery_size = 0;
int i; int i;
recovery_size = sizeof(uint32_t); recovery_size = sizeof(uint32_t);
for (i=0;i<tdb->transaction->num_blocks;i++) { for (i=0;i<tdb->tdb1.transaction->num_blocks;i++) {
if (i * tdb->transaction->block_size >= tdb->transaction->old_map_size) { if (i * tdb->tdb1.transaction->block_size >= tdb->tdb1.transaction->old_map_size) {
break; break;
} }
if (tdb->transaction->blocks[i] == NULL) { if (tdb->tdb1.transaction->blocks[i] == NULL) {
continue; continue;
} }
recovery_size += 2*sizeof(tdb1_off_t); recovery_size += 2*sizeof(tdb1_off_t);
if (i == tdb->transaction->num_blocks-1) { if (i == tdb->tdb1.transaction->num_blocks-1) {
recovery_size += tdb->transaction->last_block_size; recovery_size += tdb->tdb1.transaction->last_block_size;
} else { } else {
recovery_size += tdb->transaction->block_size; recovery_size += tdb->tdb1.transaction->block_size;
} }
} }
return recovery_size; return recovery_size;
} }
int tdb1_recovery_area(struct tdb1_context *tdb, int tdb1_recovery_area(struct tdb_context *tdb,
const struct tdb1_methods *methods, const struct tdb1_methods *methods,
tdb1_off_t *recovery_offset, tdb1_off_t *recovery_offset,
struct tdb1_record *rec) struct tdb1_record *rec)
...@@ -683,13 +683,13 @@ int tdb1_recovery_area(struct tdb1_context *tdb, ...@@ -683,13 +683,13 @@ int tdb1_recovery_area(struct tdb1_context *tdb,
allocate the recovery area, or use an existing recovery area if it is allocate the recovery area, or use an existing recovery area if it is
large enough large enough
*/ */
static int tdb1_recovery_allocate(struct tdb1_context *tdb, static int tdb1_recovery_allocate(struct tdb_context *tdb,
tdb1_len_t *recovery_size, tdb1_len_t *recovery_size,
tdb1_off_t *recovery_offset, tdb1_off_t *recovery_offset,
tdb1_len_t *recovery_max_size) tdb1_len_t *recovery_max_size)
{ {
struct tdb1_record rec; struct tdb1_record rec;
const struct tdb1_methods *methods = tdb->transaction->io_methods; const struct tdb1_methods *methods = tdb->tdb1.transaction->io_methods;
tdb1_off_t recovery_head; tdb1_off_t recovery_head;
if (tdb1_recovery_area(tdb, methods, &recovery_head, &rec) == -1) { if (tdb1_recovery_area(tdb, methods, &recovery_head, &rec) == -1) {
...@@ -726,12 +726,13 @@ static int tdb1_recovery_allocate(struct tdb1_context *tdb, ...@@ -726,12 +726,13 @@ static int tdb1_recovery_allocate(struct tdb1_context *tdb,
*recovery_size = tdb1_recovery_size(tdb); *recovery_size = tdb1_recovery_size(tdb);
/* round up to a multiple of page size */ /* round up to a multiple of page size */
*recovery_max_size = TDB1_ALIGN(sizeof(rec) + *recovery_size, tdb->page_size) - sizeof(rec); *recovery_max_size = TDB1_ALIGN(sizeof(rec) + *recovery_size,
tdb->tdb1.page_size) - sizeof(rec);
*recovery_offset = tdb->file->map_size; *recovery_offset = tdb->file->map_size;
recovery_head = *recovery_offset; recovery_head = *recovery_offset;
if (methods->tdb1_expand_file(tdb, tdb->transaction->old_map_size, if (methods->tdb1_expand_file(tdb, tdb->tdb1.transaction->old_map_size,
(tdb->file->map_size - tdb->transaction->old_map_size) + (tdb->file->map_size - tdb->tdb1.transaction->old_map_size) +
sizeof(rec) + *recovery_max_size) == -1) { sizeof(rec) + *recovery_max_size) == -1) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_recovery_allocate:" "tdb1_recovery_allocate:"
...@@ -744,7 +745,7 @@ static int tdb1_recovery_allocate(struct tdb1_context *tdb, ...@@ -744,7 +745,7 @@ static int tdb1_recovery_allocate(struct tdb1_context *tdb,
/* we have to reset the old map size so that we don't try to expand the file /* we have to reset the old map size so that we don't try to expand the file
again in the transaction commit, which would destroy the recovery area */ again in the transaction commit, which would destroy the recovery area */
tdb->transaction->old_map_size = tdb->file->map_size; tdb->tdb1.transaction->old_map_size = tdb->file->map_size;
/* write the recovery header offset and sync - we can sync without a race here /* write the recovery header offset and sync - we can sync without a race here
as the magic ptr in the recovery record has not been set */ as the magic ptr in the recovery record has not been set */
...@@ -770,15 +771,15 @@ static int tdb1_recovery_allocate(struct tdb1_context *tdb, ...@@ -770,15 +771,15 @@ static int tdb1_recovery_allocate(struct tdb1_context *tdb,
/* /*
setup the recovery data that will be used on a crash during commit setup the recovery data that will be used on a crash during commit
*/ */
static int transaction1_setup_recovery(struct tdb1_context *tdb, static int transaction1_setup_recovery(struct tdb_context *tdb,
tdb1_off_t *magic_offset) tdb1_off_t *magic_offset)
{ {
tdb1_len_t recovery_size; tdb1_len_t recovery_size;
unsigned char *data, *p; unsigned char *data, *p;
const struct tdb1_methods *methods = tdb->transaction->io_methods; const struct tdb1_methods *methods = tdb->tdb1.transaction->io_methods;
struct tdb1_record *rec; struct tdb1_record *rec;
tdb1_off_t recovery_offset, recovery_max_size; tdb1_off_t recovery_offset, recovery_max_size;
tdb1_off_t old_map_size = tdb->transaction->old_map_size; tdb1_off_t old_map_size = tdb->tdb1.transaction->old_map_size;
uint32_t magic, tailer; uint32_t magic, tailer;
int i; int i;
...@@ -808,24 +809,24 @@ static int transaction1_setup_recovery(struct tdb1_context *tdb, ...@@ -808,24 +809,24 @@ static int transaction1_setup_recovery(struct tdb1_context *tdb,
/* build the recovery data into a single blob to allow us to do a single /* build the recovery data into a single blob to allow us to do a single
large write, which should be more efficient */ large write, which should be more efficient */
p = data + sizeof(*rec); p = data + sizeof(*rec);
for (i=0;i<tdb->transaction->num_blocks;i++) { for (i=0;i<tdb->tdb1.transaction->num_blocks;i++) {
tdb1_off_t offset; tdb1_off_t offset;
tdb1_len_t length; tdb1_len_t length;
if (tdb->transaction->blocks[i] == NULL) { if (tdb->tdb1.transaction->blocks[i] == NULL) {
continue; continue;
} }
offset = i * tdb->transaction->block_size; offset = i * tdb->tdb1.transaction->block_size;
length = tdb->transaction->block_size; length = tdb->tdb1.transaction->block_size;
if (i == tdb->transaction->num_blocks-1) { if (i == tdb->tdb1.transaction->num_blocks-1) {
length = tdb->transaction->last_block_size; length = tdb->tdb1.transaction->last_block_size;
} }
if (offset >= old_map_size) { if (offset >= old_map_size) {
continue; continue;
} }
if (offset + length > tdb->transaction->old_map_size) { if (offset + length > tdb->tdb1.transaction->old_map_size) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT,
TDB_LOG_ERROR, TDB_LOG_ERROR,
"tdb1_transaction_setup_recovery: transaction data over new region boundary"); "tdb1_transaction_setup_recovery: transaction data over new region boundary");
...@@ -907,18 +908,18 @@ static int transaction1_setup_recovery(struct tdb1_context *tdb, ...@@ -907,18 +908,18 @@ static int transaction1_setup_recovery(struct tdb1_context *tdb,
return 0; return 0;
} }
static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb) static int _tdb1_transaction_prepare_commit(struct tdb_context *tdb)
{ {
const struct tdb1_methods *methods; const struct tdb1_methods *methods;
if (tdb->transaction == NULL) { if (tdb->tdb1.transaction == NULL) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb1_transaction_prepare_commit:" "tdb1_transaction_prepare_commit:"
" no transaction"); " no transaction");
return -1; return -1;
} }
if (tdb->transaction->prepared) { if (tdb->tdb1.transaction->prepared) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb1_transaction_prepare_commit:" "tdb1_transaction_prepare_commit:"
" transaction already prepared"); " transaction already prepared");
...@@ -926,7 +927,7 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb) ...@@ -926,7 +927,7 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb)
return -1; return -1;
} }
if (tdb->transaction->transaction_error) { if (tdb->tdb1.transaction->transaction_error) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR,
"tdb1_transaction_prepare_commit:" "tdb1_transaction_prepare_commit:"
" transaction error pending"); " transaction error pending");
...@@ -935,16 +936,16 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb) ...@@ -935,16 +936,16 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb)
} }
if (tdb->transaction->nesting != 0) { if (tdb->tdb1.transaction->nesting != 0) {
return 0; return 0;
} }
/* check for a null transaction */ /* check for a null transaction */
if (tdb->transaction->blocks == NULL) { if (tdb->tdb1.transaction->blocks == NULL) {
return 0; return 0;
} }
methods = tdb->transaction->io_methods; methods = tdb->tdb1.transaction->io_methods;
/* if there are any locks pending then the caller has not /* if there are any locks pending then the caller has not
nested their locks properly, so fail the transaction */ nested their locks properly, so fail the transaction */
...@@ -979,7 +980,7 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb) ...@@ -979,7 +980,7 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb)
if (!(tdb->flags & TDB_NOSYNC)) { if (!(tdb->flags & TDB_NOSYNC)) {
/* write the recovery data to the end of the file */ /* write the recovery data to the end of the file */
if (transaction1_setup_recovery(tdb, &tdb->transaction->magic_offset) == -1) { if (transaction1_setup_recovery(tdb, &tdb->tdb1.transaction->magic_offset) == -1) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_prepare_commit:" "tdb1_transaction_prepare_commit:"
" failed to setup recovery data"); " failed to setup recovery data");
...@@ -987,19 +988,19 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb) ...@@ -987,19 +988,19 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb)
} }
} }
tdb->transaction->prepared = true; tdb->tdb1.transaction->prepared = true;
/* expand the file to the new size if needed */ /* expand the file to the new size if needed */
if (tdb->file->map_size != tdb->transaction->old_map_size) { if (tdb->file->map_size != tdb->tdb1.transaction->old_map_size) {
if (methods->tdb1_expand_file(tdb, tdb->transaction->old_map_size, if (methods->tdb1_expand_file(tdb, tdb->tdb1.transaction->old_map_size,
tdb->file->map_size - tdb->file->map_size -
tdb->transaction->old_map_size) == -1) { tdb->tdb1.transaction->old_map_size) == -1) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_prepare_commit:" "tdb1_transaction_prepare_commit:"
" expansion failed"); " expansion failed");
return -1; return -1;
} }
tdb->file->map_size = tdb->transaction->old_map_size; tdb->file->map_size = tdb->tdb1.transaction->old_map_size;
methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1); methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1);
} }
...@@ -1011,13 +1012,13 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb) ...@@ -1011,13 +1012,13 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb)
/* /*
prepare to commit the current transaction prepare to commit the current transaction
*/ */
int tdb1_transaction_prepare_commit(struct tdb1_context *tdb) int tdb1_transaction_prepare_commit(struct tdb_context *tdb)
{ {
return _tdb1_transaction_prepare_commit(tdb); return _tdb1_transaction_prepare_commit(tdb);
} }
/* A repack is worthwhile if the largest is less than half total free. */ /* A repack is worthwhile if the largest is less than half total free. */
static bool repack_worthwhile(struct tdb1_context *tdb) static bool repack_worthwhile(struct tdb_context *tdb)
{ {
tdb1_off_t ptr; tdb1_off_t ptr;
struct tdb1_record rec; struct tdb1_record rec;
...@@ -1041,20 +1042,20 @@ static bool repack_worthwhile(struct tdb1_context *tdb) ...@@ -1041,20 +1042,20 @@ static bool repack_worthwhile(struct tdb1_context *tdb)
/* /*
commit the current transaction commit the current transaction
*/ */
int tdb1_transaction_commit(struct tdb1_context *tdb) int tdb1_transaction_commit(struct tdb_context *tdb)
{ {
const struct tdb1_methods *methods; const struct tdb1_methods *methods;
int i; int i;
bool need_repack = false; bool need_repack = false;
if (tdb->transaction == NULL) { if (tdb->tdb1.transaction == NULL) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb1_transaction_commit:" "tdb1_transaction_commit:"
" no transaction"); " no transaction");
return -1; return -1;
} }
if (tdb->transaction->transaction_error) { if (tdb->tdb1.transaction->transaction_error) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR,
"tdb1_transaction_commit:" "tdb1_transaction_commit:"
" transaction error pending"); " transaction error pending");
...@@ -1063,18 +1064,18 @@ int tdb1_transaction_commit(struct tdb1_context *tdb) ...@@ -1063,18 +1064,18 @@ int tdb1_transaction_commit(struct tdb1_context *tdb)
} }
if (tdb->transaction->nesting != 0) { if (tdb->tdb1.transaction->nesting != 0) {
tdb->transaction->nesting--; tdb->tdb1.transaction->nesting--;
return 0; return 0;
} }
/* check for a null transaction */ /* check for a null transaction */
if (tdb->transaction->blocks == NULL) { if (tdb->tdb1.transaction->blocks == NULL) {
_tdb1_transaction_cancel(tdb); _tdb1_transaction_cancel(tdb);
return 0; return 0;
} }
if (!tdb->transaction->prepared) { if (!tdb->tdb1.transaction->prepared) {
int ret = _tdb1_transaction_prepare_commit(tdb); int ret = _tdb1_transaction_prepare_commit(tdb);
if (ret) { if (ret) {
_tdb1_transaction_cancel(tdb); _tdb1_transaction_cancel(tdb);
...@@ -1082,24 +1083,24 @@ int tdb1_transaction_commit(struct tdb1_context *tdb) ...@@ -1082,24 +1083,24 @@ int tdb1_transaction_commit(struct tdb1_context *tdb)
} }
} }
methods = tdb->transaction->io_methods; methods = tdb->tdb1.transaction->io_methods;
/* perform all the writes */ /* perform all the writes */
for (i=0;i<tdb->transaction->num_blocks;i++) { for (i=0;i<tdb->tdb1.transaction->num_blocks;i++) {
tdb1_off_t offset; tdb1_off_t offset;
tdb1_len_t length; tdb1_len_t length;
if (tdb->transaction->blocks[i] == NULL) { if (tdb->tdb1.transaction->blocks[i] == NULL) {
continue; continue;
} }
offset = i * tdb->transaction->block_size; offset = i * tdb->tdb1.transaction->block_size;
length = tdb->transaction->block_size; length = tdb->tdb1.transaction->block_size;
if (i == tdb->transaction->num_blocks-1) { if (i == tdb->tdb1.transaction->num_blocks-1) {
length = tdb->transaction->last_block_size; length = tdb->tdb1.transaction->last_block_size;
} }
if (methods->tdb1_write(tdb, offset, tdb->transaction->blocks[i], length) == -1) { if (methods->tdb1_write(tdb, offset, tdb->tdb1.transaction->blocks[i], length) == -1) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_commit:" "tdb1_transaction_commit:"
" write failed during commit"); " write failed during commit");
...@@ -1107,7 +1108,7 @@ int tdb1_transaction_commit(struct tdb1_context *tdb) ...@@ -1107,7 +1108,7 @@ int tdb1_transaction_commit(struct tdb1_context *tdb)
/* we've overwritten part of the data and /* we've overwritten part of the data and
possibly expanded the file, so we need to possibly expanded the file, so we need to
run the crash recovery code */ run the crash recovery code */
tdb->methods = methods; tdb->tdb1.io = methods;
tdb1_transaction_recover(tdb); tdb1_transaction_recover(tdb);
_tdb1_transaction_cancel(tdb); _tdb1_transaction_cancel(tdb);
...@@ -1116,16 +1117,16 @@ int tdb1_transaction_commit(struct tdb1_context *tdb) ...@@ -1116,16 +1117,16 @@ int tdb1_transaction_commit(struct tdb1_context *tdb)
"tdb1_transaction_commit: write failed"); "tdb1_transaction_commit: write failed");
return -1; return -1;
} }
SAFE_FREE(tdb->transaction->blocks[i]); SAFE_FREE(tdb->tdb1.transaction->blocks[i]);
} }
/* Do this before we drop lock or blocks. */ /* Do this before we drop lock or blocks. */
if (tdb->transaction->expanded) { if (tdb->tdb1.transaction->expanded) {
need_repack = repack_worthwhile(tdb); need_repack = repack_worthwhile(tdb);
} }
SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->tdb1.transaction->blocks);
tdb->transaction->num_blocks = 0; tdb->tdb1.transaction->num_blocks = 0;
/* ensure the new data is on disk */ /* ensure the new data is on disk */
if (transaction1_sync(tdb, 0, tdb->file->map_size) == -1) { if (transaction1_sync(tdb, 0, tdb->file->map_size) == -1) {
...@@ -1164,7 +1165,7 @@ int tdb1_transaction_commit(struct tdb1_context *tdb) ...@@ -1164,7 +1165,7 @@ int tdb1_transaction_commit(struct tdb1_context *tdb)
database write access already established (including the open database write access already established (including the open
lock to prevent new processes attaching) lock to prevent new processes attaching)
*/ */
int tdb1_transaction_recover(struct tdb1_context *tdb) int tdb1_transaction_recover(struct tdb_context *tdb)
{ {
tdb1_off_t recovery_head, recovery_eof; tdb1_off_t recovery_head, recovery_eof;
unsigned char *data, *p; unsigned char *data, *p;
...@@ -1185,7 +1186,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb) ...@@ -1185,7 +1186,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb)
} }
/* read the recovery record */ /* read the recovery record */
if (tdb->methods->tdb1_read(tdb, recovery_head, &rec, if (tdb->tdb1.io->tdb1_read(tdb, recovery_head, &rec,
sizeof(rec), TDB1_DOCONV()) == -1) { sizeof(rec), TDB1_DOCONV()) == -1) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_recover:" "tdb1_transaction_recover:"
...@@ -1217,7 +1218,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb) ...@@ -1217,7 +1218,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb)
} }
/* read the full recovery data */ /* read the full recovery data */
if (tdb->methods->tdb1_read(tdb, recovery_head + sizeof(rec), data, if (tdb->tdb1.io->tdb1_read(tdb, recovery_head + sizeof(rec), data,
rec.data_len, 0) == -1) { rec.data_len, 0) == -1) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_recover:" "tdb1_transaction_recover:"
...@@ -1235,7 +1236,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb) ...@@ -1235,7 +1236,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb)
memcpy(&ofs, p, 4); memcpy(&ofs, p, 4);
memcpy(&len, p+4, 4); memcpy(&len, p+4, 4);
if (tdb->methods->tdb1_write(tdb, ofs, p+8, len) == -1) { if (tdb->tdb1.io->tdb1_write(tdb, ofs, p+8, len) == -1) {
free(data); free(data);
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_recover: failed to recover" "tdb1_transaction_recover: failed to recover"
...@@ -1288,7 +1289,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb) ...@@ -1288,7 +1289,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb)
} }
/* Any I/O failures we say "needs recovery". */ /* Any I/O failures we say "needs recovery". */
bool tdb1_needs_recovery(struct tdb1_context *tdb) bool tdb1_needs_recovery(struct tdb_context *tdb)
{ {
tdb1_off_t recovery_head; tdb1_off_t recovery_head;
struct tdb1_record rec; struct tdb1_record rec;
...@@ -1304,7 +1305,7 @@ bool tdb1_needs_recovery(struct tdb1_context *tdb) ...@@ -1304,7 +1305,7 @@ bool tdb1_needs_recovery(struct tdb1_context *tdb)
} }
/* read the recovery record */ /* read the recovery record */
if (tdb->methods->tdb1_read(tdb, recovery_head, &rec, if (tdb->tdb1.io->tdb1_read(tdb, recovery_head, &rec,
sizeof(rec), TDB1_DOCONV()) == -1) { sizeof(rec), TDB1_DOCONV()) == -1) {
return true; return true;
} }
......
...@@ -31,13 +31,13 @@ ...@@ -31,13 +31,13 @@
/* Uses traverse lock: 0 = finish, TDB1_NEXT_LOCK_ERR = error, /* Uses traverse lock: 0 = finish, TDB1_NEXT_LOCK_ERR = error,
other = record offset */ other = record offset */
static tdb1_off_t tdb1_next_lock(struct tdb1_context *tdb, struct tdb1_traverse_lock *tlock, static tdb1_off_t tdb1_next_lock(struct tdb_context *tdb, struct tdb1_traverse_lock *tlock,
struct tdb1_record *rec) struct tdb1_record *rec)
{ {
int want_next = (tlock->off != 0); int want_next = (tlock->off != 0);
/* Lock each chain from the start one. */ /* Lock each chain from the start one. */
for (; tlock->hash < tdb->header.hash_size; tlock->hash++) { for (; tlock->hash < tdb->tdb1.header.hash_size; tlock->hash++) {
if (!tlock->off && tlock->hash != 0) { if (!tlock->off && tlock->hash != 0) {
/* this is an optimisation for the common case where /* this is an optimisation for the common case where
the hash chain is empty, which is particularly the hash chain is empty, which is particularly
...@@ -67,8 +67,8 @@ static tdb1_off_t tdb1_next_lock(struct tdb1_context *tdb, struct tdb1_traverse_ ...@@ -67,8 +67,8 @@ static tdb1_off_t tdb1_next_lock(struct tdb1_context *tdb, struct tdb1_traverse_
factor of around 80 in speed on a linux 2.6.x factor of around 80 in speed on a linux 2.6.x
system (testing using ldbtest). system (testing using ldbtest).
*/ */
tdb->methods->next_hash_chain(tdb, &tlock->hash); tdb->tdb1.io->next_hash_chain(tdb, &tlock->hash);
if (tlock->hash == tdb->header.hash_size) { if (tlock->hash == tdb->tdb1.header.hash_size) {
continue; continue;
} }
} }
...@@ -119,7 +119,7 @@ static tdb1_off_t tdb1_next_lock(struct tdb1_context *tdb, struct tdb1_traverse_ ...@@ -119,7 +119,7 @@ static tdb1_off_t tdb1_next_lock(struct tdb1_context *tdb, struct tdb1_traverse_
/* Try to clean dead ones from old traverses */ /* Try to clean dead ones from old traverses */
current = tlock->off; current = tlock->off;
tlock->off = rec->next; tlock->off = rec->next;
if (!((tdb->flags & TDB_RDONLY) || tdb->traverse_read) && if (!((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) &&
tdb1_do_delete(tdb, current, rec) != 0) tdb1_do_delete(tdb, current, rec) != 0)
goto fail; goto fail;
} }
...@@ -143,7 +143,7 @@ static tdb1_off_t tdb1_next_lock(struct tdb1_context *tdb, struct tdb1_traverse_ ...@@ -143,7 +143,7 @@ static tdb1_off_t tdb1_next_lock(struct tdb1_context *tdb, struct tdb1_traverse_
if fn is NULL then it is not called if fn is NULL then it is not called
a non-zero return value from fn() indicates that the traversal should stop a non-zero return value from fn() indicates that the traversal should stop
*/ */
static int tdb1_traverse_internal(struct tdb1_context *tdb, static int tdb1_traverse_internal(struct tdb_context *tdb,
tdb1_traverse_func fn, void *private_data, tdb1_traverse_func fn, void *private_data,
struct tdb1_traverse_lock *tl) struct tdb1_traverse_lock *tl)
{ {
...@@ -155,10 +155,10 @@ static int tdb1_traverse_internal(struct tdb1_context *tdb, ...@@ -155,10 +155,10 @@ static int tdb1_traverse_internal(struct tdb1_context *tdb,
/* This was in the initializaton, above, but the IRIX compiler /* This was in the initializaton, above, but the IRIX compiler
* did not like it. crh * did not like it. crh
*/ */
tl->next = tdb->travlocks.next; tl->next = tdb->tdb1.travlocks.next;
/* fcntl locks don't stack: beware traverse inside traverse */ /* fcntl locks don't stack: beware traverse inside traverse */
tdb->travlocks.next = tl; tdb->tdb1.travlocks.next = tl;
/* tdb1_next_lock places locks on the record returned, and its chain */ /* tdb1_next_lock places locks on the record returned, and its chain */
while ((off = tdb1_next_lock(tdb, tl, &rec)) != 0) { while ((off = tdb1_next_lock(tdb, tl, &rec)) != 0) {
...@@ -204,7 +204,7 @@ static int tdb1_traverse_internal(struct tdb1_context *tdb, ...@@ -204,7 +204,7 @@ static int tdb1_traverse_internal(struct tdb1_context *tdb,
SAFE_FREE(key.dptr); SAFE_FREE(key.dptr);
} }
out: out:
tdb->travlocks.next = tl->next; tdb->tdb1.travlocks.next = tl->next;
if (ret < 0) if (ret < 0)
return -1; return -1;
else else
...@@ -215,7 +215,7 @@ out: ...@@ -215,7 +215,7 @@ out:
/* /*
a write style traverse - temporarily marks the db read only a write style traverse - temporarily marks the db read only
*/ */
int tdb1_traverse_read(struct tdb1_context *tdb, int tdb1_traverse_read(struct tdb_context *tdb,
tdb1_traverse_func fn, void *private_data) tdb1_traverse_func fn, void *private_data)
{ {
struct tdb1_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; struct tdb1_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
...@@ -227,9 +227,9 @@ int tdb1_traverse_read(struct tdb1_context *tdb, ...@@ -227,9 +227,9 @@ int tdb1_traverse_read(struct tdb1_context *tdb,
return -1; return -1;
} }
tdb->traverse_read++; tdb->tdb1.traverse_read++;
ret = tdb1_traverse_internal(tdb, fn, private_data, &tl); ret = tdb1_traverse_internal(tdb, fn, private_data, &tl);
tdb->traverse_read--; tdb->tdb1.traverse_read--;
tdb1_transaction_unlock(tdb, F_RDLCK); tdb1_transaction_unlock(tdb, F_RDLCK);
...@@ -243,13 +243,13 @@ int tdb1_traverse_read(struct tdb1_context *tdb, ...@@ -243,13 +243,13 @@ int tdb1_traverse_read(struct tdb1_context *tdb,
WARNING: The data buffer given to the callback fn does NOT meet the WARNING: The data buffer given to the callback fn does NOT meet the
alignment restrictions malloc gives you. alignment restrictions malloc gives you.
*/ */
int tdb1_traverse(struct tdb1_context *tdb, int tdb1_traverse(struct tdb_context *tdb,
tdb1_traverse_func fn, void *private_data) tdb1_traverse_func fn, void *private_data)
{ {
struct tdb1_traverse_lock tl = { NULL, 0, 0, F_WRLCK }; struct tdb1_traverse_lock tl = { NULL, 0, 0, F_WRLCK };
int ret; int ret;
if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) { if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) {
return tdb1_traverse_read(tdb, fn, private_data); return tdb1_traverse_read(tdb, fn, private_data);
} }
...@@ -257,9 +257,9 @@ int tdb1_traverse(struct tdb1_context *tdb, ...@@ -257,9 +257,9 @@ int tdb1_traverse(struct tdb1_context *tdb,
return -1; return -1;
} }
tdb->traverse_write++; tdb->tdb1.traverse_write++;
ret = tdb1_traverse_internal(tdb, fn, private_data, &tl); ret = tdb1_traverse_internal(tdb, fn, private_data, &tl);
tdb->traverse_write--; tdb->tdb1.traverse_write--;
tdb1_transaction_unlock(tdb, F_WRLCK); tdb1_transaction_unlock(tdb, F_WRLCK);
...@@ -268,29 +268,29 @@ int tdb1_traverse(struct tdb1_context *tdb, ...@@ -268,29 +268,29 @@ int tdb1_traverse(struct tdb1_context *tdb,
/* find the first entry in the database and return its key */ /* find the first entry in the database and return its key */
TDB_DATA tdb1_firstkey(struct tdb1_context *tdb) TDB_DATA tdb1_firstkey(struct tdb_context *tdb)
{ {
TDB_DATA key; TDB_DATA key;
struct tdb1_record rec; struct tdb1_record rec;
tdb1_off_t off; tdb1_off_t off;
/* release any old lock */ /* release any old lock */
if (tdb1_unlock_record(tdb, tdb->travlocks.off) != 0) if (tdb1_unlock_record(tdb, tdb->tdb1.travlocks.off) != 0)
return tdb1_null; return tdb1_null;
tdb->travlocks.off = tdb->travlocks.hash = 0; tdb->tdb1.travlocks.off = tdb->tdb1.travlocks.hash = 0;
tdb->travlocks.lock_rw = F_RDLCK; tdb->tdb1.travlocks.lock_rw = F_RDLCK;
/* Grab first record: locks chain and returned record. */ /* Grab first record: locks chain and returned record. */
off = tdb1_next_lock(tdb, &tdb->travlocks, &rec); off = tdb1_next_lock(tdb, &tdb->tdb1.travlocks, &rec);
if (off == 0 || off == TDB1_NEXT_LOCK_ERR) { if (off == 0 || off == TDB1_NEXT_LOCK_ERR) {
return tdb1_null; return tdb1_null;
} }
/* now read the key */ /* now read the key */
key.dsize = rec.key_len; key.dsize = rec.key_len;
key.dptr =tdb1_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); key.dptr =tdb1_alloc_read(tdb,tdb->tdb1.travlocks.off+sizeof(rec),key.dsize);
/* Unlock the hash chain of the record we just read. */ /* Unlock the hash chain of the record we just read. */
if (tdb1_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) if (tdb1_unlock(tdb, tdb->tdb1.travlocks.hash, tdb->tdb1.travlocks.lock_rw) != 0)
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_firstkey:" "tdb1_firstkey:"
" error occurred while tdb1_unlocking!"); " error occurred while tdb1_unlocking!");
...@@ -298,7 +298,7 @@ TDB_DATA tdb1_firstkey(struct tdb1_context *tdb) ...@@ -298,7 +298,7 @@ TDB_DATA tdb1_firstkey(struct tdb1_context *tdb)
} }
/* find the next entry in the database, returning its key */ /* find the next entry in the database, returning its key */
TDB_DATA tdb1_nextkey(struct tdb1_context *tdb, TDB_DATA oldkey) TDB_DATA tdb1_nextkey(struct tdb_context *tdb, TDB_DATA oldkey)
{ {
uint32_t oldhash; uint32_t oldhash;
TDB_DATA key = tdb1_null; TDB_DATA key = tdb1_null;
...@@ -307,58 +307,58 @@ TDB_DATA tdb1_nextkey(struct tdb1_context *tdb, TDB_DATA oldkey) ...@@ -307,58 +307,58 @@ TDB_DATA tdb1_nextkey(struct tdb1_context *tdb, TDB_DATA oldkey)
tdb1_off_t off; tdb1_off_t off;
/* Is locked key the old key? If so, traverse will be reliable. */ /* Is locked key the old key? If so, traverse will be reliable. */
if (tdb->travlocks.off) { if (tdb->tdb1.travlocks.off) {
if (tdb1_lock(tdb,tdb->travlocks.hash,tdb->travlocks.lock_rw)) if (tdb1_lock(tdb,tdb->tdb1.travlocks.hash,tdb->tdb1.travlocks.lock_rw))
return tdb1_null; return tdb1_null;
if (tdb1_rec_read(tdb, tdb->travlocks.off, &rec) == -1 if (tdb1_rec_read(tdb, tdb->tdb1.travlocks.off, &rec) == -1
|| !(k = tdb1_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), || !(k = tdb1_alloc_read(tdb,tdb->tdb1.travlocks.off+sizeof(rec),
rec.key_len)) rec.key_len))
|| memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) {
/* No, it wasn't: unlock it and start from scratch */ /* No, it wasn't: unlock it and start from scratch */
if (tdb1_unlock_record(tdb, tdb->travlocks.off) != 0) { if (tdb1_unlock_record(tdb, tdb->tdb1.travlocks.off) != 0) {
SAFE_FREE(k); SAFE_FREE(k);
return tdb1_null; return tdb1_null;
} }
if (tdb1_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) { if (tdb1_unlock(tdb, tdb->tdb1.travlocks.hash, tdb->tdb1.travlocks.lock_rw) != 0) {
SAFE_FREE(k); SAFE_FREE(k);
return tdb1_null; return tdb1_null;
} }
tdb->travlocks.off = 0; tdb->tdb1.travlocks.off = 0;
} }
SAFE_FREE(k); SAFE_FREE(k);
} }
if (!tdb->travlocks.off) { if (!tdb->tdb1.travlocks.off) {
/* No previous element: do normal find, and lock record */ /* No previous element: do normal find, and lock record */
tdb->travlocks.off = tdb1_find_lock_hash(tdb, oldkey, tdb_hash(tdb, oldkey.dptr, oldkey.dsize), tdb->travlocks.lock_rw, &rec); tdb->tdb1.travlocks.off = tdb1_find_lock_hash(tdb, oldkey, tdb_hash(tdb, oldkey.dptr, oldkey.dsize), tdb->tdb1.travlocks.lock_rw, &rec);
if (!tdb->travlocks.off) { if (!tdb->tdb1.travlocks.off) {
return tdb1_null; return tdb1_null;
} }
tdb->travlocks.hash = TDB1_BUCKET(rec.full_hash); tdb->tdb1.travlocks.hash = TDB1_BUCKET(rec.full_hash);
if (tdb1_lock_record(tdb, tdb->travlocks.off) != 0) { if (tdb1_lock_record(tdb, tdb->tdb1.travlocks.off) != 0) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_nextkey: lock_record failed (%s)!", "tdb1_nextkey: lock_record failed (%s)!",
strerror(errno)); strerror(errno));
return tdb1_null; return tdb1_null;
} }
} }
oldhash = tdb->travlocks.hash; oldhash = tdb->tdb1.travlocks.hash;
/* Grab next record: locks chain and returned record, /* Grab next record: locks chain and returned record,
unlocks old record */ unlocks old record */
off = tdb1_next_lock(tdb, &tdb->travlocks, &rec); off = tdb1_next_lock(tdb, &tdb->tdb1.travlocks, &rec);
if (off != TDB1_NEXT_LOCK_ERR && off != 0) { if (off != TDB1_NEXT_LOCK_ERR && off != 0) {
key.dsize = rec.key_len; key.dsize = rec.key_len;
key.dptr = tdb1_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), key.dptr = tdb1_alloc_read(tdb, tdb->tdb1.travlocks.off+sizeof(rec),
key.dsize); key.dsize);
/* Unlock the chain of this new record */ /* Unlock the chain of this new record */
if (tdb1_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) if (tdb1_unlock(tdb, tdb->tdb1.travlocks.hash, tdb->tdb1.travlocks.lock_rw) != 0)
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_nextkey: WARNING tdb1_unlock failed!"); "tdb1_nextkey: WARNING tdb1_unlock failed!");
} }
/* Unlock the chain of old record */ /* Unlock the chain of old record */
if (tdb1_unlock(tdb, TDB1_BUCKET(oldhash), tdb->travlocks.lock_rw) != 0) if (tdb1_unlock(tdb, TDB1_BUCKET(oldhash), tdb->tdb1.travlocks.lock_rw) != 0)
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_nextkey: WARNING tdb1_unlock failed!"); "tdb1_nextkey: WARNING tdb1_unlock failed!");
return key; return key;
......
...@@ -147,8 +147,8 @@ static void add_to_freetable(struct tdb_context *tdb, ...@@ -147,8 +147,8 @@ static void add_to_freetable(struct tdb_context *tdb,
unsigned ftable, unsigned ftable,
struct tle_freetable *freetable) struct tle_freetable *freetable)
{ {
tdb->ftable_off = freetable->base.off; tdb->tdb2.ftable_off = freetable->base.off;
tdb->ftable = ftable; tdb->tdb2.ftable = ftable;
add_free_record(tdb, eoff, sizeof(struct tdb_used_record) + elen, add_free_record(tdb, eoff, sizeof(struct tdb_used_record) + elen,
TDB_LOCK_WAIT, false); TDB_LOCK_WAIT, false);
} }
...@@ -313,7 +313,7 @@ struct tdb_context *tdb_layout_get(struct tdb_layout *layout, ...@@ -313,7 +313,7 @@ struct tdb_context *tdb_layout_get(struct tdb_layout *layout,
} }
} }
tdb->ftable_off = find_ftable(layout, 0)->base.off; tdb->tdb2.ftable_off = find_ftable(layout, 0)->base.off;
/* Get physical if they asked for it. */ /* Get physical if they asked for it. */
if (layout->filename) { if (layout->filename) {
......
...@@ -41,7 +41,7 @@ int main(int argc, char *argv[]) ...@@ -41,7 +41,7 @@ int main(int argc, char *argv[])
ok1(free_record_length(tdb, layout->elem[1].base.off) == len); ok1(free_record_length(tdb, layout->elem[1].base.off) == len);
/* Figure out which bucket free entry is. */ /* Figure out which bucket free entry is. */
b_off = bucket_off(tdb->ftable_off, size_to_bucket(len)); b_off = bucket_off(tdb->tdb2.ftable_off, size_to_bucket(len));
/* Lock and fail to coalesce. */ /* Lock and fail to coalesce. */
ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0); ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
test = layout->elem[1].base.off; test = layout->elem[1].base.off;
...@@ -64,7 +64,7 @@ int main(int argc, char *argv[]) ...@@ -64,7 +64,7 @@ int main(int argc, char *argv[])
ok1(tdb_check(tdb, NULL, NULL) == 0); ok1(tdb_check(tdb, NULL, NULL) == 0);
/* Figure out which bucket free entry is. */ /* Figure out which bucket free entry is. */
b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024)); b_off = bucket_off(tdb->tdb2.ftable_off, size_to_bucket(1024));
/* Lock and fail to coalesce. */ /* Lock and fail to coalesce. */
ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0); ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
test = layout->elem[1].base.off; test = layout->elem[1].base.off;
...@@ -88,7 +88,7 @@ int main(int argc, char *argv[]) ...@@ -88,7 +88,7 @@ int main(int argc, char *argv[])
ok1(tdb_check(tdb, NULL, NULL) == 0); ok1(tdb_check(tdb, NULL, NULL) == 0);
/* Figure out which bucket (first) free entry is. */ /* Figure out which bucket (first) free entry is. */
b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024)); b_off = bucket_off(tdb->tdb2.ftable_off, size_to_bucket(1024));
/* Lock and coalesce. */ /* Lock and coalesce. */
ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0); ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
test = layout->elem[2].base.off; test = layout->elem[2].base.off;
...@@ -115,7 +115,7 @@ int main(int argc, char *argv[]) ...@@ -115,7 +115,7 @@ int main(int argc, char *argv[])
ok1(tdb_check(tdb, NULL, NULL) == 0); ok1(tdb_check(tdb, NULL, NULL) == 0);
/* Figure out which bucket free entry is. */ /* Figure out which bucket free entry is. */
b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024)); b_off = bucket_off(tdb->tdb2.ftable_off, size_to_bucket(1024));
/* Lock and coalesce. */ /* Lock and coalesce. */
ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0); ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
test = layout->elem[2].base.off; test = layout->elem[2].base.off;
...@@ -142,7 +142,7 @@ int main(int argc, char *argv[]) ...@@ -142,7 +142,7 @@ int main(int argc, char *argv[])
ok1(tdb_check(tdb, NULL, NULL) == 0); ok1(tdb_check(tdb, NULL, NULL) == 0);
/* Figure out which bucket free entry is. */ /* Figure out which bucket free entry is. */
b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024)); b_off = bucket_off(tdb->tdb2.ftable_off, size_to_bucket(1024));
/* Lock and coalesce. */ /* Lock and coalesce. */
ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0); ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
test = layout->elem[2].base.off; test = layout->elem[2].base.off;
......
...@@ -68,9 +68,9 @@ int main(int argc, char *argv[]) ...@@ -68,9 +68,9 @@ int main(int argc, char *argv[])
/* Make sure we fill it in for later finding. */ /* Make sure we fill it in for later finding. */
off = new_off + sizeof(struct tdb_used_record); off = new_off + sizeof(struct tdb_used_record);
ok1(!tdb->methods->twrite(tdb, off, key.dptr, key.dsize)); ok1(!tdb->tdb2.io->twrite(tdb, off, key.dptr, key.dsize));
off += key.dsize; off += key.dsize;
ok1(!tdb->methods->twrite(tdb, off, dbuf.dptr, dbuf.dsize)); ok1(!tdb->tdb2.io->twrite(tdb, off, dbuf.dptr, dbuf.dsize));
/* We should be able to unlock that OK. */ /* We should be able to unlock that OK. */
ok1(tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range, ok1(tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range,
...@@ -228,9 +228,9 @@ int main(int argc, char *argv[]) ...@@ -228,9 +228,9 @@ int main(int argc, char *argv[])
/* Make sure we fill it in for later finding. */ /* Make sure we fill it in for later finding. */
off = new_off + sizeof(struct tdb_used_record); off = new_off + sizeof(struct tdb_used_record);
ok1(!tdb->methods->twrite(tdb, off, key.dptr, key.dsize)); ok1(!tdb->tdb2.io->twrite(tdb, off, key.dptr, key.dsize));
off += key.dsize; off += key.dsize;
ok1(!tdb->methods->twrite(tdb, off, dbuf.dptr, dbuf.dsize)); ok1(!tdb->tdb2.io->twrite(tdb, off, dbuf.dptr, dbuf.dsize));
/* We should be able to unlock that OK. */ /* We should be able to unlock that OK. */
ok1(tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range, ok1(tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range,
......
...@@ -9,7 +9,7 @@ static bool empty_freetable(struct tdb_context *tdb) ...@@ -9,7 +9,7 @@ static bool empty_freetable(struct tdb_context *tdb)
unsigned int i; unsigned int i;
/* Now, free table should be completely exhausted in zone 0 */ /* Now, free table should be completely exhausted in zone 0 */
if (tdb_read_convert(tdb, tdb->ftable_off, &ftab, sizeof(ftab)) != 0) if (tdb_read_convert(tdb, tdb->tdb2.ftable_off, &ftab, sizeof(ftab)) != 0)
abort(); abort();
for (i = 0; i < sizeof(ftab.buckets)/sizeof(ftab.buckets[0]); i++) { for (i = 0; i < sizeof(ftab.buckets)/sizeof(ftab.buckets[0]); i++) {
......
...@@ -41,22 +41,22 @@ int main(int argc, char *argv[]) ...@@ -41,22 +41,22 @@ int main(int argc, char *argv[])
off = get_free(tdb, 0, 80 - sizeof(struct tdb_used_record), 0, off = get_free(tdb, 0, 80 - sizeof(struct tdb_used_record), 0,
TDB_USED_MAGIC, 0); TDB_USED_MAGIC, 0);
ok1(off == layout->elem[3].base.off); ok1(off == layout->elem[3].base.off);
ok1(tdb->ftable_off == layout->elem[0].base.off); ok1(tdb->tdb2.ftable_off == layout->elem[0].base.off);
off = get_free(tdb, 0, 160 - sizeof(struct tdb_used_record), 0, off = get_free(tdb, 0, 160 - sizeof(struct tdb_used_record), 0,
TDB_USED_MAGIC, 0); TDB_USED_MAGIC, 0);
ok1(off == layout->elem[5].base.off); ok1(off == layout->elem[5].base.off);
ok1(tdb->ftable_off == layout->elem[1].base.off); ok1(tdb->tdb2.ftable_off == layout->elem[1].base.off);
off = get_free(tdb, 0, 320 - sizeof(struct tdb_used_record), 0, off = get_free(tdb, 0, 320 - sizeof(struct tdb_used_record), 0,
TDB_USED_MAGIC, 0); TDB_USED_MAGIC, 0);
ok1(off == layout->elem[7].base.off); ok1(off == layout->elem[7].base.off);
ok1(tdb->ftable_off == layout->elem[2].base.off); ok1(tdb->tdb2.ftable_off == layout->elem[2].base.off);
off = get_free(tdb, 0, 40 - sizeof(struct tdb_used_record), 0, off = get_free(tdb, 0, 40 - sizeof(struct tdb_used_record), 0,
TDB_USED_MAGIC, 0); TDB_USED_MAGIC, 0);
ok1(off == layout->elem[9].base.off); ok1(off == layout->elem[9].base.off);
ok1(tdb->ftable_off == layout->elem[0].base.off); ok1(tdb->tdb2.ftable_off == layout->elem[0].base.off);
/* Now we fail. */ /* Now we fail. */
off = get_free(tdb, 0, 0, 1, TDB_USED_MAGIC, 0); off = get_free(tdb, 0, 0, 1, TDB_USED_MAGIC, 0);
......
...@@ -6,11 +6,11 @@ ...@@ -6,11 +6,11 @@
#include <err.h> #include <err.h>
#include "tdb1-logging.h" #include "tdb1-logging.h"
static int tdb1_expand_file_sparse(struct tdb1_context *tdb, static int tdb1_expand_file_sparse(struct tdb_context *tdb,
tdb1_off_t size, tdb1_off_t size,
tdb1_off_t addition) tdb1_off_t addition)
{ {
if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) { if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) {
tdb->last_error = TDB_ERR_RDONLY; tdb->last_error = TDB_ERR_RDONLY;
return -1; return -1;
} }
...@@ -46,7 +46,7 @@ static const struct tdb1_methods large_io_methods = { ...@@ -46,7 +46,7 @@ static const struct tdb1_methods large_io_methods = {
tdb1_expand_file_sparse tdb1_expand_file_sparse
}; };
static int test_traverse(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, static int test_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data,
void *_data) void *_data)
{ {
TDB_DATA *expect = _data; TDB_DATA *expect = _data;
...@@ -59,7 +59,7 @@ static int test_traverse(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, ...@@ -59,7 +59,7 @@ static int test_traverse(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data,
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
TDB_DATA key, orig_data, data; TDB_DATA key, orig_data, data;
uint32_t hash; uint32_t hash;
tdb1_off_t rec_ptr; tdb1_off_t rec_ptr;
...@@ -70,7 +70,7 @@ int main(int argc, char *argv[]) ...@@ -70,7 +70,7 @@ int main(int argc, char *argv[])
O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
ok1(tdb); ok1(tdb);
tdb->methods = &large_io_methods; tdb->tdb1.io = &large_io_methods;
/* Enlarge the file (internally multiplies by 2). */ /* Enlarge the file (internally multiplies by 2). */
ok1(tdb1_expand(tdb, 1500000000) == 0); ok1(tdb1_expand(tdb, 1500000000) == 0);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
struct tdb1_header hdr; struct tdb1_header hdr;
int fd; int fd;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
TDB_DATA key, data; TDB_DATA key, data;
plan_tests(13); plan_tests(13);
......
...@@ -23,7 +23,7 @@ static int check(TDB_DATA key, TDB_DATA data, void *private) ...@@ -23,7 +23,7 @@ static int check(TDB_DATA key, TDB_DATA data, void *private)
return 0; return 0;
} }
static void tdb1_flip_bit(struct tdb1_context *tdb, unsigned int bit) static void tdb1_flip_bit(struct tdb_context *tdb, unsigned int bit)
{ {
unsigned int off = bit / CHAR_BIT; unsigned int off = bit / CHAR_BIT;
unsigned char mask = (1 << (bit % CHAR_BIT)); unsigned char mask = (1 << (bit % CHAR_BIT));
...@@ -40,7 +40,7 @@ static void tdb1_flip_bit(struct tdb1_context *tdb, unsigned int bit) ...@@ -40,7 +40,7 @@ static void tdb1_flip_bit(struct tdb1_context *tdb, unsigned int bit)
} }
} }
static void check_test(struct tdb1_context *tdb) static void check_test(struct tdb_context *tdb)
{ {
TDB_DATA key, data; TDB_DATA key, data;
unsigned int i, verifiable, corrupt, sizes[2], dsize, ksize; unsigned int i, verifiable, corrupt, sizes[2], dsize, ksize;
...@@ -93,7 +93,7 @@ static void check_test(struct tdb1_context *tdb) ...@@ -93,7 +93,7 @@ static void check_test(struct tdb1_context *tdb)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
plan_tests(4); plan_tests(4);
/* This should use mmap. */ /* This should use mmap. */
......
...@@ -81,7 +81,7 @@ static int ftruncate_check(int fd, off_t length) ...@@ -81,7 +81,7 @@ static int ftruncate_check(int fd, off_t length)
static bool test_death(enum operation op, struct agent *agent) static bool test_death(enum operation op, struct agent *agent)
{ {
struct tdb1_context *tdb = NULL; struct tdb_context *tdb = NULL;
TDB_DATA key; TDB_DATA key;
enum agent_return ret; enum agent_return ret;
int needed_recovery = 0; int needed_recovery = 0;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
TDB_DATA key, data; TDB_DATA key, data;
plan_tests(13); plan_tests(13);
......
...@@ -9,7 +9,7 @@ static uint64_t tdb1_dumb_hash(const void *key, size_t len, uint64_t seed, ...@@ -9,7 +9,7 @@ static uint64_t tdb1_dumb_hash(const void *key, size_t len, uint64_t seed,
return len; return len;
} }
static void log_fn(struct tdb1_context *tdb, enum tdb_log_level level, static void log_fn(struct tdb_context *tdb, enum tdb_log_level level,
enum TDB_ERROR ecode, const char *message, void *priv) enum TDB_ERROR ecode, const char *message, void *priv)
{ {
unsigned int *count = priv; unsigned int *count = priv;
...@@ -46,7 +46,7 @@ static uint64_t old_hash(const void *key, size_t len, uint64_t seed, ...@@ -46,7 +46,7 @@ static uint64_t old_hash(const void *key, size_t len, uint64_t seed,
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
unsigned int log_count, flags; unsigned int log_count, flags;
TDB_DATA d; TDB_DATA d;
struct tdb1_logging_context log_ctx = { log_fn, &log_count }; struct tdb1_logging_context log_ctx = { log_fn, &log_count };
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
TDB_DATA key, data; TDB_DATA key, data;
plan_tests(27); plan_tests(27);
......
...@@ -23,7 +23,7 @@ static bool correct_data(TDB_DATA data) ...@@ -23,7 +23,7 @@ static bool correct_data(TDB_DATA data)
&& memcmp(data.dptr, "world", data.dsize) == 0; && memcmp(data.dptr, "world", data.dsize) == 0;
} }
static int traverse2(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, static int traverse2(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data,
void *p) void *p)
{ {
ok1(correct_key(key)); ok1(correct_key(key));
...@@ -31,7 +31,7 @@ static int traverse2(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, ...@@ -31,7 +31,7 @@ static int traverse2(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data,
return 0; return 0;
} }
static int traverse1(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, static int traverse1(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data,
void *p) void *p)
{ {
ok1(correct_key(key)); ok1(correct_key(key));
...@@ -48,7 +48,7 @@ static int traverse1(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, ...@@ -48,7 +48,7 @@ static int traverse1(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data,
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
TDB_DATA key, data; TDB_DATA key, data;
plan_tests(17); plan_tests(17);
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#define NUM_ENTRIES 10 #define NUM_ENTRIES 10
static bool prepare_entries(struct tdb1_context *tdb) static bool prepare_entries(struct tdb_context *tdb)
{ {
unsigned int i; unsigned int i;
TDB_DATA key, data; TDB_DATA key, data;
...@@ -31,7 +31,7 @@ static bool prepare_entries(struct tdb1_context *tdb) ...@@ -31,7 +31,7 @@ static bool prepare_entries(struct tdb1_context *tdb)
return true; return true;
} }
static void delete_entries(struct tdb1_context *tdb) static void delete_entries(struct tdb_context *tdb)
{ {
unsigned int i; unsigned int i;
TDB_DATA key; TDB_DATA key;
...@@ -45,7 +45,7 @@ static void delete_entries(struct tdb1_context *tdb) ...@@ -45,7 +45,7 @@ static void delete_entries(struct tdb1_context *tdb)
} }
/* We don't know how many times this will run. */ /* We don't know how many times this will run. */
static int delete_other(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, static int delete_other(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data,
void *private_data) void *private_data)
{ {
unsigned int i; unsigned int i;
...@@ -57,7 +57,7 @@ static int delete_other(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, ...@@ -57,7 +57,7 @@ static int delete_other(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data,
return 0; return 0;
} }
static int delete_self(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, static int delete_self(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data,
void *private_data) void *private_data)
{ {
ok1(tdb1_delete(tdb, key) == 0); ok1(tdb1_delete(tdb, key) == 0);
...@@ -66,7 +66,7 @@ static int delete_self(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, ...@@ -66,7 +66,7 @@ static int delete_self(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data,
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
int errors = 0; int errors = 0;
plan_tests(41); plan_tests(41);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
plan_tests(8); plan_tests(8);
......
...@@ -131,7 +131,7 @@ int main(int argc, char *argv[]) ...@@ -131,7 +131,7 @@ int main(int argc, char *argv[])
const int flags[] = { TDB_DEFAULT, const int flags[] = { TDB_DEFAULT,
TDB_NOMMAP }; TDB_NOMMAP };
int i; int i;
struct tdb1_context *tdb; struct tdb_context *tdb;
TDB_DATA key, data; TDB_DATA key, data;
plan_tests(10); plan_tests(10);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
TDB_DATA key, data; TDB_DATA key, data;
plan_tests(11); plan_tests(11);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <err.h> #include <err.h>
static void log_fn(struct tdb1_context *tdb, enum tdb_log_level level, static void log_fn(struct tdb_context *tdb, enum tdb_log_level level,
enum TDB_ERROR ecode, const char *message, void *priv) enum TDB_ERROR ecode, const char *message, void *priv)
{ {
unsigned int *count = priv; unsigned int *count = priv;
...@@ -14,7 +14,7 @@ static void log_fn(struct tdb1_context *tdb, enum tdb_log_level level, ...@@ -14,7 +14,7 @@ static void log_fn(struct tdb1_context *tdb, enum tdb_log_level level,
/* The code should barf on TDBs created with rwlocks. */ /* The code should barf on TDBs created with rwlocks. */
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
unsigned int log_count; unsigned int log_count;
struct tdb1_logging_context log_ctx = { log_fn, &log_count }; struct tdb1_logging_context log_ctx = { log_fn, &log_count };
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
unsigned int i, j; unsigned int i, j;
struct tdb1_context *tdb; struct tdb_context *tdb;
int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP, int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP,
TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT, TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT,
TDB_NOMMAP|TDB_CONVERT }; TDB_NOMMAP|TDB_CONVERT };
......
...@@ -24,7 +24,7 @@ static bool correct_data(TDB_DATA data) ...@@ -24,7 +24,7 @@ static bool correct_data(TDB_DATA data)
&& memcmp(data.dptr, "world", data.dsize) == 0; && memcmp(data.dptr, "world", data.dsize) == 0;
} }
static int traverse(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, static int traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data,
void *p) void *p)
{ {
ok1(correct_key(key)); ok1(correct_key(key));
...@@ -34,7 +34,7 @@ static int traverse(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data, ...@@ -34,7 +34,7 @@ static int traverse(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data,
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
TDB_DATA key, data; TDB_DATA key, data;
plan_tests(13); plan_tests(13);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <err.h> #include <err.h>
static void log_fn(struct tdb1_context *tdb, enum tdb_log_level level, static void log_fn(struct tdb_context *tdb, enum tdb_log_level level,
enum TDB_ERROR ecode, const char *message, void *priv) enum TDB_ERROR ecode, const char *message, void *priv)
{ {
unsigned int *count = priv; unsigned int *count = priv;
...@@ -27,7 +27,7 @@ static uint64_t old_hash(const void *key, size_t len, uint64_t seed, ...@@ -27,7 +27,7 @@ static uint64_t old_hash(const void *key, size_t len, uint64_t seed,
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
unsigned int log_count; unsigned int log_count;
TDB_DATA d; TDB_DATA d;
struct tdb1_logging_context log_ctx = { log_fn, &log_count }; struct tdb1_logging_context log_ctx = { log_fn, &log_count };
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
TDB_DATA key, data; TDB_DATA key, data;
plan_tests(4); plan_tests(4);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
struct tdb1_context *tdb; struct tdb_context *tdb;
TDB_DATA key, data; TDB_DATA key, data;
plan_tests(10); plan_tests(10);
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
static struct tdb1_context *tdb; static struct tdb_context *tdb;
static enum agent_return do_operation(enum operation op, const char *name) static enum agent_return do_operation(enum operation op, const char *name)
{ {
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <stdio.h> #include <stdio.h>
/* Turn log messages into tap diag messages. */ /* Turn log messages into tap diag messages. */
static void taplog(struct tdb1_context *tdb, static void taplog(struct tdb_context *tdb,
enum tdb_log_level level, enum tdb_log_level level,
enum TDB_ERROR ecode, enum TDB_ERROR ecode,
const char *message, const char *message,
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
*/ */
#include "private.h" #include "private.h"
#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) #define SAFE_FREE(x) do { if ((x) != NULL) {free((void *)x); (x)=NULL;} } while(0)
/* /*
transaction design: transaction design:
...@@ -151,10 +151,10 @@ static enum TDB_ERROR transaction_read(struct tdb_context *tdb, tdb_off_t off, ...@@ -151,10 +151,10 @@ static enum TDB_ERROR transaction_read(struct tdb_context *tdb, tdb_off_t off,
blk = off / PAGESIZE; blk = off / PAGESIZE;
/* see if we have it in the block list */ /* see if we have it in the block list */
if (tdb->transaction->num_blocks <= blk || if (tdb->tdb2.transaction->num_blocks <= blk ||
tdb->transaction->blocks[blk] == NULL) { tdb->tdb2.transaction->blocks[blk] == NULL) {
/* nope, do a real read */ /* nope, do a real read */
ecode = tdb->transaction->io_methods->tread(tdb, off, buf, len); ecode = tdb->tdb2.transaction->io_methods->tread(tdb, off, buf, len);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
goto fail; goto fail;
} }
...@@ -162,19 +162,19 @@ static enum TDB_ERROR transaction_read(struct tdb_context *tdb, tdb_off_t off, ...@@ -162,19 +162,19 @@ static enum TDB_ERROR transaction_read(struct tdb_context *tdb, tdb_off_t off,
} }
/* it is in the block list. Now check for the last block */ /* it is in the block list. Now check for the last block */
if (blk == tdb->transaction->num_blocks-1) { if (blk == tdb->tdb2.transaction->num_blocks-1) {
if (len > tdb->transaction->last_block_size) { if (len > tdb->tdb2.transaction->last_block_size) {
ecode = TDB_ERR_IO; ecode = TDB_ERR_IO;
goto fail; goto fail;
} }
} }
/* now copy it out of this block */ /* now copy it out of this block */
memcpy(buf, tdb->transaction->blocks[blk] + (off % PAGESIZE), len); memcpy(buf, tdb->tdb2.transaction->blocks[blk] + (off % PAGESIZE), len);
return TDB_SUCCESS; return TDB_SUCCESS;
fail: fail:
tdb->transaction->transaction_error = 1; tdb->tdb2.transaction->transaction_error = 1;
return tdb_logerr(tdb, ecode, TDB_LOG_ERROR, return tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
"transaction_read: failed at off=%zu len=%zu", "transaction_read: failed at off=%zu len=%zu",
(size_t)off, (size_t)len); (size_t)off, (size_t)len);
...@@ -191,7 +191,7 @@ static enum TDB_ERROR transaction_write(struct tdb_context *tdb, tdb_off_t off, ...@@ -191,7 +191,7 @@ static enum TDB_ERROR transaction_write(struct tdb_context *tdb, tdb_off_t off,
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
/* Only a commit is allowed on a prepared transaction */ /* Only a commit is allowed on a prepared transaction */
if (tdb->transaction->prepared) { if (tdb->tdb2.transaction->prepared) {
ecode = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_ERROR, ecode = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_ERROR,
"transaction_write: transaction already" "transaction_write: transaction already"
" prepared, write not allowed"); " prepared, write not allowed");
...@@ -219,15 +219,15 @@ static enum TDB_ERROR transaction_write(struct tdb_context *tdb, tdb_off_t off, ...@@ -219,15 +219,15 @@ static enum TDB_ERROR transaction_write(struct tdb_context *tdb, tdb_off_t off,
blk = off / PAGESIZE; blk = off / PAGESIZE;
off = off % PAGESIZE; off = off % PAGESIZE;
if (tdb->transaction->num_blocks <= blk) { if (tdb->tdb2.transaction->num_blocks <= blk) {
uint8_t **new_blocks; uint8_t **new_blocks;
/* expand the blocks array */ /* expand the blocks array */
if (tdb->transaction->blocks == NULL) { if (tdb->tdb2.transaction->blocks == NULL) {
new_blocks = (uint8_t **)malloc( new_blocks = (uint8_t **)malloc(
(blk+1)*sizeof(uint8_t *)); (blk+1)*sizeof(uint8_t *));
} else { } else {
new_blocks = (uint8_t **)realloc( new_blocks = (uint8_t **)realloc(
tdb->transaction->blocks, tdb->tdb2.transaction->blocks,
(blk+1)*sizeof(uint8_t *)); (blk+1)*sizeof(uint8_t *));
} }
if (new_blocks == NULL) { if (new_blocks == NULL) {
...@@ -236,30 +236,30 @@ static enum TDB_ERROR transaction_write(struct tdb_context *tdb, tdb_off_t off, ...@@ -236,30 +236,30 @@ static enum TDB_ERROR transaction_write(struct tdb_context *tdb, tdb_off_t off,
" failed to allocate"); " failed to allocate");
goto fail; goto fail;
} }
memset(&new_blocks[tdb->transaction->num_blocks], 0, memset(&new_blocks[tdb->tdb2.transaction->num_blocks], 0,
(1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *)); (1+(blk - tdb->tdb2.transaction->num_blocks))*sizeof(uint8_t *));
tdb->transaction->blocks = new_blocks; tdb->tdb2.transaction->blocks = new_blocks;
tdb->transaction->num_blocks = blk+1; tdb->tdb2.transaction->num_blocks = blk+1;
tdb->transaction->last_block_size = 0; tdb->tdb2.transaction->last_block_size = 0;
} }
/* allocate and fill a block? */ /* allocate and fill a block? */
if (tdb->transaction->blocks[blk] == NULL) { if (tdb->tdb2.transaction->blocks[blk] == NULL) {
tdb->transaction->blocks[blk] = (uint8_t *)calloc(PAGESIZE, 1); tdb->tdb2.transaction->blocks[blk] = (uint8_t *)calloc(PAGESIZE, 1);
if (tdb->transaction->blocks[blk] == NULL) { if (tdb->tdb2.transaction->blocks[blk] == NULL) {
ecode = tdb_logerr(tdb, TDB_ERR_OOM, TDB_LOG_ERROR, ecode = tdb_logerr(tdb, TDB_ERR_OOM, TDB_LOG_ERROR,
"transaction_write:" "transaction_write:"
" failed to allocate"); " failed to allocate");
goto fail; goto fail;
} }
if (tdb->transaction->old_map_size > blk * PAGESIZE) { if (tdb->tdb2.transaction->old_map_size > blk * PAGESIZE) {
tdb_len_t len2 = PAGESIZE; tdb_len_t len2 = PAGESIZE;
if (len2 + (blk * PAGESIZE) > tdb->transaction->old_map_size) { if (len2 + (blk * PAGESIZE) > tdb->tdb2.transaction->old_map_size) {
len2 = tdb->transaction->old_map_size - (blk * PAGESIZE); len2 = tdb->tdb2.transaction->old_map_size - (blk * PAGESIZE);
} }
ecode = tdb->transaction->io_methods->tread(tdb, ecode = tdb->tdb2.transaction->io_methods->tread(tdb,
blk * PAGESIZE, blk * PAGESIZE,
tdb->transaction->blocks[blk], tdb->tdb2.transaction->blocks[blk],
len2); len2);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
ecode = tdb_logerr(tdb, ecode, ecode = tdb_logerr(tdb, ecode,
...@@ -268,31 +268,31 @@ static enum TDB_ERROR transaction_write(struct tdb_context *tdb, tdb_off_t off, ...@@ -268,31 +268,31 @@ static enum TDB_ERROR transaction_write(struct tdb_context *tdb, tdb_off_t off,
" failed to" " failed to"
" read old block: %s", " read old block: %s",
strerror(errno)); strerror(errno));
SAFE_FREE(tdb->transaction->blocks[blk]); SAFE_FREE(tdb->tdb2.transaction->blocks[blk]);
goto fail; goto fail;
} }
if (blk == tdb->transaction->num_blocks-1) { if (blk == tdb->tdb2.transaction->num_blocks-1) {
tdb->transaction->last_block_size = len2; tdb->tdb2.transaction->last_block_size = len2;
} }
} }
} }
/* overwrite part of an existing block */ /* overwrite part of an existing block */
if (buf == NULL) { if (buf == NULL) {
memset(tdb->transaction->blocks[blk] + off, 0, len); memset(tdb->tdb2.transaction->blocks[blk] + off, 0, len);
} else { } else {
memcpy(tdb->transaction->blocks[blk] + off, buf, len); memcpy(tdb->tdb2.transaction->blocks[blk] + off, buf, len);
} }
if (blk == tdb->transaction->num_blocks-1) { if (blk == tdb->tdb2.transaction->num_blocks-1) {
if (len + off > tdb->transaction->last_block_size) { if (len + off > tdb->tdb2.transaction->last_block_size) {
tdb->transaction->last_block_size = len + off; tdb->tdb2.transaction->last_block_size = len + off;
} }
} }
return TDB_SUCCESS; return TDB_SUCCESS;
fail: fail:
tdb->transaction->transaction_error = 1; tdb->tdb2.transaction->transaction_error = 1;
return ecode; return ecode;
} }
...@@ -324,21 +324,21 @@ static void transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, ...@@ -324,21 +324,21 @@ static void transaction_write_existing(struct tdb_context *tdb, tdb_off_t off,
blk = off / PAGESIZE; blk = off / PAGESIZE;
off = off % PAGESIZE; off = off % PAGESIZE;
if (tdb->transaction->num_blocks <= blk || if (tdb->tdb2.transaction->num_blocks <= blk ||
tdb->transaction->blocks[blk] == NULL) { tdb->tdb2.transaction->blocks[blk] == NULL) {
return; return;
} }
if (blk == tdb->transaction->num_blocks-1 && if (blk == tdb->tdb2.transaction->num_blocks-1 &&
off + len > tdb->transaction->last_block_size) { off + len > tdb->tdb2.transaction->last_block_size) {
if (off >= tdb->transaction->last_block_size) { if (off >= tdb->tdb2.transaction->last_block_size) {
return; return;
} }
len = tdb->transaction->last_block_size - off; len = tdb->tdb2.transaction->last_block_size - off;
} }
/* overwrite part of an existing block */ /* overwrite part of an existing block */
memcpy(tdb->transaction->blocks[blk] + off, buf, len); memcpy(tdb->tdb2.transaction->blocks[blk] + off, buf, len);
} }
...@@ -388,32 +388,32 @@ static void *transaction_direct(struct tdb_context *tdb, tdb_off_t off, ...@@ -388,32 +388,32 @@ static void *transaction_direct(struct tdb_context *tdb, tdb_off_t off,
if (write_mode) { if (write_mode) {
tdb->stats.transaction_write_direct++; tdb->stats.transaction_write_direct++;
if (blk != end_blk if (blk != end_blk
|| blk >= tdb->transaction->num_blocks || blk >= tdb->tdb2.transaction->num_blocks
|| tdb->transaction->blocks[blk] == NULL) { || tdb->tdb2.transaction->blocks[blk] == NULL) {
tdb->stats.transaction_write_direct_fail++; tdb->stats.transaction_write_direct_fail++;
return NULL; return NULL;
} }
return tdb->transaction->blocks[blk] + off % PAGESIZE; return tdb->tdb2.transaction->blocks[blk] + off % PAGESIZE;
} }
tdb->stats.transaction_read_direct++; tdb->stats.transaction_read_direct++;
/* Single which we have copied? */ /* Single which we have copied? */
if (blk == end_blk if (blk == end_blk
&& blk < tdb->transaction->num_blocks && blk < tdb->tdb2.transaction->num_blocks
&& tdb->transaction->blocks[blk]) && tdb->tdb2.transaction->blocks[blk])
return tdb->transaction->blocks[blk] + off % PAGESIZE; return tdb->tdb2.transaction->blocks[blk] + off % PAGESIZE;
/* Otherwise must be all not copied. */ /* Otherwise must be all not copied. */
while (blk <= end_blk) { while (blk <= end_blk) {
if (blk >= tdb->transaction->num_blocks) if (blk >= tdb->tdb2.transaction->num_blocks)
break; break;
if (tdb->transaction->blocks[blk]) { if (tdb->tdb2.transaction->blocks[blk]) {
tdb->stats.transaction_read_direct_fail++; tdb->stats.transaction_read_direct_fail++;
return NULL; return NULL;
} }
blk++; blk++;
} }
return tdb->transaction->io_methods->direct(tdb, off, len, false); return tdb->tdb2.transaction->io_methods->direct(tdb, off, len, false);
} }
static const struct tdb_methods transaction_methods = { static const struct tdb_methods transaction_methods = {
...@@ -459,38 +459,38 @@ static void _tdb_transaction_cancel(struct tdb_context *tdb) ...@@ -459,38 +459,38 @@ static void _tdb_transaction_cancel(struct tdb_context *tdb)
int i; int i;
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
if (tdb->transaction == NULL) { if (tdb->tdb2.transaction == NULL) {
tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb_transaction_cancel: no transaction"); "tdb_transaction_cancel: no transaction");
return; return;
} }
if (tdb->transaction->nesting != 0) { if (tdb->tdb2.transaction->nesting != 0) {
tdb->transaction->transaction_error = 1; tdb->tdb2.transaction->transaction_error = 1;
tdb->transaction->nesting--; tdb->tdb2.transaction->nesting--;
return; return;
} }
tdb->file->map_size = tdb->transaction->old_map_size; tdb->file->map_size = tdb->tdb2.transaction->old_map_size;
/* free all the transaction blocks */ /* free all the transaction blocks */
for (i=0;i<tdb->transaction->num_blocks;i++) { for (i=0;i<tdb->tdb2.transaction->num_blocks;i++) {
if (tdb->transaction->blocks[i] != NULL) { if (tdb->tdb2.transaction->blocks[i] != NULL) {
free(tdb->transaction->blocks[i]); free(tdb->tdb2.transaction->blocks[i]);
} }
} }
SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->tdb2.transaction->blocks);
if (tdb->transaction->magic_offset) { if (tdb->tdb2.transaction->magic_offset) {
const struct tdb_methods *methods = tdb->transaction->io_methods; const struct tdb_methods *methods = tdb->tdb2.transaction->io_methods;
uint64_t invalid = TDB_RECOVERY_INVALID_MAGIC; uint64_t invalid = TDB_RECOVERY_INVALID_MAGIC;
/* remove the recovery marker */ /* remove the recovery marker */
ecode = methods->twrite(tdb, tdb->transaction->magic_offset, ecode = methods->twrite(tdb, tdb->tdb2.transaction->magic_offset,
&invalid, sizeof(invalid)); &invalid, sizeof(invalid));
if (ecode == TDB_SUCCESS) if (ecode == TDB_SUCCESS)
ecode = transaction_sync(tdb, ecode = transaction_sync(tdb,
tdb->transaction->magic_offset, tdb->tdb2.transaction->magic_offset,
sizeof(invalid)); sizeof(invalid));
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
tdb_logerr(tdb, ecode, TDB_LOG_ERROR, tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
...@@ -503,14 +503,14 @@ static void _tdb_transaction_cancel(struct tdb_context *tdb) ...@@ -503,14 +503,14 @@ static void _tdb_transaction_cancel(struct tdb_context *tdb)
tdb_allrecord_unlock(tdb, tdb->file->allrecord_lock.ltype); tdb_allrecord_unlock(tdb, tdb->file->allrecord_lock.ltype);
/* restore the normal io methods */ /* restore the normal io methods */
tdb->methods = tdb->transaction->io_methods; tdb->tdb2.io = tdb->tdb2.transaction->io_methods;
tdb_transaction_unlock(tdb, F_WRLCK); tdb_transaction_unlock(tdb, F_WRLCK);
if (tdb_has_open_lock(tdb)) if (tdb_has_open_lock(tdb))
tdb_unlock_open(tdb, F_WRLCK); tdb_unlock_open(tdb, F_WRLCK);
SAFE_FREE(tdb->transaction); SAFE_FREE(tdb->tdb2.transaction);
} }
/* /*
...@@ -542,7 +542,7 @@ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb) ...@@ -542,7 +542,7 @@ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb)
} }
/* cope with nested tdb_transaction_start() calls */ /* cope with nested tdb_transaction_start() calls */
if (tdb->transaction != NULL) { if (tdb->tdb2.transaction != NULL) {
if (!(tdb->flags & TDB_ALLOW_NESTING)) { if (!(tdb->flags & TDB_ALLOW_NESTING)) {
return tdb->last_error return tdb->last_error
= tdb_logerr(tdb, TDB_ERR_IO, = tdb_logerr(tdb, TDB_ERR_IO,
...@@ -550,7 +550,7 @@ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb) ...@@ -550,7 +550,7 @@ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb)
"tdb_transaction_start:" "tdb_transaction_start:"
" already inside transaction"); " already inside transaction");
} }
tdb->transaction->nesting++; tdb->tdb2.transaction->nesting++;
tdb->stats.transaction_nest++; tdb->stats.transaction_nest++;
return 0; return 0;
} }
...@@ -567,9 +567,9 @@ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb) ...@@ -567,9 +567,9 @@ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb)
" held"); " held");
} }
tdb->transaction = (struct tdb_transaction *) tdb->tdb2.transaction = (struct tdb_transaction *)
calloc(sizeof(struct tdb_transaction), 1); calloc(sizeof(struct tdb_transaction), 1);
if (tdb->transaction == NULL) { if (tdb->tdb2.transaction == NULL) {
return tdb->last_error = tdb_logerr(tdb, TDB_ERR_OOM, return tdb->last_error = tdb_logerr(tdb, TDB_ERR_OOM,
TDB_LOG_ERROR, TDB_LOG_ERROR,
"tdb_transaction_start:" "tdb_transaction_start:"
...@@ -581,8 +581,8 @@ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb) ...@@ -581,8 +581,8 @@ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb)
make this async, which we will probably do in the future */ make this async, which we will probably do in the future */
ecode = tdb_transaction_lock(tdb, F_WRLCK); ecode = tdb_transaction_lock(tdb, F_WRLCK);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->tdb2.transaction->blocks);
SAFE_FREE(tdb->transaction); SAFE_FREE(tdb->tdb2.transaction);
return tdb->last_error = ecode; return tdb->last_error = ecode;
} }
...@@ -595,19 +595,19 @@ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb) ...@@ -595,19 +595,19 @@ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb)
/* make sure we know about any file expansions already done by /* make sure we know about any file expansions already done by
anyone else */ anyone else */
tdb->methods->oob(tdb, tdb->file->map_size + 1, true); tdb->tdb2.io->oob(tdb, tdb->file->map_size + 1, true);
tdb->transaction->old_map_size = tdb->file->map_size; tdb->tdb2.transaction->old_map_size = tdb->file->map_size;
/* finally hook the io methods, replacing them with /* finally hook the io methods, replacing them with
transaction specific methods */ transaction specific methods */
tdb->transaction->io_methods = tdb->methods; tdb->tdb2.transaction->io_methods = tdb->tdb2.io;
tdb->methods = &transaction_methods; tdb->tdb2.io = &transaction_methods;
return tdb->last_error = TDB_SUCCESS; return tdb->last_error = TDB_SUCCESS;
fail_allrecord_lock: fail_allrecord_lock:
tdb_transaction_unlock(tdb, F_WRLCK); tdb_transaction_unlock(tdb, F_WRLCK);
SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->tdb2.transaction->blocks);
SAFE_FREE(tdb->transaction); SAFE_FREE(tdb->tdb2.transaction);
return tdb->last_error = ecode; return tdb->last_error = ecode;
} }
...@@ -630,16 +630,16 @@ static tdb_len_t tdb_recovery_size(struct tdb_context *tdb) ...@@ -630,16 +630,16 @@ static tdb_len_t tdb_recovery_size(struct tdb_context *tdb)
int i; int i;
recovery_size = 0; recovery_size = 0;
for (i=0;i<tdb->transaction->num_blocks;i++) { for (i=0;i<tdb->tdb2.transaction->num_blocks;i++) {
if (i * PAGESIZE >= tdb->transaction->old_map_size) { if (i * PAGESIZE >= tdb->tdb2.transaction->old_map_size) {
break; break;
} }
if (tdb->transaction->blocks[i] == NULL) { if (tdb->tdb2.transaction->blocks[i] == NULL) {
continue; continue;
} }
recovery_size += 2*sizeof(tdb_off_t); recovery_size += 2*sizeof(tdb_off_t);
if (i == tdb->transaction->num_blocks-1) { if (i == tdb->tdb2.transaction->num_blocks-1) {
recovery_size += tdb->transaction->last_block_size; recovery_size += tdb->tdb2.transaction->last_block_size;
} else { } else {
recovery_size += PAGESIZE; recovery_size += PAGESIZE;
} }
...@@ -726,7 +726,7 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb, ...@@ -726,7 +726,7 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb,
size_t i; size_t i;
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
unsigned char *p; unsigned char *p;
const struct tdb_methods *old_methods = tdb->methods; const struct tdb_methods *old_methods = tdb->tdb2.io;
rec = malloc(sizeof(*rec) + tdb_recovery_size(tdb)); rec = malloc(sizeof(*rec) + tdb_recovery_size(tdb));
if (!rec) { if (!rec) {
...@@ -738,28 +738,28 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb, ...@@ -738,28 +738,28 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb,
/* We temporarily revert to the old I/O methods, so we can use /* We temporarily revert to the old I/O methods, so we can use
* tdb_access_read */ * tdb_access_read */
tdb->methods = tdb->transaction->io_methods; tdb->tdb2.io = tdb->tdb2.transaction->io_methods;
/* build the recovery data into a single blob to allow us to do a single /* build the recovery data into a single blob to allow us to do a single
large write, which should be more efficient */ large write, which should be more efficient */
p = (unsigned char *)(rec + 1); p = (unsigned char *)(rec + 1);
for (i=0;i<tdb->transaction->num_blocks;i++) { for (i=0;i<tdb->tdb2.transaction->num_blocks;i++) {
tdb_off_t offset; tdb_off_t offset;
tdb_len_t length; tdb_len_t length;
unsigned int off; unsigned int off;
const unsigned char *buffer; const unsigned char *buffer;
if (tdb->transaction->blocks[i] == NULL) { if (tdb->tdb2.transaction->blocks[i] == NULL) {
continue; continue;
} }
offset = i * PAGESIZE; offset = i * PAGESIZE;
length = PAGESIZE; length = PAGESIZE;
if (i == tdb->transaction->num_blocks-1) { if (i == tdb->tdb2.transaction->num_blocks-1) {
length = tdb->transaction->last_block_size; length = tdb->tdb2.transaction->last_block_size;
} }
if (offset >= tdb->transaction->old_map_size) { if (offset >= tdb->tdb2.transaction->old_map_size) {
continue; continue;
} }
...@@ -770,9 +770,9 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb, ...@@ -770,9 +770,9 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb,
" boundary"); " boundary");
goto fail; goto fail;
} }
if (offset + length > tdb->transaction->old_map_size) { if (offset + length > tdb->tdb2.transaction->old_map_size) {
/* Short read at EOF. */ /* Short read at EOF. */
length = tdb->transaction->old_map_size - offset; length = tdb->tdb2.transaction->old_map_size - offset;
} }
buffer = tdb_access_read(tdb, offset, length, false); buffer = tdb_access_read(tdb, offset, length, false);
if (TDB_PTR_IS_ERR(buffer)) { if (TDB_PTR_IS_ERR(buffer)) {
...@@ -781,14 +781,14 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb, ...@@ -781,14 +781,14 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb,
} }
/* Skip over anything the same at the start. */ /* Skip over anything the same at the start. */
off = same(tdb->transaction->blocks[i], buffer, length); off = same(tdb->tdb2.transaction->blocks[i], buffer, length);
offset += off; offset += off;
while (off < length) { while (off < length) {
tdb_len_t len; tdb_len_t len;
unsigned int samelen; unsigned int samelen;
len = different(tdb->transaction->blocks[i] + off, len = different(tdb->tdb2.transaction->blocks[i] + off,
buffer + off, length - off, buffer + off, length - off,
sizeof(offset) + sizeof(len) + 1, sizeof(offset) + sizeof(len) + 1,
&samelen); &samelen);
...@@ -806,12 +806,12 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb, ...@@ -806,12 +806,12 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb,
} }
*len = p - (unsigned char *)(rec + 1); *len = p - (unsigned char *)(rec + 1);
tdb->methods = old_methods; tdb->tdb2.io = old_methods;
return rec; return rec;
fail: fail:
free(rec); free(rec);
tdb->methods = old_methods; tdb->tdb2.io = old_methods;
return TDB_ERR_PTR(ecode); return TDB_ERR_PTR(ecode);
} }
...@@ -822,7 +822,7 @@ static tdb_off_t create_recovery_area(struct tdb_context *tdb, ...@@ -822,7 +822,7 @@ static tdb_off_t create_recovery_area(struct tdb_context *tdb,
tdb_off_t off, recovery_off; tdb_off_t off, recovery_off;
tdb_len_t addition; tdb_len_t addition;
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
const struct tdb_methods *methods = tdb->transaction->io_methods; const struct tdb_methods *methods = tdb->tdb2.transaction->io_methods;
/* round up to a multiple of page size. Overallocate, since each /* round up to a multiple of page size. Overallocate, since each
* such allocation forces us to expand the file. */ * such allocation forces us to expand the file. */
...@@ -836,9 +836,9 @@ static tdb_off_t create_recovery_area(struct tdb_context *tdb, ...@@ -836,9 +836,9 @@ static tdb_off_t create_recovery_area(struct tdb_context *tdb,
Also so that we don't try to expand the file again in the Also so that we don't try to expand the file again in the
transaction commit, which would destroy the recovery transaction commit, which would destroy the recovery
area */ area */
addition = (tdb->file->map_size - tdb->transaction->old_map_size) + addition = (tdb->file->map_size - tdb->tdb2.transaction->old_map_size) +
sizeof(*rec) + rec->max_len; sizeof(*rec) + rec->max_len;
tdb->file->map_size = tdb->transaction->old_map_size; tdb->file->map_size = tdb->tdb2.transaction->old_map_size;
tdb->stats.transaction_expand_file++; tdb->stats.transaction_expand_file++;
ecode = methods->expand_file(tdb, addition); ecode = methods->expand_file(tdb, addition);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
...@@ -850,7 +850,7 @@ static tdb_off_t create_recovery_area(struct tdb_context *tdb, ...@@ -850,7 +850,7 @@ static tdb_off_t create_recovery_area(struct tdb_context *tdb,
/* we have to reset the old map size so that we don't try to /* we have to reset the old map size so that we don't try to
expand the file again in the transaction commit, which expand the file again in the transaction commit, which
would destroy the recovery area */ would destroy the recovery area */
tdb->transaction->old_map_size = tdb->file->map_size; tdb->tdb2.transaction->old_map_size = tdb->file->map_size;
/* write the recovery header offset and sync - we can sync without a race here /* write the recovery header offset and sync - we can sync without a race here
as the magic ptr in the recovery record has not been set */ as the magic ptr in the recovery record has not been set */
...@@ -876,9 +876,9 @@ static enum TDB_ERROR transaction_setup_recovery(struct tdb_context *tdb) ...@@ -876,9 +876,9 @@ static enum TDB_ERROR transaction_setup_recovery(struct tdb_context *tdb)
{ {
tdb_len_t recovery_size = 0; tdb_len_t recovery_size = 0;
tdb_off_t recovery_off = 0; tdb_off_t recovery_off = 0;
tdb_off_t old_map_size = tdb->transaction->old_map_size; tdb_off_t old_map_size = tdb->tdb2.transaction->old_map_size;
struct tdb_recovery_record *recovery; struct tdb_recovery_record *recovery;
const struct tdb_methods *methods = tdb->transaction->io_methods; const struct tdb_methods *methods = tdb->tdb2.transaction->io_methods;
uint64_t magic; uint64_t magic;
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
...@@ -950,21 +950,21 @@ static enum TDB_ERROR transaction_setup_recovery(struct tdb_context *tdb) ...@@ -950,21 +950,21 @@ static enum TDB_ERROR transaction_setup_recovery(struct tdb_context *tdb)
magic = TDB_RECOVERY_MAGIC; magic = TDB_RECOVERY_MAGIC;
tdb_convert(tdb, &magic, sizeof(magic)); tdb_convert(tdb, &magic, sizeof(magic));
tdb->transaction->magic_offset tdb->tdb2.transaction->magic_offset
= recovery_off + offsetof(struct tdb_recovery_record, magic); = recovery_off + offsetof(struct tdb_recovery_record, magic);
ecode = methods->twrite(tdb, tdb->transaction->magic_offset, ecode = methods->twrite(tdb, tdb->tdb2.transaction->magic_offset,
&magic, sizeof(magic)); &magic, sizeof(magic));
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
return tdb_logerr(tdb, ecode, TDB_LOG_ERROR, return tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
"tdb_transaction_setup_recovery:" "tdb_transaction_setup_recovery:"
" failed to write recovery magic"); " failed to write recovery magic");
} }
transaction_write_existing(tdb, tdb->transaction->magic_offset, transaction_write_existing(tdb, tdb->tdb2.transaction->magic_offset,
&magic, sizeof(magic)); &magic, sizeof(magic));
/* ensure the recovery magic marker is on disk */ /* ensure the recovery magic marker is on disk */
return transaction_sync(tdb, tdb->transaction->magic_offset, return transaction_sync(tdb, tdb->tdb2.transaction->magic_offset,
sizeof(magic)); sizeof(magic));
} }
...@@ -973,20 +973,20 @@ static enum TDB_ERROR _tdb_transaction_prepare_commit(struct tdb_context *tdb) ...@@ -973,20 +973,20 @@ static enum TDB_ERROR _tdb_transaction_prepare_commit(struct tdb_context *tdb)
const struct tdb_methods *methods; const struct tdb_methods *methods;
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
if (tdb->transaction == NULL) { if (tdb->tdb2.transaction == NULL) {
return tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, return tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb_transaction_prepare_commit:" "tdb_transaction_prepare_commit:"
" no transaction"); " no transaction");
} }
if (tdb->transaction->prepared) { if (tdb->tdb2.transaction->prepared) {
_tdb_transaction_cancel(tdb); _tdb_transaction_cancel(tdb);
return tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR, return tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb_transaction_prepare_commit:" "tdb_transaction_prepare_commit:"
" transaction already prepared"); " transaction already prepared");
} }
if (tdb->transaction->transaction_error) { if (tdb->tdb2.transaction->transaction_error) {
_tdb_transaction_cancel(tdb); _tdb_transaction_cancel(tdb);
return tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_ERROR, return tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_ERROR,
"tdb_transaction_prepare_commit:" "tdb_transaction_prepare_commit:"
...@@ -994,16 +994,16 @@ static enum TDB_ERROR _tdb_transaction_prepare_commit(struct tdb_context *tdb) ...@@ -994,16 +994,16 @@ static enum TDB_ERROR _tdb_transaction_prepare_commit(struct tdb_context *tdb)
} }
if (tdb->transaction->nesting != 0) { if (tdb->tdb2.transaction->nesting != 0) {
return TDB_SUCCESS; return TDB_SUCCESS;
} }
/* check for a null transaction */ /* check for a null transaction */
if (tdb->transaction->blocks == NULL) { if (tdb->tdb2.transaction->blocks == NULL) {
return TDB_SUCCESS; return TDB_SUCCESS;
} }
methods = tdb->transaction->io_methods; methods = tdb->tdb2.transaction->io_methods;
/* upgrade the main transaction lock region to a write lock */ /* upgrade the main transaction lock region to a write lock */
ecode = tdb_allrecord_upgrade(tdb, TDB_HASH_LOCK_START); ecode = tdb_allrecord_upgrade(tdb, TDB_HASH_LOCK_START);
...@@ -1020,23 +1020,23 @@ static enum TDB_ERROR _tdb_transaction_prepare_commit(struct tdb_context *tdb) ...@@ -1020,23 +1020,23 @@ static enum TDB_ERROR _tdb_transaction_prepare_commit(struct tdb_context *tdb)
/* Since we have whole db locked, we don't need the expansion lock. */ /* Since we have whole db locked, we don't need the expansion lock. */
if (!(tdb->flags & TDB_NOSYNC)) { if (!(tdb->flags & TDB_NOSYNC)) {
/* Sets up tdb->transaction->recovery and /* Sets up tdb->tdb2.transaction->recovery and
* tdb->transaction->magic_offset. */ * tdb->tdb2.transaction->magic_offset. */
ecode = transaction_setup_recovery(tdb); ecode = transaction_setup_recovery(tdb);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
return ecode; return ecode;
} }
} }
tdb->transaction->prepared = true; tdb->tdb2.transaction->prepared = true;
/* expand the file to the new size if needed */ /* expand the file to the new size if needed */
if (tdb->file->map_size != tdb->transaction->old_map_size) { if (tdb->file->map_size != tdb->tdb2.transaction->old_map_size) {
tdb_len_t add; tdb_len_t add;
add = tdb->file->map_size - tdb->transaction->old_map_size; add = tdb->file->map_size - tdb->tdb2.transaction->old_map_size;
/* Restore original map size for tdb_expand_file */ /* Restore original map size for tdb_expand_file */
tdb->file->map_size = tdb->transaction->old_map_size; tdb->file->map_size = tdb->tdb2.transaction->old_map_size;
ecode = methods->expand_file(tdb, add); ecode = methods->expand_file(tdb, add);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
return ecode; return ecode;
...@@ -1064,7 +1064,7 @@ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb) ...@@ -1064,7 +1064,7 @@ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb)
int i; int i;
enum TDB_ERROR ecode; enum TDB_ERROR ecode;
if (tdb->transaction == NULL) { if (tdb->tdb2.transaction == NULL) {
return tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, return tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL,
TDB_LOG_USE_ERROR, TDB_LOG_USE_ERROR,
"tdb_transaction_commit:" "tdb_transaction_commit:"
...@@ -1073,18 +1073,18 @@ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb) ...@@ -1073,18 +1073,18 @@ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb)
tdb_trace(tdb, "tdb_transaction_commit"); tdb_trace(tdb, "tdb_transaction_commit");
if (tdb->transaction->nesting != 0) { if (tdb->tdb2.transaction->nesting != 0) {
tdb->transaction->nesting--; tdb->tdb2.transaction->nesting--;
return tdb->last_error = TDB_SUCCESS; return tdb->last_error = TDB_SUCCESS;
} }
/* check for a null transaction */ /* check for a null transaction */
if (tdb->transaction->blocks == NULL) { if (tdb->tdb2.transaction->blocks == NULL) {
_tdb_transaction_cancel(tdb); _tdb_transaction_cancel(tdb);
return tdb->last_error = TDB_SUCCESS; return tdb->last_error = TDB_SUCCESS;
} }
if (!tdb->transaction->prepared) { if (!tdb->tdb2.transaction->prepared) {
ecode = _tdb_transaction_prepare_commit(tdb); ecode = _tdb_transaction_prepare_commit(tdb);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
_tdb_transaction_cancel(tdb); _tdb_transaction_cancel(tdb);
...@@ -1092,41 +1092,41 @@ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb) ...@@ -1092,41 +1092,41 @@ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb)
} }
} }
methods = tdb->transaction->io_methods; methods = tdb->tdb2.transaction->io_methods;
/* perform all the writes */ /* perform all the writes */
for (i=0;i<tdb->transaction->num_blocks;i++) { for (i=0;i<tdb->tdb2.transaction->num_blocks;i++) {
tdb_off_t offset; tdb_off_t offset;
tdb_len_t length; tdb_len_t length;
if (tdb->transaction->blocks[i] == NULL) { if (tdb->tdb2.transaction->blocks[i] == NULL) {
continue; continue;
} }
offset = i * PAGESIZE; offset = i * PAGESIZE;
length = PAGESIZE; length = PAGESIZE;
if (i == tdb->transaction->num_blocks-1) { if (i == tdb->tdb2.transaction->num_blocks-1) {
length = tdb->transaction->last_block_size; length = tdb->tdb2.transaction->last_block_size;
} }
ecode = methods->twrite(tdb, offset, ecode = methods->twrite(tdb, offset,
tdb->transaction->blocks[i], length); tdb->tdb2.transaction->blocks[i], length);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
/* we've overwritten part of the data and /* we've overwritten part of the data and
possibly expanded the file, so we need to possibly expanded the file, so we need to
run the crash recovery code */ run the crash recovery code */
tdb->methods = methods; tdb->tdb2.io = methods;
tdb_transaction_recover(tdb); tdb_transaction_recover(tdb);
_tdb_transaction_cancel(tdb); _tdb_transaction_cancel(tdb);
return tdb->last_error = ecode; return tdb->last_error = ecode;
} }
SAFE_FREE(tdb->transaction->blocks[i]); SAFE_FREE(tdb->tdb2.transaction->blocks[i]);
} }
SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->tdb2.transaction->blocks);
tdb->transaction->num_blocks = 0; tdb->tdb2.transaction->num_blocks = 0;
/* ensure the new data is on disk */ /* ensure the new data is on disk */
ecode = transaction_sync(tdb, 0, tdb->file->map_size); ecode = transaction_sync(tdb, 0, tdb->file->map_size);
...@@ -1151,7 +1151,7 @@ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb) ...@@ -1151,7 +1151,7 @@ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb)
/* use a transaction cancel to free memory and remove the /* use a transaction cancel to free memory and remove the
transaction locks: it "restores" map_size, too. */ transaction locks: it "restores" map_size, too. */
tdb->transaction->old_map_size = tdb->file->map_size; tdb->tdb2.transaction->old_map_size = tdb->file->map_size;
_tdb_transaction_cancel(tdb); _tdb_transaction_cancel(tdb);
return tdb->last_error = TDB_SUCCESS; return tdb->last_error = TDB_SUCCESS;
...@@ -1212,7 +1212,7 @@ enum TDB_ERROR tdb_transaction_recover(struct tdb_context *tdb) ...@@ -1212,7 +1212,7 @@ enum TDB_ERROR tdb_transaction_recover(struct tdb_context *tdb)
} }
/* read the full recovery data */ /* read the full recovery data */
ecode = tdb->methods->tread(tdb, recovery_head + sizeof(rec), data, ecode = tdb->tdb2.io->tread(tdb, recovery_head + sizeof(rec), data,
rec.len); rec.len);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
return tdb_logerr(tdb, ecode, TDB_LOG_ERROR, return tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
...@@ -1230,7 +1230,7 @@ enum TDB_ERROR tdb_transaction_recover(struct tdb_context *tdb) ...@@ -1230,7 +1230,7 @@ enum TDB_ERROR tdb_transaction_recover(struct tdb_context *tdb)
memcpy(&len, p + sizeof(ofs), sizeof(len)); memcpy(&len, p + sizeof(ofs), sizeof(len));
p += sizeof(ofs) + sizeof(len); p += sizeof(ofs) + sizeof(len);
ecode = tdb->methods->twrite(tdb, ofs, p, len); ecode = tdb->tdb2.io->twrite(tdb, ofs, p, len);
if (ecode != TDB_SUCCESS) { if (ecode != TDB_SUCCESS) {
free(data); free(data);
return tdb_logerr(tdb, ecode, TDB_LOG_ERROR, return tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
......
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