1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

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.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
(Imported from CCAN commit bbeb528e74c0e234e1f724ac8d54be404cfc6f9a)
This commit is contained in:
Rusty Russell 2011-09-14 07:43:13 +09:30
parent 997592431f
commit c16184f83b
44 changed files with 848 additions and 913 deletions

View File

@ -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)
+ sizeof(struct tdb_used_record),
false);
@ -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++) {
char c;
ecode = tdb->methods->tread(tdb, off, &c, 1);
ecode = tdb->tdb2.io->tread(tdb, off, &c, 1);
if (ecode != TDB_SUCCESS) {
return ecode;
}

View File

@ -65,8 +65,8 @@ enum TDB_ERROR tdb_ftable_init(struct tdb_context *tdb)
unsigned int rnd, max = 0, count = 0;
tdb_off_t off;
tdb->ftable_off = off = first_ftable(tdb);
tdb->ftable = 0;
tdb->tdb2.ftable_off = off = first_ftable(tdb);
tdb->tdb2.ftable = 0;
while (off) {
if (TDB_OFF_IS_ERR(off)) {
@ -75,8 +75,8 @@ enum TDB_ERROR tdb_ftable_init(struct tdb_context *tdb)
rnd = random();
if (rnd >= max) {
tdb->ftable_off = off;
tdb->ftable = count;
tdb->tdb2.ftable_off = off;
tdb->tdb2.ftable = count;
max = rnd;
}
@ -218,7 +218,7 @@ static enum TDB_ERROR enqueue_in_free(struct tdb_context *tdb,
return head;
/* 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;
/* new->next = head. */
@ -287,8 +287,8 @@ static tdb_off_t ftable_offset(struct tdb_context *tdb, unsigned int ftable)
tdb_off_t off;
unsigned int i;
if (likely(tdb->ftable == ftable))
return tdb->ftable_off;
if (likely(tdb->tdb2.ftable == ftable))
return tdb->tdb2.ftable_off;
off = first_ftable(tdb);
for (i = 0; i < ftable; i++) {
@ -595,7 +595,7 @@ enum TDB_ERROR add_free_record(struct tdb_context *tdb,
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);
if (ecode != TDB_SUCCESS) {
return ecode;
@ -606,7 +606,7 @@ enum TDB_ERROR add_free_record(struct tdb_context *tdb,
/* Coalescing unlocks free list. */
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
tdb_unlock_free_bucket(tdb, b_off);
return ecode;
@ -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. */
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);
if (ecode != TDB_SUCCESS) {
goto unlock_err;
@ -800,9 +800,9 @@ static tdb_off_t get_free(struct tdb_context *tdb,
else
start_b = size_to_bucket(adjust_size(keylen, datalen));
ftable_off = tdb->ftable_off;
ftable = tdb->ftable;
while (!wrapped || ftable_off != tdb->ftable_off) {
ftable_off = tdb->tdb2.ftable_off;
ftable = tdb->tdb2.ftable;
while (!wrapped || ftable_off != tdb->tdb2.ftable_off) {
/* Start at exact size bucket, and search up... */
for (b = find_free_head(tdb, ftable_off, start_b);
b < TDB_FREE_BUCKETS;
@ -819,8 +819,8 @@ static tdb_off_t get_free(struct tdb_context *tdb,
if (b == TDB_FREE_BUCKETS - 1)
tdb->stats.alloc_bucket_max++;
/* Worked? Stay using this list. */
tdb->ftable_off = ftable_off;
tdb->ftable = ftable;
tdb->tdb2.ftable_off = ftable_off;
tdb->tdb2.ftable = ftable;
return off;
}
/* Didn't work. Try next bucket. */
@ -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. */
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) {
tdb_unlock_expand(tdb, F_WRLCK);
return TDB_SUCCESS;
@ -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. */
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) {
tdb_unlock_expand(tdb, F_WRLCK);
return ecode;
@ -950,7 +950,7 @@ tdb_off_t alloc(struct tdb_context *tdb, size_t keylen, size_t datalen,
tdb_off_t off;
/* We can't hold pointers during this: we could unmap! */
assert(!tdb->direct_access);
assert(!tdb->tdb2.direct_access);
for (;;) {
enum TDB_ERROR ecode;

View File

@ -88,7 +88,7 @@ static enum TDB_ERROR tdb_oob(struct tdb_context *tdb, tdb_off_t len,
enum TDB_ERROR ecode;
/* We can't hold pointers during this: we could unmap! */
assert(!tdb->direct_access
assert(!tdb->tdb2.direct_access
|| (tdb->flags & TDB_NOLOCK)
|| tdb_has_expansion_lock(tdb));
@ -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)
{
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;
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)
}
while (len) {
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) {
break;
}
@ -226,7 +226,7 @@ tdb_off_t tdb_read_off(struct tdb_context *tdb, tdb_off_t off)
enum TDB_ERROR ecode;
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);
if (TDB_PTR_IS_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,
"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) {
return ecode;
}
@ -283,7 +283,7 @@ static enum TDB_ERROR tdb_read(struct tdb_context *tdb, tdb_off_t off,
{
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) {
return ecode;
}
@ -317,11 +317,11 @@ enum TDB_ERROR tdb_write_convert(struct tdb_context *tdb, tdb_off_t off,
" %zu bytes", len);
}
memcpy(conv, rec, len);
ecode = tdb->methods->twrite(tdb, off,
ecode = tdb->tdb2.io->twrite(tdb, off,
tdb_convert(tdb, conv, len), len);
free(conv);
} else {
ecode = tdb->methods->twrite(tdb, off, rec, len);
ecode = tdb->tdb2.io->twrite(tdb, off, rec, len);
}
return ecode;
}
@ -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,
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);
return ecode;
}
@ -343,7 +343,7 @@ enum TDB_ERROR tdb_write_off(struct tdb_context *tdb,
}
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);
if (TDB_PTR_IS_ERR(p)) {
return TDB_PTR_ERR(p);
@ -370,7 +370,7 @@ static void *_tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset,
(size_t)(prefix + len));
return TDB_ERR_PTR(TDB_ERR_OOM);
} 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)) {
free(buf);
return TDB_ERR_PTR(ecode);
@ -459,7 +459,7 @@ const void *tdb_access_read(struct tdb_context *tdb,
void *ret = NULL;
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)) {
return ret;
@ -471,14 +471,14 @@ const void *tdb_access_read(struct tdb_context *tdb,
if (TDB_PTR_IS_ERR(hdr)) {
return hdr;
}
hdr->next = tdb->access;
tdb->access = hdr;
hdr->next = tdb->tdb2.access;
tdb->tdb2.access = hdr;
ret = hdr + 1;
if (convert) {
tdb_convert(tdb, (void *)ret, len);
}
} else
tdb->direct_access++;
tdb->tdb2.direct_access++;
return ret;
}
@ -495,7 +495,7 @@ void *tdb_access_write(struct tdb_context *tdb,
}
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)) {
return ret;
@ -508,8 +508,8 @@ void *tdb_access_write(struct tdb_context *tdb,
if (TDB_PTR_IS_ERR(hdr)) {
return hdr;
}
hdr->next = tdb->access;
tdb->access = hdr;
hdr->next = tdb->tdb2.access;
tdb->tdb2.access = hdr;
hdr->off = off;
hdr->len = len;
hdr->convert = convert;
@ -517,7 +517,7 @@ void *tdb_access_write(struct tdb_context *tdb,
if (convert)
tdb_convert(tdb, (void *)ret, len);
} else
tdb->direct_access++;
tdb->tdb2.direct_access++;
return ret;
}
@ -526,7 +526,7 @@ static struct tdb_access_hdr **find_hdr(struct tdb_context *tdb, const void *p)
{
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)
return hp;
}
@ -542,7 +542,7 @@ void tdb_access_release(struct tdb_context *tdb, const void *p)
*hp = hdr->next;
free(hdr);
} else
tdb->direct_access--;
tdb->tdb2.direct_access--;
}
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;
free(hdr);
} else {
tdb->direct_access--;
tdb->tdb2.direct_access--;
ecode = TDB_SUCCESS;
}
@ -587,7 +587,7 @@ void tdb_inc_seqnum(struct tdb_context *tdb)
if (likely(!(tdb->flags & TDB_CONVERT))) {
int64_t *direct;
direct = tdb->methods->direct(tdb,
direct = tdb->tdb2.io->direct(tdb,
offsetof(struct tdb_header,
seqnum),
sizeof(*direct), true);
@ -622,5 +622,5 @@ static const struct tdb_methods io_methods = {
*/
void tdb_io_init(struct tdb_context *tdb)
{
tdb->methods = &io_methods;
tdb->tdb2.io = &io_methods;
}

View File

@ -363,11 +363,8 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
} else {
tdb->name = NULL;
}
tdb->direct_access = 0;
tdb->flags = tdb_flags;
tdb->log_fn = NULL;
tdb->transaction = NULL;
tdb->access = NULL;
tdb->open_flags = open_flags;
tdb->last_error = TDB_SUCCESS;
tdb->file = NULL;
@ -379,6 +376,9 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
tdb->stats.base.attr = TDB_ATTRIBUTE_STATS;
tdb->stats.size = sizeof(tdb->stats);
tdb_io_init(tdb);
tdb->tdb2.direct_access = 0;
tdb->tdb2.transaction = NULL;
tdb->tdb2.access = NULL;
while (attr) {
switch (attr->base.attr) {
@ -573,7 +573,7 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
tdb_unlock_open(tdb, openlock);
/* 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))
goto fail;
@ -655,7 +655,7 @@ int tdb_close(struct tdb_context *tdb)
tdb_trace(tdb, "tdb_close");
if (tdb->transaction) {
if (tdb->tdb2.transaction) {
tdb_transaction_cancel(tdb);
}

View File

@ -283,6 +283,9 @@ struct traverse_info {
tdb_off_t prev;
};
typedef uint32_t tdb1_len_t;
typedef uint32_t tdb1_off_t;
enum tdb_lock_flags {
/* WAIT == F_SETLKW, NOWAIT == F_SETLK */
TDB_LOCK_NOWAIT = 0,
@ -333,68 +336,6 @@ struct tdb_file {
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 {
enum TDB_ERROR (*tread)(struct tdb_context *, tdb_off_t, void *,
tdb_len_t);
@ -600,6 +541,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);
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: */
enum TDB_ERROR COLD tdb_logerr(struct tdb_context *tdb,
enum TDB_ERROR ecode,

View File

@ -72,13 +72,13 @@ static enum TDB_ERROR replace_data(struct tdb_context *tdb,
}
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) {
return ecode;
}
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) {
return ecode;
}
@ -96,10 +96,10 @@ static enum TDB_ERROR update_data(struct tdb_context *tdb,
{
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) {
/* 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)
tdb_inc_seqnum(tdb);
@ -213,7 +213,7 @@ enum TDB_ERROR tdb_append(struct tdb_context *tdb,
+ dbuf.dsize));
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);
if (ecode != TDB_SUCCESS) {
goto out_free_newdata;
@ -326,9 +326,17 @@ unsigned int tdb_get_flags(struct tdb_context *tdb)
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)
{
if (tdb->transaction) {
if (inside_transaction(tdb)) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL,
TDB_LOG_USE_ERROR,
"%s: can't change"

View File

@ -36,11 +36,8 @@
#endif
/** This is the context structure that is returned from a db open. */
typedef struct tdb1_context TDB1_CONTEXT;
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,
typedef int (*tdb1_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *);
typedef void (*tdb1_log_func)(struct tdb_context *, enum tdb_log_level, enum TDB_ERROR,
const char *, void *);
typedef uint64_t (*tdb1_hash_func)(const void *key, size_t len, uint64_t seed,
void *data);
@ -50,84 +47,84 @@ struct tdb1_logging_context {
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);
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,
const struct tdb1_logging_context *log_ctx,
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,
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 *);
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),
void *private_data);
/* @} ******************************************************************/
/* Low level locking functions: use with care */
int tdb1_chainlock(struct tdb1_context *tdb, TDB_DATA key);
int tdb1_chainunlock(struct tdb1_context *tdb, TDB_DATA key);
int tdb1_chainlock_read(struct tdb1_context *tdb, TDB_DATA key);
int tdb1_chainunlock_read(struct tdb1_context *tdb, TDB_DATA key);
int tdb1_chainlock(struct tdb_context *tdb, TDB_DATA key);
int tdb1_chainunlock(struct tdb_context *tdb, TDB_DATA key);
int tdb1_chainlock_read(struct tdb_context *tdb, TDB_DATA key);
int tdb1_chainunlock_read(struct tdb_context *tdb, TDB_DATA key);
/* wipe and repack */
int tdb1_wipe_all(struct tdb1_context *tdb);
int tdb1_repack(struct tdb1_context *tdb);
int tdb1_wipe_all(struct tdb_context *tdb);
int tdb1_repack(struct tdb_context *tdb);
/* 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;

View File

@ -25,12 +25,12 @@
#include "tdb1_private.h"
/* 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;
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;
if (strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0)
goto corrupt;
@ -50,11 +50,11 @@ static bool tdb1_check_header(struct tdb1_context *tdb, tdb1_off_t *recovery)
if (hdr.hash_size == 0)
goto corrupt;
if (hdr.hash_size != tdb->header.hash_size)
if (hdr.hash_size != tdb->tdb1.header.hash_size)
goto corrupt;
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;
*recovery = hdr.recovery_start;
@ -67,14 +67,14 @@ corrupt:
}
/* 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,
const struct tdb1_record *rec)
{
tdb1_off_t tailer;
/* 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,
"Record offset %d too small next %d\n",
off, rec->next);
@ -92,7 +92,7 @@ static bool tdb1_check_record(struct tdb1_context *tdb,
off, rec->next);
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;
/* Check rec_len: similar to rec->next, implies next record. */
@ -110,7 +110,7 @@ static bool tdb1_check_record(struct tdb1_context *tdb,
goto corrupt;
}
/* 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;
/* Check tailer. */
@ -132,14 +132,14 @@ corrupt:
/* Grab some bytes: may copy if can't use mmap.
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)
{
TDB_DATA d;
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;
else
d.dptr = tdb1_alloc_read(tdb, off, d.dsize);
@ -147,9 +147,9 @@ static TDB_DATA get_bytes(struct tdb1_context *tdb,
}
/* 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;
free(d.dptr);
}
@ -232,7 +232,7 @@ static void record_offset(unsigned char bits[], tdb1_off_t off)
}
/* 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,
const struct tdb1_record *rec,
unsigned char **hashes,
@ -291,7 +291,7 @@ fail_put_key:
}
/* 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,
const struct tdb1_record *rec,
unsigned char **hashes)
@ -308,13 +308,13 @@ static bool tdb1_check_free_record(struct tdb1_context *tdb,
}
/* 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;
for (len = 0; off + len < tdb->file->map_size; len++) {
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;
if (c != 0 && c != 0x42)
break;
@ -322,7 +322,7 @@ size_t tdb1_dead_space(struct tdb1_context *tdb, tdb1_off_t off)
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),
void *private_data)
{
@ -344,14 +344,14 @@ int tdb1_check(struct tdb1_context *tdb,
}
/* 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. */
if (!tdb1_check_header(tdb, &recovery_start))
goto unlock;
/* 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,
"File too short for hashes\n");
goto unlock;
@ -359,20 +359,20 @@ int tdb1_check(struct tdb1_context *tdb,
/* One big malloc: pointers then bit arrays. */
hashes = (unsigned char **)calloc(
1, sizeof(hashes[0]) * (1+tdb->header.hash_size)
+ BITMAP_BITS / CHAR_BIT * (1+tdb->header.hash_size));
1, sizeof(hashes[0]) * (1+tdb->tdb1.header.hash_size)
+ BITMAP_BITS / CHAR_BIT * (1+tdb->tdb1.header.hash_size));
if (!hashes) {
tdb->last_error = TDB_ERR_OOM;
goto unlock;
}
/* Initialize pointers */
hashes[0] = (unsigned char *)(&hashes[1+tdb->header.hash_size]);
for (h = 1; h < 1+tdb->header.hash_size; h++)
hashes[0] = (unsigned char *)(&hashes[1+tdb->tdb1.header.hash_size]);
for (h = 1; h < 1+tdb->tdb1.header.hash_size; h++)
hashes[h] = hashes[h-1] + BITMAP_BITS / CHAR_BIT;
/* 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),
&off) == -1)
goto free;
@ -381,10 +381,10 @@ int tdb1_check(struct tdb1_context *tdb,
}
/* 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 += 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)
goto free;
switch (rec.magic) {
@ -434,7 +434,7 @@ int tdb1_check(struct tdb1_context *tdb,
/* Now, hashes should all be empty: each record exists and is referred
* 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;
for (i = 0; i < BITMAP_BITS / CHAR_BIT; i++) {
if (hashes[h][i] != 0) {

View File

@ -28,9 +28,9 @@
#include "tdb1_private.h"
/* 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;
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
"tdb1_rec_free_read non-free magic 0x%x at offset=%d - fixing\n",
rec->magic, off);
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;
}
@ -50,14 +50,14 @@ int tdb1_rec_free_read(struct tdb1_context *tdb, tdb1_off_t off, struct tdb1_rec
rec->magic, off);
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 0;
}
/* 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)
{
tdb1_off_t totalsize;
@ -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
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 */
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
}
/* 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);
struct tdb1_record l;
tdb1_off_t leftsize;
@ -104,12 +104,12 @@ int tdb1_free(struct tdb1_context *tdb, tdb1_off_t offset, struct tdb1_record *r
left = offset - leftsize;
if (leftsize > offset ||
left < TDB1_DATA_START(tdb->header.hash_size)) {
left < TDB1_DATA_START(tdb->tdb1.header.hash_size)) {
goto update;
}
/* 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,
"tdb1_free: left read failed at %u (%u)", left, leftsize);
goto update;
@ -169,7 +169,7 @@ update:
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
*/
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,
struct tdb1_record *rec, tdb1_off_t last_ptr)
{
@ -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
*/
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;
struct {

View File

@ -36,7 +36,7 @@
if necessary
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;
if (len <= tdb->file->map_size)
@ -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 */
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)
{
if (len == 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;
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;
if (tdb->file->map_ptr) {
@ -133,10 +133,10 @@ void *tdb1_convert(void *buf, uint32_t size)
/* 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)
{
if (tdb->methods->tdb1_oob(tdb, off + len, 0) != 0) {
if (tdb->tdb1.io->tdb1_oob(tdb, off + len, 0) != 0) {
return -1;
}
@ -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
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;
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)) {
break;
}
}
} else {
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) {
break;
}
@ -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)
return 0;
@ -206,7 +206,7 @@ int tdb1_munmap(struct tdb1_context *tdb)
return 0;
}
void tdb1_mmap(struct tdb1_context *tdb)
void tdb1_mmap(struct tdb_context *tdb)
{
if (tdb->flags & TDB_INTERNAL)
return;
@ -243,11 +243,11 @@ void tdb1_mmap(struct tdb1_context *tdb)
/* expand a file. we prefer to use ftruncate, as that is what posix
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];
if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) {
if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) {
tdb->last_error = TDB_ERR_RDONLY;
return -1;
}
@ -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
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;
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)
}
/* 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
* 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)
/* Round the database up to a multiple of the page 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))
tdb1_munmap(tdb);
@ -359,7 +359,7 @@ int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size)
/* expand the file itself */
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;
}
@ -401,20 +401,20 @@ int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size)
}
/* 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;
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 */
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;
@ -427,7 +427,7 @@ unsigned char *tdb1_alloc_read(struct tdb1_context *tdb, tdb1_off_t offset, tdb1
len, strerror(errno));
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);
return NULL;
}
@ -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 */
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,
int (*parser)(TDB_DATA key, TDB_DATA data,
void *private_data),
@ -447,12 +447,12 @@ int tdb1_parse_data(struct tdb1_context *tdb, TDB_DATA key,
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
* 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;
}
data.dptr = offset + (unsigned char *)tdb->file->map_ptr;
@ -469,9 +469,9 @@ int tdb1_parse_data(struct tdb1_context *tdb, TDB_DATA key,
}
/* 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;
if (TDB1_BAD_MAGIC(rec)) {
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
rec->magic, offset);
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;
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 = {
@ -499,7 +499,7 @@ static const struct tdb1_methods io1_methods = {
/*
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;
}

View File

@ -41,7 +41,7 @@ static tdb1_off_t lock_offset(int list)
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,
enum tdb_lock_flags flags)
{
@ -53,7 +53,7 @@ int tdb1_brlock(struct tdb1_context *tdb,
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)
{
enum TDB_ERROR ecode = tdb_brunlock(tdb, rw_type, offset, len);
@ -63,7 +63,7 @@ int tdb1_brunlock(struct tdb1_context *tdb,
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);
if (ecode == TDB_SUCCESS)
@ -72,7 +72,7 @@ int tdb1_allrecord_upgrade(struct tdb1_context *tdb)
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)
{
unsigned int i;
@ -86,12 +86,12 @@ static struct tdb_lock *tdb1_find_nestlock(struct tdb1_context *tdb,
}
/* 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_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,
"tdb1_lock: invalid offset %u for"
" ltype=%d",
@ -107,7 +107,7 @@ int tdb1_nest_lock(struct tdb1_context *tdb, uint32_t offset, int ltype,
return 0;
}
static int tdb1_lock_and_recover(struct tdb1_context *tdb)
static int tdb1_lock_and_recover(struct tdb_context *tdb)
{
int ret;
@ -131,7 +131,7 @@ static int tdb1_lock_and_recover(struct tdb1_context *tdb)
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;
@ -142,7 +142,7 @@ static bool have_data_locks(const struct tdb1_context *tdb)
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)
{
int ret;
@ -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 */
int tdb1_lock(struct tdb1_context *tdb, int list, int ltype)
int tdb1_lock(struct tdb_context *tdb, int list, int ltype)
{
int ret;
@ -189,15 +189,15 @@ int tdb1_lock(struct tdb1_context *tdb, int list, int ltype)
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;
/* 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,
"tdb1_unlock: offset %u invalid (%d)",
offset, tdb->header.hash_size);
offset, tdb->tdb1.header.hash_size);
return -1;
}
@ -209,7 +209,7 @@ int tdb1_nest_unlock(struct tdb1_context *tdb, uint32_t offset, int ltype)
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 */
if (tdb->file->allrecord_lock.count &&
@ -228,7 +228,7 @@ int tdb1_unlock(struct tdb1_context *tdb, int list, int ltype)
/*
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)
{
return tdb1_nest_lock(tdb, TDB1_TRANSACTION_LOCK, ltype, lockflags);
@ -237,7 +237,7 @@ int tdb1_transaction_lock(struct tdb1_context *tdb, int ltype,
/*
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);
}
@ -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
* other way of guaranteeing exclusivity (ie. transaction write lock).
* 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_ERROR ecode;
/* tdb_lock_gradual() doesn't know about tdb->traverse_read. */
if (tdb->traverse_read && !(tdb->flags & TDB_NOLOCK)) {
/* tdb_lock_gradual() doesn't know about tdb->tdb1.traverse_read. */
if (tdb->tdb1.traverse_read && !(tdb->flags & TDB_NOLOCK)) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK,
TDB_LOG_USE_ERROR,
"tdb1_allrecord_lock during"
@ -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
* gradual for that. */
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) {
tdb->last_error = ecode;
return -1;
}
/* 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) {
tdb1_brunlock(tdb, ltype, TDB1_FREELIST_TOP,
tdb->header.hash_size * 4);
tdb->tdb1.header.hash_size * 4);
return -1;
}
@ -327,10 +327,10 @@ int tdb1_allrecord_lock(struct tdb1_context *tdb, int ltype,
/* 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! */
if (tdb->traverse_read) {
if (tdb->tdb1.traverse_read) {
tdb->last_error = TDB_ERR_LOCK;
return -1;
}
@ -365,32 +365,32 @@ int tdb1_allrecord_unlock(struct tdb1_context *tdb, int ltype)
}
/* 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);
}
/* 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);
}
/* 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);
}
/* 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);
}
/* lock/unlock one hash chain. This is meant to be used to reduce
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,
TDB1_BUCKET(tdb_hash(tdb, key.dptr, key.dsize)),
@ -398,13 +398,13 @@ int tdb1_chainlock(struct tdb1_context *tdb, TDB_DATA key)
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)),
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;
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)
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)),
F_RDLCK);
}
/* 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) {
return 0;
@ -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
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;
for (i = &tdb->travlocks; i; i = i->next)
for (i = &tdb->tdb1.travlocks; i; i = i->next)
if (i->off == off)
return -1;
if (tdb->file->allrecord_lock.count) {
@ -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);
}
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) {
return 0;
@ -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 */
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;
uint32_t count = 0;
@ -467,18 +467,18 @@ int tdb1_unlock_record(struct tdb1_context *tdb, tdb1_off_t off)
if (off == 0)
return 0;
for (i = &tdb->travlocks; i; i = i->next)
for (i = &tdb->tdb1.travlocks; i; i = i->next)
if (i->off == off)
count++;
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;
/* 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;
}
@ -488,7 +488,7 @@ bool tdb1_have_extra_locks(struct tdb1_context *tdb)
}
/* In a transaction, we expect to hold the transaction lock */
if (tdb->transaction
if (tdb->tdb1.transaction
&& tdb1_find_nestlock(tdb, TDB1_TRANSACTION_LOCK)) {
extra--;
}
@ -497,7 +497,7 @@ bool tdb1_have_extra_locks(struct tdb1_context *tdb)
}
/* 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;

View File

@ -28,10 +28,10 @@
#include "tdb1_private.h"
/* 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. */
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 tdb1_magic = TDB1_MAGIC;
@ -45,7 +45,7 @@ void tdb1_header_hash(struct tdb1_context *tdb,
}
/* 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;
size_t size;
@ -73,7 +73,7 @@ static int tdb1_new_database(struct tdb1_context *tdb, int hash_size)
tdb->file->fd = -1;
tdb->file->map_size = size;
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. */
TDB1_CONV(*newdb);
return 0;
@ -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 */
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! */
memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
/* we still have "ret == -1" here */
@ -103,7 +103,7 @@ static int tdb1_new_database(struct tdb1_context *tdb, int hash_size)
static int tdb1_already_open(dev_t device,
ino_t ino)
{
struct tdb1_context *i;
struct tdb_context *i;
for (i = tdb1s; i; i = i->next) {
if (i->file->device == device && i->file->inode == ino) {
@ -124,21 +124,21 @@ static int tdb1_already_open(dev_t device,
try to call tdb1_error or tdb1_errname, just do strerror(errno).
@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)
{
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)
{
tdb1_header_hash(tdb, m1, m2);
return (tdb->header.magic1_hash == *m1 &&
tdb->header.magic2_hash == *m2);
return (tdb->tdb1.header.magic1_hash == *m1 &&
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)
{
if (hash_correct(tdb, m1, m2))
@ -154,19 +154,19 @@ static bool check_header_hash(struct tdb1_context *tdb,
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,
const struct tdb1_logging_context *log_ctx,
tdb1_hash_func hash_fn)
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
struct stat st;
int rev = 0;
unsigned v;
const char *hash_alg;
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 */
errno = ENOMEM;
goto fail;
@ -231,13 +231,13 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag
}
/* cache the page size */
tdb->page_size = getpagesize();
if (tdb->page_size <= 0) {
tdb->page_size = 0x2000;
tdb->tdb1.page_size = getpagesize();
if (tdb->tdb1.page_size <= 0) {
tdb->tdb1.page_size = 0x2000;
}
/* 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) {
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
}
errno = 0;
if (read(tdb->file->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
|| strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0) {
if (read(tdb->file->fd, &tdb->tdb1.header, sizeof(tdb->tdb1.header)) != sizeof(tdb->tdb1.header)
|| strcmp(tdb->tdb1.header.magic_food, TDB_MAGIC_FOOD) != 0) {
if (!(open_flags & O_CREAT) || tdb1_new_database(tdb, hash_size) == -1) {
if (errno == 0) {
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
goto fail;
}
rev = (tdb->flags & TDB_CONVERT);
} else if (tdb->header.version != TDB1_VERSION
&& !(rev = (tdb->header.version==TDB1_BYTEREV(TDB1_VERSION)))) {
} else if (tdb->tdb1.header.version != TDB1_VERSION
&& !(rev = (tdb->tdb1.header.version==TDB1_BYTEREV(TDB1_VERSION)))) {
/* wrong version */
errno = EIO;
goto fail;
@ -305,19 +305,19 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag
tdb->flags &= ~TDB_CONVERT;
else {
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)
goto fail;
if (tdb->header.rwlocks != 0 &&
tdb->header.rwlocks != TDB1_HASH_RWLOCK_MAGIC) {
if (tdb->tdb1.header.rwlocks != 0 &&
tdb->tdb1.header.rwlocks != TDB1_HASH_RWLOCK_MAGIC) {
tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
"tdb1_open_ex: spinlocks no longer supported");
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 */
tdb->hash_fn = tdb1_old_hash;
} 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
"magic1_hash[0x%08X %s 0x%08X] "
"magic2_hash[0x%08X %s 0x%08X]",
name, hash_alg,
tdb->header.magic1_hash,
(tdb->header.magic1_hash == magic1) ? "==" : "!=",
tdb->tdb1.header.magic1_hash,
(tdb->tdb1.header.magic1_hash == magic1) ? "==" : "!=",
magic1,
tdb->header.magic2_hash,
(tdb->header.magic2_hash == magic2) ? "==" : "!=",
tdb->tdb1.header.magic2_hash,
(tdb->tdb1.header.magic2_hash == magic2) ? "==" : "!=",
magic2);
errno = EINVAL;
goto fail;
@ -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
*/
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)
*
* @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;
if (tdb->transaction) {
if (tdb->tdb1.transaction) {
tdb1_transaction_cancel(tdb);
}

View File

@ -28,44 +28,6 @@
#include "private.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>
/* #define TDB_TRACE 1 */
@ -85,9 +47,6 @@
#define __location__ __FILE__ ":" __STRINGSTRING(__LINE__)
#endif
typedef uint32_t tdb1_len_t;
typedef uint32_t tdb1_off_t;
#ifndef offsetof
#define offsetof(t,f) ((unsigned int)&((t *)0)->f)
#endif
@ -107,7 +66,7 @@ typedef uint32_t tdb1_off_t;
#define TDB1_DEAD(r) ((r)->magic == TDB1_DEAD_MAGIC)
#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_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_RECOVERY_HEAD offsetof(struct tdb1_header, recovery_start)
#define TDB1_SEQNUM_OFS offsetof(struct tdb1_header, sequence_number)
@ -121,10 +80,10 @@ typedef uint32_t tdb1_off_t;
/* free memory if the pointer is valid and zero the pointer */
#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
#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_CONV(x) (TDB1_DOCONV() ? tdb1_convert(&x, sizeof(x)) : &x)
@ -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 {
int (*tdb1_read)(struct tdb1_context *, tdb1_off_t , void *, tdb1_len_t , int );
int (*tdb1_write)(struct tdb1_context *, tdb1_off_t, const void *, tdb1_len_t);
void (*next_hash_chain)(struct tdb1_context *, uint32_t *);
int (*tdb1_oob)(struct tdb1_context *, tdb1_off_t , int );
int (*tdb1_expand_file)(struct tdb1_context *, tdb1_off_t , tdb1_off_t );
int (*tdb1_read)(struct tdb_context *, tdb1_off_t , void *, tdb1_len_t , int );
int (*tdb1_write)(struct tdb_context *, tdb1_off_t, const void *, tdb1_len_t);
void (*next_hash_chain)(struct tdb_context *, uint32_t *);
int (*tdb1_oob)(struct tdb_context *, tdb1_off_t , int );
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
*/
int tdb1_munmap(struct tdb1_context *tdb);
void tdb1_mmap(struct tdb1_context *tdb);
int tdb1_lock(struct tdb1_context *tdb, int list, int ltype);
int tdb1_nest_lock(struct tdb1_context *tdb, uint32_t offset, int ltype,
int tdb1_munmap(struct tdb_context *tdb);
void tdb1_mmap(struct tdb_context *tdb);
int tdb1_lock(struct tdb_context *tdb, int list, int ltype);
int tdb1_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype,
enum tdb_lock_flags flags);
int tdb1_nest_unlock(struct tdb1_context *tdb, uint32_t offset, int ltype);
int tdb1_unlock(struct tdb1_context *tdb, int list, int ltype);
int tdb1_brlock(struct tdb1_context *tdb,
int tdb1_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype);
int tdb1_unlock(struct tdb_context *tdb, int list, int ltype);
int tdb1_brlock(struct tdb_context *tdb,
int rw_type, tdb1_off_t offset, size_t len,
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);
bool tdb1_have_extra_locks(struct tdb1_context *tdb);
void tdb1_release_transaction_locks(struct tdb1_context *tdb);
int tdb1_transaction_lock(struct tdb1_context *tdb, int ltype,
bool tdb1_have_extra_locks(struct tdb_context *tdb);
void tdb1_release_transaction_locks(struct tdb_context *tdb);
int tdb1_transaction_lock(struct tdb_context *tdb, int ltype,
enum tdb_lock_flags lockflags);
int tdb1_transaction_unlock(struct tdb1_context *tdb, int ltype);
int tdb1_recovery_area(struct tdb1_context *tdb,
int tdb1_transaction_unlock(struct tdb_context *tdb, int ltype);
int tdb1_recovery_area(struct tdb_context *tdb,
const struct tdb1_methods *methods,
tdb1_off_t *recovery_offset,
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);
int tdb1_allrecord_unlock(struct tdb1_context *tdb, int ltype);
int tdb1_allrecord_upgrade(struct tdb1_context *tdb);
int tdb1_write_lock_record(struct tdb1_context *tdb, tdb1_off_t off);
int tdb1_write_unlock_record(struct tdb1_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_write(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_off_t *d);
int tdb1_allrecord_unlock(struct tdb_context *tdb, int ltype);
int tdb1_allrecord_upgrade(struct tdb_context *tdb);
int tdb1_write_lock_record(struct tdb_context *tdb, tdb1_off_t off);
int tdb1_write_unlock_record(struct tdb_context *tdb, tdb1_off_t off);
int tdb1_ofs_read(struct tdb_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);
int tdb1_free(struct tdb1_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);
int tdb1_ofs_read(struct tdb1_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_lock_record(struct tdb1_context *tdb, tdb1_off_t off);
int tdb1_unlock_record(struct tdb1_context *tdb, tdb1_off_t off);
bool tdb1_needs_recovery(struct tdb1_context *tdb);
int tdb1_rec_read(struct tdb1_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_do_delete(struct tdb1_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);
int tdb1_parse_data(struct tdb1_context *tdb, TDB_DATA key,
int tdb1_free(struct tdb_context *tdb, tdb1_off_t offset, 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 tdb_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 tdb_context *tdb, tdb1_off_t off);
int tdb1_unlock_record(struct tdb_context *tdb, tdb1_off_t off);
bool tdb1_needs_recovery(struct tdb_context *tdb);
int tdb1_rec_read(struct tdb_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 tdb_context *tdb, tdb1_off_t rec_ptr, struct tdb1_record *rec);
unsigned char *tdb1_alloc_read(struct tdb_context *tdb, tdb1_off_t offset, tdb1_len_t len);
int tdb1_parse_data(struct tdb_context *tdb, TDB_DATA key,
tdb1_off_t offset, tdb1_len_t len,
int (*parser)(TDB_DATA key, TDB_DATA 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);
void tdb1_io_init(struct tdb1_context *tdb);
int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size);
int tdb1_rec_free_read(struct tdb1_context *tdb, tdb1_off_t off,
void tdb1_io_init(struct tdb_context *tdb);
int tdb1_expand(struct tdb_context *tdb, tdb1_off_t size);
int tdb1_rec_free_read(struct tdb_context *tdb, tdb1_off_t off,
struct tdb1_record *rec);
bool tdb1_write_all(int fd, const void *buf, size_t count);
int tdb1_transaction_recover(struct tdb1_context *tdb);
void tdb1_header_hash(struct tdb1_context *tdb,
int tdb1_transaction_recover(struct tdb_context *tdb);
void tdb1_header_hash(struct tdb_context *tdb,
uint32_t *magic1_hash, uint32_t *magic2_hash);
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 */

View File

@ -65,7 +65,7 @@ static size_t tally1_mean(const struct tally *tally)
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;
size_t count = 0;
@ -84,7 +84,7 @@ static size_t get_hash_length(struct tdb1_context *tdb, unsigned int i)
return count;
}
char *tdb1_summary(struct tdb1_context *tdb)
char *tdb1_summary(struct tdb_context *tdb)
{
tdb1_off_t off, rec_off;
struct tally freet, keys, data, dead, extra, hash, uncoal;
@ -103,7 +103,7 @@ char *tdb1_summary(struct tdb1_context *tdb)
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;
}
@ -115,10 +115,10 @@ char *tdb1_summary(struct tdb1_context *tdb)
tally1_init(&hash);
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 += 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)
goto unlock;
switch (rec.magic) {
@ -160,7 +160,7 @@ char *tdb1_summary(struct tdb1_context *tdb)
if (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));
/* 20 is max length of a %zu. */
@ -191,7 +191,7 @@ char *tdb1_summary(struct tdb1_context *tdb)
(keys.num + freet.num + dead.num)
* (sizeof(struct tdb1_record) + sizeof(uint32_t))
* 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);
unlock:

View File

@ -33,7 +33,7 @@ TDB_DATA tdb1_null;
non-blocking increment of the tdb sequence number if the tdb has been opened using
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;
@ -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
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)) {
return;
@ -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
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)
{
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
}
/* 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)
{
uint32_t rec_ptr;
@ -123,13 +123,13 @@ tdb1_off_t tdb1_find_lock_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t
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
is <= the old data size and the key exists.
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;
tdb1_off_t rec_ptr;
@ -162,7 +162,7 @@ static int tdb1_update_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
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)
return -1;
@ -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
* 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;
struct tdb1_record rec;
@ -200,7 +200,7 @@ static TDB_DATA _tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key)
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);
@ -225,7 +225,7 @@ TDB_DATA tdb1_fetch(struct tdb1_context *tdb, TDB_DATA key)
* 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,
void *private_data),
void *private_data)
@ -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
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;
@ -268,7 +268,7 @@ static int tdb1_exists_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
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);
int ret;
@ -278,14 +278,14 @@ int tdb1_exists(struct tdb1_context *tdb, TDB_DATA key)
}
/* 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;
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) {
/* Someone traversing here: mark it as dead */
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
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;
tdb1_off_t rec_ptr;
@ -338,7 +338,7 @@ static int tdb1_count_dead(struct tdb1_context *tdb, uint32_t hash)
/*
* 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;
struct tdb1_record rec;
@ -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 */
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;
struct tdb1_record rec;
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
@ -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)
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,
* delete all existing dead records
@ -427,7 +427,7 @@ static int tdb1_delete_hash(struct tdb1_context *tdb, TDB_DATA key, uint32_t has
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);
int ret;
@ -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
*/
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)
{
tdb1_off_t rec_ptr;
@ -465,7 +465,7 @@ static tdb1_off_t tdb1_find_dead(struct tdb1_context *tdb, uint32_t hash,
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)
{
struct tdb1_record rec;
@ -512,7 +512,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
if (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
* 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,
rec.full_hash = hash;
rec.magic = TDB1_MAGIC;
if (tdb1_rec_write(tdb, rec_ptr, &rec) == -1
|| tdb->methods->tdb1_write(
|| tdb->tdb1.io->tdb1_write(
tdb, rec_ptr + sizeof(rec),
p, key.dsize + dbuf.dsize) == -1) {
goto fail;
@ -548,7 +548,7 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
goto fail;
}
if ((tdb->max_dead_records != 0)
if ((tdb->tdb1.max_dead_records != 0)
&& (tdb1_purge_dead(tdb, hash) == -1)) {
tdb1_unlock(tdb, -1, F_WRLCK);
goto fail;
@ -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 */
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) {
/* Need to tdb1_unallocate() here */
goto fail;
@ -596,12 +596,12 @@ static int _tdb1_store(struct tdb1_context *tdb, TDB_DATA key,
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;
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;
return -1;
}
@ -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. */
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;
TDB_DATA dbuf;
@ -673,7 +673,7 @@ failed:
The aim of this sequence number is to allow for a very lightweight
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;
@ -681,9 +681,9 @@ int tdb1_get_seqnum(struct tdb1_context *tdb)
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)
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
*/
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;
if (length <= sizeof(rec)) {
@ -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
*/
int tdb1_wipe_all(struct tdb1_context *tdb)
int tdb1_wipe_all(struct tdb_context *tdb)
{
int i;
tdb1_off_t offset = 0;
@ -746,7 +746,7 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
if (recovery_head != 0) {
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,
"tdb1_wipe_all: failed to read recovery record");
return -1;
@ -755,7 +755,7 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
}
/* 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) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_wipe_all: failed to write hash %d", i);
@ -774,8 +774,8 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
for the recovery area */
if (recovery_size == 0) {
/* 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));
if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->header.hash_size), data_len) != 0) {
data_len = (tdb->file->map_size - TDB1_DATA_START(tdb->tdb1.header.hash_size));
if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->tdb1.header.hash_size), data_len) != 0) {
goto failed;
}
} else {
@ -787,8 +787,8 @@ int tdb1_wipe_all(struct tdb1_context *tdb)
move the recovery area or we risk subtle data
corruption
*/
data_len = (recovery_head - TDB1_DATA_START(tdb->header.hash_size));
if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->header.hash_size), data_len) != 0) {
data_len = (recovery_head - TDB1_DATA_START(tdb->tdb1.header.hash_size));
if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->tdb1.header.hash_size), data_len) != 0) {
goto failed;
}
/* and the 2nd free list entry after the recovery area - if any */
@ -813,13 +813,13 @@ failed:
struct traverse_state {
enum TDB_ERROR error;
struct tdb1_context *dest_db;
struct tdb_context *dest_db;
};
/*
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;
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
/*
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;
if (tdb1_transaction_start(tdb) != 0) {

View File

@ -138,14 +138,14 @@ struct tdb1_transaction {
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
*/
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)
{
uint32_t blk;
/* break it down into block sized ops */
while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) {
tdb1_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size);
while (len + (off % tdb->tdb1.transaction->block_size) > tdb->tdb1.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) {
return -1;
}
@ -158,27 +158,27 @@ static int transaction1_read(struct tdb1_context *tdb, tdb1_off_t off, void *buf
return 0;
}
blk = off / tdb->transaction->block_size;
blk = off / tdb->tdb1.transaction->block_size;
/* see if we have it in the block list */
if (tdb->transaction->num_blocks <= blk ||
tdb->transaction->blocks[blk] == NULL) {
if (tdb->tdb1.transaction->num_blocks <= blk ||
tdb->tdb1.transaction->blocks[blk] == NULL) {
/* 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;
}
return 0;
}
/* it is in the block list. Now check for the last block */
if (blk == tdb->transaction->num_blocks-1) {
if (len > tdb->transaction->last_block_size) {
if (blk == tdb->tdb1.transaction->num_blocks-1) {
if (len > tdb->tdb1.transaction->last_block_size) {
goto fail;
}
}
/* 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) {
tdb1_convert(buf, len);
}
@ -188,7 +188,7 @@ fail:
tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR,
"transaction_read: failed at off=%d len=%d",
off, len);
tdb->transaction->transaction_error = 1;
tdb->tdb1.transaction->transaction_error = 1;
return -1;
}
@ -196,17 +196,17 @@ fail:
/*
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)
{
uint32_t blk;
/* 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,
"transaction_write: transaction already"
" prepared, write not allowed");
tdb->transaction->transaction_error = 1;
tdb->tdb1.transaction->transaction_error = 1;
return -1;
}
@ -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 &&
off < TDB1_FREELIST_TOP+TDB1_HASHTABLE_SIZE(tdb)) {
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 */
while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) {
tdb1_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size);
while (len + (off % tdb->tdb1.transaction->block_size) > tdb->tdb1.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) {
return -1;
}
@ -235,66 +235,66 @@ static int transaction1_write(struct tdb1_context *tdb, tdb1_off_t off,
return 0;
}
blk = off / tdb->transaction->block_size;
off = off % tdb->transaction->block_size;
blk = off / tdb->tdb1.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;
/* expand the blocks array */
if (tdb->transaction->blocks == NULL) {
if (tdb->tdb1.transaction->blocks == NULL) {
new_blocks = (uint8_t **)malloc(
(blk+1)*sizeof(uint8_t *));
} else {
new_blocks = (uint8_t **)realloc(
tdb->transaction->blocks,
tdb->tdb1.transaction->blocks,
(blk+1)*sizeof(uint8_t *));
}
if (new_blocks == NULL) {
tdb->last_error = TDB_ERR_OOM;
goto fail;
}
memset(&new_blocks[tdb->transaction->num_blocks], 0,
(1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *));
tdb->transaction->blocks = new_blocks;
tdb->transaction->num_blocks = blk+1;
tdb->transaction->last_block_size = 0;
memset(&new_blocks[tdb->tdb1.transaction->num_blocks], 0,
(1+(blk - tdb->tdb1.transaction->num_blocks))*sizeof(uint8_t *));
tdb->tdb1.transaction->blocks = new_blocks;
tdb->tdb1.transaction->num_blocks = blk+1;
tdb->tdb1.transaction->last_block_size = 0;
}
/* allocate and fill a block? */
if (tdb->transaction->blocks[blk] == NULL) {
tdb->transaction->blocks[blk] = (uint8_t *)calloc(tdb->transaction->block_size, 1);
if (tdb->transaction->blocks[blk] == NULL) {
if (tdb->tdb1.transaction->blocks[blk] == NULL) {
tdb->tdb1.transaction->blocks[blk] = (uint8_t *)calloc(tdb->tdb1.transaction->block_size, 1);
if (tdb->tdb1.transaction->blocks[blk] == NULL) {
tdb->last_error = TDB_ERR_OOM;
tdb->transaction->transaction_error = 1;
tdb->tdb1.transaction->transaction_error = 1;
return -1;
}
if (tdb->transaction->old_map_size > blk * tdb->transaction->block_size) {
tdb1_len_t len2 = tdb->transaction->block_size;
if (len2 + (blk * tdb->transaction->block_size) > tdb->transaction->old_map_size) {
len2 = 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->tdb1.transaction->block_size;
if (len2 + (blk * tdb->tdb1.transaction->block_size) > tdb->tdb1.transaction->old_map_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,
tdb->transaction->blocks[blk],
if (tdb->tdb1.transaction->io_methods->tdb1_read(tdb, blk * tdb->tdb1.transaction->block_size,
tdb->tdb1.transaction->blocks[blk],
len2, 0) != 0) {
SAFE_FREE(tdb->transaction->blocks[blk]);
SAFE_FREE(tdb->tdb1.transaction->blocks[blk]);
tdb->last_error = TDB_ERR_IO;
goto fail;
}
if (blk == tdb->transaction->num_blocks-1) {
tdb->transaction->last_block_size = len2;
if (blk == tdb->tdb1.transaction->num_blocks-1) {
tdb->tdb1.transaction->last_block_size = len2;
}
}
}
/* overwrite part of an existing block */
if (buf == NULL) {
memset(tdb->transaction->blocks[blk] + off, 0, len);
memset(tdb->tdb1.transaction->blocks[blk] + off, 0, len);
} 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 (len + off > tdb->transaction->last_block_size) {
tdb->transaction->last_block_size = len + off;
if (blk == tdb->tdb1.transaction->num_blocks-1) {
if (len + off > tdb->tdb1.transaction->last_block_size) {
tdb->tdb1.transaction->last_block_size = len + off;
}
}
@ -303,8 +303,8 @@ static int transaction1_write(struct tdb1_context *tdb, tdb1_off_t off,
fail:
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"transaction_write: failed at off=%d len=%d",
(blk*tdb->transaction->block_size) + off, len);
tdb->transaction->transaction_error = 1;
(blk*tdb->tdb1.transaction->block_size) + off, len);
tdb->tdb1.transaction->transaction_error = 1;
return -1;
}
@ -313,14 +313,14 @@ fail:
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
*/
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)
{
uint32_t blk;
/* break it up into block sized chunks */
while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) {
tdb1_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size);
while (len + (off % tdb->tdb1.transaction->block_size) > tdb->tdb1.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) {
return -1;
}
@ -335,24 +335,24 @@ static int transaction1_write_existing(struct tdb1_context *tdb, tdb1_off_t off,
return 0;
}
blk = off / tdb->transaction->block_size;
off = off % tdb->transaction->block_size;
blk = off / tdb->tdb1.transaction->block_size;
off = off % tdb->tdb1.transaction->block_size;
if (tdb->transaction->num_blocks <= blk ||
tdb->transaction->blocks[blk] == NULL) {
if (tdb->tdb1.transaction->num_blocks <= blk ||
tdb->tdb1.transaction->blocks[blk] == NULL) {
return 0;
}
if (blk == tdb->transaction->num_blocks-1 &&
off + len > tdb->transaction->last_block_size) {
if (off >= tdb->transaction->last_block_size) {
if (blk == tdb->tdb1.transaction->num_blocks-1 &&
off + len > tdb->tdb1.transaction->last_block_size) {
if (off >= tdb->tdb1.transaction->last_block_size) {
return 0;
}
len = tdb->transaction->last_block_size - off;
len = tdb->tdb1.transaction->last_block_size - off;
}
/* 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;
}
@ -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
*/
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;
for (;h < tdb->header.hash_size;h++) {
for (;h < tdb->tdb1.header.hash_size;h++) {
/* 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;
}
}
@ -376,7 +376,7 @@ static void transaction1_next_hash_chain(struct tdb1_context *tdb, uint32_t *cha
/*
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) {
return 0;
@ -388,7 +388,7 @@ static int transaction1_oob(struct tdb1_context *tdb, tdb1_off_t len, int probe)
/*
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)
{
/* 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,
return -1;
}
tdb->transaction->expanded = true;
tdb->tdb1.transaction->expanded = true;
return 0;
}
@ -413,12 +413,12 @@ static const struct tdb1_methods transaction1_methods = {
/*
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 */
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,
"tdb1_transaction_start: cannot start a"
" transaction on a read-only or"
@ -427,12 +427,12 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb)
}
/* cope with nested tdb1_transaction_start() calls */
if (tdb->transaction != NULL) {
if (tdb->tdb1.transaction != NULL) {
if (!(tdb->flags & TDB_ALLOW_NESTING)) {
tdb->last_error = TDB_ERR_EINVAL;
return -1;
}
tdb->transaction->nesting++;
tdb->tdb1.transaction->nesting++;
return 0;
}
@ -446,7 +446,7 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb)
return -1;
}
if (tdb->travlocks.next != NULL) {
if (tdb->tdb1.travlocks.next != NULL) {
/* you cannot use transactions inside a traverse (although you can use
traverse inside a transaction) as otherwise you can end up with
deadlock */
@ -456,22 +456,22 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb)
return -1;
}
tdb->transaction = (struct tdb1_transaction *)
tdb->tdb1.transaction = (struct tdb1_transaction *)
calloc(sizeof(struct tdb1_transaction), 1);
if (tdb->transaction == NULL) {
if (tdb->tdb1.transaction == NULL) {
tdb->last_error = TDB_ERR_OOM;
return -1;
}
/* 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
discussed with Volker, there are a number of ways we could
make this async, which we will probably do in the future */
if (tdb1_transaction_lock(tdb, F_WRLCK, TDB_LOCK_WAIT) == -1) {
SAFE_FREE(tdb->transaction->blocks);
SAFE_FREE(tdb->transaction);
SAFE_FREE(tdb->tdb1.transaction->blocks);
SAFE_FREE(tdb->tdb1.transaction);
return -1;
}
@ -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
traverse can be fast */
tdb->transaction->hash_heads = (uint32_t *)
calloc(tdb->header.hash_size+1, sizeof(uint32_t));
if (tdb->transaction->hash_heads == NULL) {
tdb->tdb1.transaction->hash_heads = (uint32_t *)
calloc(tdb->tdb1.header.hash_size+1, sizeof(uint32_t));
if (tdb->tdb1.transaction->hash_heads == NULL) {
tdb->last_error = TDB_ERR_OOM;
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) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_start: failed to read hash heads");
@ -503,13 +503,13 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb)
/* make sure we know about any file expansions already done by
anyone else */
tdb->methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1);
tdb->transaction->old_map_size = tdb->file->map_size;
tdb->tdb1.io->tdb1_oob(tdb, tdb->file->map_size + 1, 1);
tdb->tdb1.transaction->old_map_size = tdb->file->map_size;
/* finally hook the io methods, replacing them with
transaction specific methods */
tdb->transaction->io_methods = tdb->methods;
tdb->methods = &transaction1_methods;
tdb->tdb1.transaction->io_methods = tdb->tdb1.io;
tdb->tdb1.io = &transaction1_methods;
return 0;
@ -517,13 +517,13 @@ fail:
tdb1_allrecord_unlock(tdb, F_RDLCK);
fail_allrecord_lock:
tdb1_transaction_unlock(tdb, F_WRLCK);
SAFE_FREE(tdb->transaction->blocks);
SAFE_FREE(tdb->transaction->hash_heads);
SAFE_FREE(tdb->transaction);
SAFE_FREE(tdb->tdb1.transaction->blocks);
SAFE_FREE(tdb->tdb1.transaction->hash_heads);
SAFE_FREE(tdb->tdb1.transaction);
return -1;
}
int tdb1_transaction_start(struct tdb1_context *tdb)
int tdb1_transaction_start(struct tdb_context *tdb)
{
return _tdb1_transaction_start(tdb);
}
@ -531,7 +531,7 @@ int tdb1_transaction_start(struct tdb1_context *tdb)
/*
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) {
return 0;
@ -548,7 +548,7 @@ static int transaction1_sync(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_l
}
#if HAVE_MMAP
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,
length + (offset - moffset), MS_SYNC) != 0) {
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
}
static int _tdb1_transaction_cancel(struct tdb1_context *tdb)
static int _tdb1_transaction_cancel(struct tdb_context *tdb)
{
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,
"tdb1_transaction_cancel:"
" no transaction");
return -1;
}
if (tdb->transaction->nesting != 0) {
tdb->transaction->transaction_error = 1;
tdb->transaction->nesting--;
if (tdb->tdb1.transaction->nesting != 0) {
tdb->tdb1.transaction->transaction_error = 1;
tdb->tdb1.transaction->nesting--;
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 */
for (i=0;i<tdb->transaction->num_blocks;i++) {
if (tdb->transaction->blocks[i] != NULL) {
free(tdb->transaction->blocks[i]);
for (i=0;i<tdb->tdb1.transaction->num_blocks;i++) {
if (tdb->tdb1.transaction->blocks[i] != NULL) {
free(tdb->tdb1.transaction->blocks[i]);
}
}
SAFE_FREE(tdb->transaction->blocks);
SAFE_FREE(tdb->tdb1.transaction->blocks);
if (tdb->transaction->magic_offset) {
const struct tdb1_methods *methods = tdb->transaction->io_methods;
if (tdb->tdb1.transaction->magic_offset) {
const struct tdb1_methods *methods = tdb->tdb1.transaction->io_methods;
const uint32_t invalid = TDB1_RECOVERY_INVALID_MAGIC;
/* remove the recovery marker */
if (methods->tdb1_write(tdb, tdb->transaction->magic_offset, &invalid, 4) == -1 ||
transaction1_sync(tdb, tdb->transaction->magic_offset, 4) == -1) {
if (methods->tdb1_write(tdb, tdb->tdb1.transaction->magic_offset, &invalid, 4) == -1 ||
transaction1_sync(tdb, tdb->tdb1.transaction->magic_offset, 4) == -1) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_cancel: failed to"
" remove recovery magic");
@ -608,10 +608,10 @@ static int _tdb1_transaction_cancel(struct tdb1_context *tdb)
tdb1_release_transaction_locks(tdb);
/* 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->transaction);
SAFE_FREE(tdb->tdb1.transaction->hash_heads);
SAFE_FREE(tdb->tdb1.transaction);
return ret;
}
@ -619,7 +619,7 @@ static int _tdb1_transaction_cancel(struct tdb1_context *tdb)
/*
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);
}
@ -627,31 +627,31 @@ int tdb1_transaction_cancel(struct tdb1_context *tdb)
/*
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;
int i;
recovery_size = sizeof(uint32_t);
for (i=0;i<tdb->transaction->num_blocks;i++) {
if (i * tdb->transaction->block_size >= tdb->transaction->old_map_size) {
for (i=0;i<tdb->tdb1.transaction->num_blocks;i++) {
if (i * tdb->tdb1.transaction->block_size >= tdb->tdb1.transaction->old_map_size) {
break;
}
if (tdb->transaction->blocks[i] == NULL) {
if (tdb->tdb1.transaction->blocks[i] == NULL) {
continue;
}
recovery_size += 2*sizeof(tdb1_off_t);
if (i == tdb->transaction->num_blocks-1) {
recovery_size += tdb->transaction->last_block_size;
if (i == tdb->tdb1.transaction->num_blocks-1) {
recovery_size += tdb->tdb1.transaction->last_block_size;
} else {
recovery_size += tdb->transaction->block_size;
recovery_size += tdb->tdb1.transaction->block_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,
tdb1_off_t *recovery_offset,
struct tdb1_record *rec)
@ -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
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_off_t *recovery_offset,
tdb1_len_t *recovery_max_size)
{
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;
if (tdb1_recovery_area(tdb, methods, &recovery_head, &rec) == -1) {
@ -726,12 +726,13 @@ static int tdb1_recovery_allocate(struct tdb1_context *tdb,
*recovery_size = tdb1_recovery_size(tdb);
/* 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_head = *recovery_offset;
if (methods->tdb1_expand_file(tdb, tdb->transaction->old_map_size,
(tdb->file->map_size - tdb->transaction->old_map_size) +
if (methods->tdb1_expand_file(tdb, tdb->tdb1.transaction->old_map_size,
(tdb->file->map_size - tdb->tdb1.transaction->old_map_size) +
sizeof(rec) + *recovery_max_size) == -1) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_recovery_allocate:"
@ -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
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
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,
/*
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_len_t recovery_size;
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;
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;
int i;
@ -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
large write, which should be more efficient */
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_len_t length;
if (tdb->transaction->blocks[i] == NULL) {
if (tdb->tdb1.transaction->blocks[i] == NULL) {
continue;
}
offset = i * tdb->transaction->block_size;
length = tdb->transaction->block_size;
if (i == tdb->transaction->num_blocks-1) {
length = tdb->transaction->last_block_size;
offset = i * tdb->tdb1.transaction->block_size;
length = tdb->tdb1.transaction->block_size;
if (i == tdb->tdb1.transaction->num_blocks-1) {
length = tdb->tdb1.transaction->last_block_size;
}
if (offset >= old_map_size) {
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_LOG_ERROR,
"tdb1_transaction_setup_recovery: transaction data over new region boundary");
@ -907,18 +908,18 @@ static int transaction1_setup_recovery(struct tdb1_context *tdb,
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;
if (tdb->transaction == NULL) {
if (tdb->tdb1.transaction == NULL) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb1_transaction_prepare_commit:"
" no transaction");
return -1;
}
if (tdb->transaction->prepared) {
if (tdb->tdb1.transaction->prepared) {
tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb1_transaction_prepare_commit:"
" transaction already prepared");
@ -926,7 +927,7 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb)
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,
"tdb1_transaction_prepare_commit:"
" transaction error pending");
@ -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;
}
/* check for a null transaction */
if (tdb->transaction->blocks == NULL) {
if (tdb->tdb1.transaction->blocks == NULL) {
return 0;
}
methods = tdb->transaction->io_methods;
methods = tdb->tdb1.transaction->io_methods;
/* if there are any locks pending then the caller has not
nested their locks properly, so fail the transaction */
@ -979,7 +980,7 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb)
if (!(tdb->flags & TDB_NOSYNC)) {
/* 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,
"tdb1_transaction_prepare_commit:"
" failed to setup recovery data");
@ -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 */
if (tdb->file->map_size != tdb->transaction->old_map_size) {
if (methods->tdb1_expand_file(tdb, tdb->transaction->old_map_size,
if (tdb->file->map_size != tdb->tdb1.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) == -1) {
tdb->tdb1.transaction->old_map_size) == -1) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_prepare_commit:"
" expansion failed");
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);
}
@ -1011,13 +1012,13 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb)
/*
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);
}
/* 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;
struct tdb1_record rec;
@ -1041,20 +1042,20 @@ static bool repack_worthwhile(struct tdb1_context *tdb)
/*
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;
int i;
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,
"tdb1_transaction_commit:"
" no transaction");
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,
"tdb1_transaction_commit:"
" transaction error pending");
@ -1063,18 +1064,18 @@ int tdb1_transaction_commit(struct tdb1_context *tdb)
}
if (tdb->transaction->nesting != 0) {
tdb->transaction->nesting--;
if (tdb->tdb1.transaction->nesting != 0) {
tdb->tdb1.transaction->nesting--;
return 0;
}
/* check for a null transaction */
if (tdb->transaction->blocks == NULL) {
if (tdb->tdb1.transaction->blocks == NULL) {
_tdb1_transaction_cancel(tdb);
return 0;
}
if (!tdb->transaction->prepared) {
if (!tdb->tdb1.transaction->prepared) {
int ret = _tdb1_transaction_prepare_commit(tdb);
if (ret) {
_tdb1_transaction_cancel(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 */
for (i=0;i<tdb->transaction->num_blocks;i++) {
for (i=0;i<tdb->tdb1.transaction->num_blocks;i++) {
tdb1_off_t offset;
tdb1_len_t length;
if (tdb->transaction->blocks[i] == NULL) {
if (tdb->tdb1.transaction->blocks[i] == NULL) {
continue;
}
offset = i * tdb->transaction->block_size;
length = tdb->transaction->block_size;
if (i == tdb->transaction->num_blocks-1) {
length = tdb->transaction->last_block_size;
offset = i * tdb->tdb1.transaction->block_size;
length = tdb->tdb1.transaction->block_size;
if (i == tdb->tdb1.transaction->num_blocks-1) {
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,
"tdb1_transaction_commit:"
" write failed during commit");
@ -1107,7 +1108,7 @@ int tdb1_transaction_commit(struct tdb1_context *tdb)
/* we've overwritten part of the data and
possibly expanded the file, so we need to
run the crash recovery code */
tdb->methods = methods;
tdb->tdb1.io = methods;
tdb1_transaction_recover(tdb);
_tdb1_transaction_cancel(tdb);
@ -1116,16 +1117,16 @@ int tdb1_transaction_commit(struct tdb1_context *tdb)
"tdb1_transaction_commit: write failed");
return -1;
}
SAFE_FREE(tdb->transaction->blocks[i]);
SAFE_FREE(tdb->tdb1.transaction->blocks[i]);
}
/* Do this before we drop lock or blocks. */
if (tdb->transaction->expanded) {
if (tdb->tdb1.transaction->expanded) {
need_repack = repack_worthwhile(tdb);
}
SAFE_FREE(tdb->transaction->blocks);
tdb->transaction->num_blocks = 0;
SAFE_FREE(tdb->tdb1.transaction->blocks);
tdb->tdb1.transaction->num_blocks = 0;
/* ensure the new data is on disk */
if (transaction1_sync(tdb, 0, tdb->file->map_size) == -1) {
@ -1164,7 +1165,7 @@ int tdb1_transaction_commit(struct tdb1_context *tdb)
database write access already established (including the open
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;
unsigned char *data, *p;
@ -1185,7 +1186,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb)
}
/* 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) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_recover:"
@ -1217,7 +1218,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb)
}
/* 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) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_recover:"
@ -1235,7 +1236,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb)
memcpy(&ofs, p, 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);
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_transaction_recover: failed to recover"
@ -1288,7 +1289,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb)
}
/* 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;
struct tdb1_record rec;
@ -1304,7 +1305,7 @@ bool tdb1_needs_recovery(struct tdb1_context *tdb)
}
/* 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) {
return true;
}

View File

@ -31,13 +31,13 @@
/* Uses traverse lock: 0 = finish, TDB1_NEXT_LOCK_ERR = error,
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)
{
int want_next = (tlock->off != 0);
/* 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) {
/* this is an optimisation for the common case where
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_
factor of around 80 in speed on a linux 2.6.x
system (testing using ldbtest).
*/
tdb->methods->next_hash_chain(tdb, &tlock->hash);
if (tlock->hash == tdb->header.hash_size) {
tdb->tdb1.io->next_hash_chain(tdb, &tlock->hash);
if (tlock->hash == tdb->tdb1.header.hash_size) {
continue;
}
}
@ -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 */
current = tlock->off;
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)
goto fail;
}
@ -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
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,
struct tdb1_traverse_lock *tl)
{
@ -155,10 +155,10 @@ static int tdb1_traverse_internal(struct tdb1_context *tdb,
/* This was in the initializaton, above, but the IRIX compiler
* 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 */
tdb->travlocks.next = tl;
tdb->tdb1.travlocks.next = tl;
/* tdb1_next_lock places locks on the record returned, and its chain */
while ((off = tdb1_next_lock(tdb, tl, &rec)) != 0) {
@ -204,7 +204,7 @@ static int tdb1_traverse_internal(struct tdb1_context *tdb,
SAFE_FREE(key.dptr);
}
out:
tdb->travlocks.next = tl->next;
tdb->tdb1.travlocks.next = tl->next;
if (ret < 0)
return -1;
else
@ -215,7 +215,7 @@ out:
/*
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)
{
struct tdb1_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
@ -227,9 +227,9 @@ int tdb1_traverse_read(struct tdb1_context *tdb,
return -1;
}
tdb->traverse_read++;
tdb->tdb1.traverse_read++;
ret = tdb1_traverse_internal(tdb, fn, private_data, &tl);
tdb->traverse_read--;
tdb->tdb1.traverse_read--;
tdb1_transaction_unlock(tdb, F_RDLCK);
@ -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
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)
{
struct tdb1_traverse_lock tl = { NULL, 0, 0, F_WRLCK };
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);
}
@ -257,9 +257,9 @@ int tdb1_traverse(struct tdb1_context *tdb,
return -1;
}
tdb->traverse_write++;
tdb->tdb1.traverse_write++;
ret = tdb1_traverse_internal(tdb, fn, private_data, &tl);
tdb->traverse_write--;
tdb->tdb1.traverse_write--;
tdb1_transaction_unlock(tdb, F_WRLCK);
@ -268,29 +268,29 @@ int tdb1_traverse(struct tdb1_context *tdb,
/* 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;
struct tdb1_record rec;
tdb1_off_t off;
/* 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;
tdb->travlocks.off = tdb->travlocks.hash = 0;
tdb->travlocks.lock_rw = F_RDLCK;
tdb->tdb1.travlocks.off = tdb->tdb1.travlocks.hash = 0;
tdb->tdb1.travlocks.lock_rw = F_RDLCK;
/* 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) {
return tdb1_null;
}
/* now read the key */
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. */
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,
"tdb1_firstkey:"
" error occurred while tdb1_unlocking!");
@ -298,7 +298,7 @@ TDB_DATA tdb1_firstkey(struct tdb1_context *tdb)
}
/* 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;
TDB_DATA key = tdb1_null;
@ -307,58 +307,58 @@ TDB_DATA tdb1_nextkey(struct tdb1_context *tdb, TDB_DATA oldkey)
tdb1_off_t off;
/* Is locked key the old key? If so, traverse will be reliable. */
if (tdb->travlocks.off) {
if (tdb1_lock(tdb,tdb->travlocks.hash,tdb->travlocks.lock_rw))
if (tdb->tdb1.travlocks.off) {
if (tdb1_lock(tdb,tdb->tdb1.travlocks.hash,tdb->tdb1.travlocks.lock_rw))
return tdb1_null;
if (tdb1_rec_read(tdb, tdb->travlocks.off, &rec) == -1
|| !(k = tdb1_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),
if (tdb1_rec_read(tdb, tdb->tdb1.travlocks.off, &rec) == -1
|| !(k = tdb1_alloc_read(tdb,tdb->tdb1.travlocks.off+sizeof(rec),
rec.key_len))
|| memcmp(k, oldkey.dptr, oldkey.dsize) != 0) {
/* 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);
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);
return tdb1_null;
}
tdb->travlocks.off = 0;
tdb->tdb1.travlocks.off = 0;
}
SAFE_FREE(k);
}
if (!tdb->travlocks.off) {
if (!tdb->tdb1.travlocks.off) {
/* 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);
if (!tdb->travlocks.off) {
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->tdb1.travlocks.off) {
return tdb1_null;
}
tdb->travlocks.hash = TDB1_BUCKET(rec.full_hash);
if (tdb1_lock_record(tdb, tdb->travlocks.off) != 0) {
tdb->tdb1.travlocks.hash = TDB1_BUCKET(rec.full_hash);
if (tdb1_lock_record(tdb, tdb->tdb1.travlocks.off) != 0) {
tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR,
"tdb1_nextkey: lock_record failed (%s)!",
strerror(errno));
return tdb1_null;
}
}
oldhash = tdb->travlocks.hash;
oldhash = tdb->tdb1.travlocks.hash;
/* Grab next record: locks chain and returned 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) {
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);
/* 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,
"tdb1_nextkey: WARNING tdb1_unlock failed!");
}
/* 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,
"tdb1_nextkey: WARNING tdb1_unlock failed!");
return key;

View File

@ -147,8 +147,8 @@ static void add_to_freetable(struct tdb_context *tdb,
unsigned ftable,
struct tle_freetable *freetable)
{
tdb->ftable_off = freetable->base.off;
tdb->ftable = ftable;
tdb->tdb2.ftable_off = freetable->base.off;
tdb->tdb2.ftable = ftable;
add_free_record(tdb, eoff, sizeof(struct tdb_used_record) + elen,
TDB_LOCK_WAIT, false);
}
@ -312,7 +312,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. */
if (layout->filename) {

View File

@ -41,7 +41,7 @@ int main(int argc, char *argv[])
ok1(free_record_length(tdb, layout->elem[1].base.off) == len);
/* 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. */
ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
test = layout->elem[1].base.off;
@ -64,7 +64,7 @@ int main(int argc, char *argv[])
ok1(tdb_check(tdb, NULL, NULL) == 0);
/* 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. */
ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
test = layout->elem[1].base.off;
@ -88,7 +88,7 @@ int main(int argc, char *argv[])
ok1(tdb_check(tdb, NULL, NULL) == 0);
/* 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. */
ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
test = layout->elem[2].base.off;
@ -115,7 +115,7 @@ int main(int argc, char *argv[])
ok1(tdb_check(tdb, NULL, NULL) == 0);
/* 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. */
ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
test = layout->elem[2].base.off;
@ -142,7 +142,7 @@ int main(int argc, char *argv[])
ok1(tdb_check(tdb, NULL, NULL) == 0);
/* 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. */
ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
test = layout->elem[2].base.off;

View File

@ -68,9 +68,9 @@ int main(int argc, char *argv[])
/* Make sure we fill it in for later finding. */
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;
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. */
ok1(tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range,
@ -228,9 +228,9 @@ int main(int argc, char *argv[])
/* Make sure we fill it in for later finding. */
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;
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. */
ok1(tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range,

View File

@ -9,7 +9,7 @@ static bool empty_freetable(struct tdb_context *tdb)
unsigned int i;
/* 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();
for (i = 0; i < sizeof(ftab.buckets)/sizeof(ftab.buckets[0]); i++) {

View File

@ -35,22 +35,22 @@ int main(int argc, char *argv[])
off = get_free(tdb, 0, 80 - sizeof(struct tdb_used_record), 0,
TDB_USED_MAGIC, 0);
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,
TDB_USED_MAGIC, 0);
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,
TDB_USED_MAGIC, 0);
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,
TDB_USED_MAGIC, 0);
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. */
off = get_free(tdb, 0, 0, 1, TDB_USED_MAGIC, 0);

View File

@ -6,11 +6,11 @@
#include <err.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 addition)
{
if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) {
if ((tdb->flags & TDB_RDONLY) || tdb->tdb1.traverse_read) {
tdb->last_error = TDB_ERR_RDONLY;
return -1;
}
@ -46,7 +46,7 @@ static const struct tdb1_methods large_io_methods = {
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)
{
TDB_DATA *expect = _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[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
TDB_DATA key, orig_data, data;
uint32_t hash;
tdb1_off_t rec_ptr;
@ -70,7 +70,7 @@ int main(int argc, char *argv[])
O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL);
ok1(tdb);
tdb->methods = &large_io_methods;
tdb->tdb1.io = &large_io_methods;
/* Enlarge the file (internally multiplies by 2). */
ok1(tdb1_expand(tdb, 1500000000) == 0);

View File

@ -6,7 +6,7 @@
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
struct tdb1_header hdr;
int fd;

View File

@ -6,7 +6,7 @@
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
TDB_DATA key, data;
plan_tests(13);

View File

@ -23,7 +23,7 @@ static int check(TDB_DATA key, TDB_DATA data, void *private)
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 char mask = (1 << (bit % CHAR_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;
unsigned int i, verifiable, corrupt, sizes[2], dsize, ksize;
@ -93,7 +93,7 @@ static void check_test(struct tdb1_context *tdb)
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
plan_tests(4);
/* This should use mmap. */

View File

@ -81,7 +81,7 @@ static int ftruncate_check(int fd, off_t length)
static bool test_death(enum operation op, struct agent *agent)
{
struct tdb1_context *tdb = NULL;
struct tdb_context *tdb = NULL;
TDB_DATA key;
enum agent_return ret;
int needed_recovery = 0;

View File

@ -6,7 +6,7 @@
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
TDB_DATA key, data;
plan_tests(13);

View File

@ -9,7 +9,7 @@ static uint64_t tdb1_dumb_hash(const void *key, size_t len, uint64_t seed,
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)
{
unsigned int *count = priv;
@ -46,7 +46,7 @@ static uint64_t old_hash(const void *key, size_t len, uint64_t seed,
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
unsigned int log_count, flags;
TDB_DATA d;
struct tdb1_logging_context log_ctx = { log_fn, &log_count };

View File

@ -7,7 +7,7 @@
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
TDB_DATA key, data;
plan_tests(27);

View File

@ -23,7 +23,7 @@ static bool correct_data(TDB_DATA data)
&& 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)
{
ok1(correct_key(key));
@ -31,7 +31,7 @@ static int traverse2(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data,
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)
{
ok1(correct_key(key));
@ -48,7 +48,7 @@ static int traverse1(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data,
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
TDB_DATA key, data;
plan_tests(17);

View File

@ -14,7 +14,7 @@
#define NUM_ENTRIES 10
static bool prepare_entries(struct tdb1_context *tdb)
static bool prepare_entries(struct tdb_context *tdb)
{
unsigned int i;
TDB_DATA key, data;
@ -31,7 +31,7 @@ static bool prepare_entries(struct tdb1_context *tdb)
return true;
}
static void delete_entries(struct tdb1_context *tdb)
static void delete_entries(struct tdb_context *tdb)
{
unsigned int i;
TDB_DATA key;
@ -45,7 +45,7 @@ static void delete_entries(struct tdb1_context *tdb)
}
/* 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)
{
unsigned int i;
@ -57,7 +57,7 @@ static int delete_other(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data,
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)
{
ok1(tdb1_delete(tdb, key) == 0);
@ -66,7 +66,7 @@ static int delete_self(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data,
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
int errors = 0;
plan_tests(41);

View File

@ -6,7 +6,7 @@
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
plan_tests(8);

View File

@ -131,7 +131,7 @@ int main(int argc, char *argv[])
const int flags[] = { TDB_DEFAULT,
TDB_NOMMAP };
int i;
struct tdb1_context *tdb;
struct tdb_context *tdb;
TDB_DATA key, data;
plan_tests(10);

View File

@ -8,7 +8,7 @@
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
TDB_DATA key, data;
plan_tests(11);

View File

@ -3,7 +3,7 @@
#include <stdlib.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)
{
unsigned int *count = priv;
@ -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. */
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
unsigned int log_count;
struct tdb1_logging_context log_ctx = { log_fn, &log_count };

View File

@ -6,7 +6,7 @@
int main(int argc, char *argv[])
{
unsigned int i, j;
struct tdb1_context *tdb;
struct tdb_context *tdb;
int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP,
TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT,
TDB_NOMMAP|TDB_CONVERT };

View File

@ -24,7 +24,7 @@ static bool correct_data(TDB_DATA data)
&& 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)
{
ok1(correct_key(key));
@ -34,7 +34,7 @@ static int traverse(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA data,
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
TDB_DATA key, data;
plan_tests(13);

View File

@ -3,7 +3,7 @@
#include <stdlib.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)
{
unsigned int *count = priv;
@ -27,7 +27,7 @@ static uint64_t old_hash(const void *key, size_t len, uint64_t seed,
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
unsigned int log_count;
TDB_DATA d;
struct tdb1_logging_context log_ctx = { log_fn, &log_count };

View File

@ -6,7 +6,7 @@
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
TDB_DATA key, data;
plan_tests(4);

View File

@ -6,7 +6,7 @@
int main(int argc, char *argv[])
{
struct tdb1_context *tdb;
struct tdb_context *tdb;
TDB_DATA key, data;
plan_tests(10);

View File

@ -16,7 +16,7 @@
#include <stdio.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)
{

View File

@ -6,7 +6,7 @@
#include <stdio.h>
/* 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_ERROR ecode,
const char *message,

View File

@ -25,7 +25,7 @@
*/
#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:
@ -151,10 +151,10 @@ static enum TDB_ERROR transaction_read(struct tdb_context *tdb, tdb_off_t off,
blk = off / PAGESIZE;
/* see if we have it in the block list */
if (tdb->transaction->num_blocks <= blk ||
tdb->transaction->blocks[blk] == NULL) {
if (tdb->tdb2.transaction->num_blocks <= blk ||
tdb->tdb2.transaction->blocks[blk] == NULL) {
/* 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) {
goto fail;
}
@ -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 */
if (blk == tdb->transaction->num_blocks-1) {
if (len > tdb->transaction->last_block_size) {
if (blk == tdb->tdb2.transaction->num_blocks-1) {
if (len > tdb->tdb2.transaction->last_block_size) {
ecode = TDB_ERR_IO;
goto fail;
}
}
/* 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;
fail:
tdb->transaction->transaction_error = 1;
tdb->tdb2.transaction->transaction_error = 1;
return tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
"transaction_read: failed at off=%zu len=%zu",
(size_t)off, (size_t)len);
@ -191,7 +191,7 @@ static enum TDB_ERROR transaction_write(struct tdb_context *tdb, tdb_off_t off,
enum TDB_ERROR ecode;
/* 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,
"transaction_write: transaction already"
" prepared, write not allowed");
@ -219,15 +219,15 @@ static enum TDB_ERROR transaction_write(struct tdb_context *tdb, tdb_off_t off,
blk = off / PAGESIZE;
off = off % PAGESIZE;
if (tdb->transaction->num_blocks <= blk) {
if (tdb->tdb2.transaction->num_blocks <= blk) {
uint8_t **new_blocks;
/* expand the blocks array */
if (tdb->transaction->blocks == NULL) {
if (tdb->tdb2.transaction->blocks == NULL) {
new_blocks = (uint8_t **)malloc(
(blk+1)*sizeof(uint8_t *));
} else {
new_blocks = (uint8_t **)realloc(
tdb->transaction->blocks,
tdb->tdb2.transaction->blocks,
(blk+1)*sizeof(uint8_t *));
}
if (new_blocks == NULL) {
@ -236,30 +236,30 @@ static enum TDB_ERROR transaction_write(struct tdb_context *tdb, tdb_off_t off,
" failed to allocate");
goto fail;
}
memset(&new_blocks[tdb->transaction->num_blocks], 0,
(1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *));
tdb->transaction->blocks = new_blocks;
tdb->transaction->num_blocks = blk+1;
tdb->transaction->last_block_size = 0;
memset(&new_blocks[tdb->tdb2.transaction->num_blocks], 0,
(1+(blk - tdb->tdb2.transaction->num_blocks))*sizeof(uint8_t *));
tdb->tdb2.transaction->blocks = new_blocks;
tdb->tdb2.transaction->num_blocks = blk+1;
tdb->tdb2.transaction->last_block_size = 0;
}
/* allocate and fill a block? */
if (tdb->transaction->blocks[blk] == NULL) {
tdb->transaction->blocks[blk] = (uint8_t *)calloc(PAGESIZE, 1);
if (tdb->transaction->blocks[blk] == NULL) {
if (tdb->tdb2.transaction->blocks[blk] == NULL) {
tdb->tdb2.transaction->blocks[blk] = (uint8_t *)calloc(PAGESIZE, 1);
if (tdb->tdb2.transaction->blocks[blk] == NULL) {
ecode = tdb_logerr(tdb, TDB_ERR_OOM, TDB_LOG_ERROR,
"transaction_write:"
" failed to allocate");
goto fail;
}
if (tdb->transaction->old_map_size > blk * PAGESIZE) {
if (tdb->tdb2.transaction->old_map_size > blk * PAGESIZE) {
tdb_len_t len2 = PAGESIZE;
if (len2 + (blk * PAGESIZE) > tdb->transaction->old_map_size) {
len2 = tdb->transaction->old_map_size - (blk * PAGESIZE);
if (len2 + (blk * PAGESIZE) > tdb->tdb2.transaction->old_map_size) {
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,
tdb->transaction->blocks[blk],
tdb->tdb2.transaction->blocks[blk],
len2);
if (ecode != TDB_SUCCESS) {
ecode = tdb_logerr(tdb, ecode,
@ -268,31 +268,31 @@ static enum TDB_ERROR transaction_write(struct tdb_context *tdb, tdb_off_t off,
" failed to"
" read old block: %s",
strerror(errno));
SAFE_FREE(tdb->transaction->blocks[blk]);
SAFE_FREE(tdb->tdb2.transaction->blocks[blk]);
goto fail;
}
if (blk == tdb->transaction->num_blocks-1) {
tdb->transaction->last_block_size = len2;
if (blk == tdb->tdb2.transaction->num_blocks-1) {
tdb->tdb2.transaction->last_block_size = len2;
}
}
}
/* overwrite part of an existing block */
if (buf == NULL) {
memset(tdb->transaction->blocks[blk] + off, 0, len);
memset(tdb->tdb2.transaction->blocks[blk] + off, 0, len);
} 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 (len + off > tdb->transaction->last_block_size) {
tdb->transaction->last_block_size = len + off;
if (blk == tdb->tdb2.transaction->num_blocks-1) {
if (len + off > tdb->tdb2.transaction->last_block_size) {
tdb->tdb2.transaction->last_block_size = len + off;
}
}
return TDB_SUCCESS;
fail:
tdb->transaction->transaction_error = 1;
tdb->tdb2.transaction->transaction_error = 1;
return ecode;
}
@ -324,21 +324,21 @@ static void transaction_write_existing(struct tdb_context *tdb, tdb_off_t off,
blk = off / PAGESIZE;
off = off % PAGESIZE;
if (tdb->transaction->num_blocks <= blk ||
tdb->transaction->blocks[blk] == NULL) {
if (tdb->tdb2.transaction->num_blocks <= blk ||
tdb->tdb2.transaction->blocks[blk] == NULL) {
return;
}
if (blk == tdb->transaction->num_blocks-1 &&
off + len > tdb->transaction->last_block_size) {
if (off >= tdb->transaction->last_block_size) {
if (blk == tdb->tdb2.transaction->num_blocks-1 &&
off + len > tdb->tdb2.transaction->last_block_size) {
if (off >= tdb->tdb2.transaction->last_block_size) {
return;
}
len = tdb->transaction->last_block_size - off;
len = tdb->tdb2.transaction->last_block_size - off;
}
/* 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,
if (write_mode) {
tdb->stats.transaction_write_direct++;
if (blk != end_blk
|| blk >= tdb->transaction->num_blocks
|| tdb->transaction->blocks[blk] == NULL) {
|| blk >= tdb->tdb2.transaction->num_blocks
|| tdb->tdb2.transaction->blocks[blk] == NULL) {
tdb->stats.transaction_write_direct_fail++;
return NULL;
}
return tdb->transaction->blocks[blk] + off % PAGESIZE;
return tdb->tdb2.transaction->blocks[blk] + off % PAGESIZE;
}
tdb->stats.transaction_read_direct++;
/* Single which we have copied? */
if (blk == end_blk
&& blk < tdb->transaction->num_blocks
&& tdb->transaction->blocks[blk])
return tdb->transaction->blocks[blk] + off % PAGESIZE;
&& blk < tdb->tdb2.transaction->num_blocks
&& tdb->tdb2.transaction->blocks[blk])
return tdb->tdb2.transaction->blocks[blk] + off % PAGESIZE;
/* Otherwise must be all not copied. */
while (blk <= end_blk) {
if (blk >= tdb->transaction->num_blocks)
if (blk >= tdb->tdb2.transaction->num_blocks)
break;
if (tdb->transaction->blocks[blk]) {
if (tdb->tdb2.transaction->blocks[blk]) {
tdb->stats.transaction_read_direct_fail++;
return NULL;
}
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 = {
@ -459,38 +459,38 @@ static void _tdb_transaction_cancel(struct tdb_context *tdb)
int i;
enum TDB_ERROR ecode;
if (tdb->transaction == NULL) {
if (tdb->tdb2.transaction == NULL) {
tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb_transaction_cancel: no transaction");
return;
}
if (tdb->transaction->nesting != 0) {
tdb->transaction->transaction_error = 1;
tdb->transaction->nesting--;
if (tdb->tdb2.transaction->nesting != 0) {
tdb->tdb2.transaction->transaction_error = 1;
tdb->tdb2.transaction->nesting--;
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 */
for (i=0;i<tdb->transaction->num_blocks;i++) {
if (tdb->transaction->blocks[i] != NULL) {
free(tdb->transaction->blocks[i]);
for (i=0;i<tdb->tdb2.transaction->num_blocks;i++) {
if (tdb->tdb2.transaction->blocks[i] != NULL) {
free(tdb->tdb2.transaction->blocks[i]);
}
}
SAFE_FREE(tdb->transaction->blocks);
SAFE_FREE(tdb->tdb2.transaction->blocks);
if (tdb->transaction->magic_offset) {
const struct tdb_methods *methods = tdb->transaction->io_methods;
if (tdb->tdb2.transaction->magic_offset) {
const struct tdb_methods *methods = tdb->tdb2.transaction->io_methods;
uint64_t invalid = TDB_RECOVERY_INVALID_MAGIC;
/* remove the recovery marker */
ecode = methods->twrite(tdb, tdb->transaction->magic_offset,
ecode = methods->twrite(tdb, tdb->tdb2.transaction->magic_offset,
&invalid, sizeof(invalid));
if (ecode == TDB_SUCCESS)
ecode = transaction_sync(tdb,
tdb->transaction->magic_offset,
tdb->tdb2.transaction->magic_offset,
sizeof(invalid));
if (ecode != TDB_SUCCESS) {
tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
@ -503,14 +503,14 @@ static void _tdb_transaction_cancel(struct tdb_context *tdb)
tdb_allrecord_unlock(tdb, tdb->file->allrecord_lock.ltype);
/* 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);
if (tdb_has_open_lock(tdb))
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)
}
/* cope with nested tdb_transaction_start() calls */
if (tdb->transaction != NULL) {
if (tdb->tdb2.transaction != NULL) {
if (!(tdb->flags & TDB_ALLOW_NESTING)) {
return tdb->last_error
= tdb_logerr(tdb, TDB_ERR_IO,
@ -550,7 +550,7 @@ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb)
"tdb_transaction_start:"
" already inside transaction");
}
tdb->transaction->nesting++;
tdb->tdb2.transaction->nesting++;
tdb->stats.transaction_nest++;
return 0;
}
@ -567,9 +567,9 @@ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb)
" held");
}
tdb->transaction = (struct tdb_transaction *)
tdb->tdb2.transaction = (struct tdb_transaction *)
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,
TDB_LOG_ERROR,
"tdb_transaction_start:"
@ -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 */
ecode = tdb_transaction_lock(tdb, F_WRLCK);
if (ecode != TDB_SUCCESS) {
SAFE_FREE(tdb->transaction->blocks);
SAFE_FREE(tdb->transaction);
SAFE_FREE(tdb->tdb2.transaction->blocks);
SAFE_FREE(tdb->tdb2.transaction);
return tdb->last_error = ecode;
}
@ -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
anyone else */
tdb->methods->oob(tdb, tdb->file->map_size + 1, true);
tdb->transaction->old_map_size = tdb->file->map_size;
tdb->tdb2.io->oob(tdb, tdb->file->map_size + 1, true);
tdb->tdb2.transaction->old_map_size = tdb->file->map_size;
/* finally hook the io methods, replacing them with
transaction specific methods */
tdb->transaction->io_methods = tdb->methods;
tdb->methods = &transaction_methods;
tdb->tdb2.transaction->io_methods = tdb->tdb2.io;
tdb->tdb2.io = &transaction_methods;
return tdb->last_error = TDB_SUCCESS;
fail_allrecord_lock:
tdb_transaction_unlock(tdb, F_WRLCK);
SAFE_FREE(tdb->transaction->blocks);
SAFE_FREE(tdb->transaction);
SAFE_FREE(tdb->tdb2.transaction->blocks);
SAFE_FREE(tdb->tdb2.transaction);
return tdb->last_error = ecode;
}
@ -630,16 +630,16 @@ static tdb_len_t tdb_recovery_size(struct tdb_context *tdb)
int i;
recovery_size = 0;
for (i=0;i<tdb->transaction->num_blocks;i++) {
if (i * PAGESIZE >= tdb->transaction->old_map_size) {
for (i=0;i<tdb->tdb2.transaction->num_blocks;i++) {
if (i * PAGESIZE >= tdb->tdb2.transaction->old_map_size) {
break;
}
if (tdb->transaction->blocks[i] == NULL) {
if (tdb->tdb2.transaction->blocks[i] == NULL) {
continue;
}
recovery_size += 2*sizeof(tdb_off_t);
if (i == tdb->transaction->num_blocks-1) {
recovery_size += tdb->transaction->last_block_size;
if (i == tdb->tdb2.transaction->num_blocks-1) {
recovery_size += tdb->tdb2.transaction->last_block_size;
} else {
recovery_size += PAGESIZE;
}
@ -726,7 +726,7 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb,
size_t i;
enum TDB_ERROR ecode;
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));
if (!rec) {
@ -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
* 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
large write, which should be more efficient */
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_len_t length;
unsigned int off;
const unsigned char *buffer;
if (tdb->transaction->blocks[i] == NULL) {
if (tdb->tdb2.transaction->blocks[i] == NULL) {
continue;
}
offset = i * PAGESIZE;
length = PAGESIZE;
if (i == tdb->transaction->num_blocks-1) {
length = tdb->transaction->last_block_size;
if (i == tdb->tdb2.transaction->num_blocks-1) {
length = tdb->tdb2.transaction->last_block_size;
}
if (offset >= tdb->transaction->old_map_size) {
if (offset >= tdb->tdb2.transaction->old_map_size) {
continue;
}
@ -770,9 +770,9 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb,
" boundary");
goto fail;
}
if (offset + length > tdb->transaction->old_map_size) {
if (offset + length > tdb->tdb2.transaction->old_map_size) {
/* 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);
if (TDB_PTR_IS_ERR(buffer)) {
@ -781,14 +781,14 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb,
}
/* 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;
while (off < length) {
tdb_len_t len;
unsigned int samelen;
len = different(tdb->transaction->blocks[i] + off,
len = different(tdb->tdb2.transaction->blocks[i] + off,
buffer + off, length - off,
sizeof(offset) + sizeof(len) + 1,
&samelen);
@ -806,12 +806,12 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb,
}
*len = p - (unsigned char *)(rec + 1);
tdb->methods = old_methods;
tdb->tdb2.io = old_methods;
return rec;
fail:
free(rec);
tdb->methods = old_methods;
tdb->tdb2.io = old_methods;
return TDB_ERR_PTR(ecode);
}
@ -822,7 +822,7 @@ static tdb_off_t create_recovery_area(struct tdb_context *tdb,
tdb_off_t off, recovery_off;
tdb_len_t addition;
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
* such allocation forces us to expand the file. */
@ -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
transaction commit, which would destroy the recovery
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;
tdb->file->map_size = tdb->transaction->old_map_size;
tdb->file->map_size = tdb->tdb2.transaction->old_map_size;
tdb->stats.transaction_expand_file++;
ecode = methods->expand_file(tdb, addition);
if (ecode != TDB_SUCCESS) {
@ -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
expand the file again in the transaction commit, which
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
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)
{
tdb_len_t recovery_size = 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;
const struct tdb_methods *methods = tdb->transaction->io_methods;
const struct tdb_methods *methods = tdb->tdb2.transaction->io_methods;
uint64_t magic;
enum TDB_ERROR ecode;
@ -950,21 +950,21 @@ static enum TDB_ERROR transaction_setup_recovery(struct tdb_context *tdb)
magic = TDB_RECOVERY_MAGIC;
tdb_convert(tdb, &magic, sizeof(magic));
tdb->transaction->magic_offset
tdb->tdb2.transaction->magic_offset
= 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));
if (ecode != TDB_SUCCESS) {
return tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
"tdb_transaction_setup_recovery:"
" 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));
/* 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));
}
@ -973,20 +973,20 @@ static enum TDB_ERROR _tdb_transaction_prepare_commit(struct tdb_context *tdb)
const struct tdb_methods *methods;
enum TDB_ERROR ecode;
if (tdb->transaction == NULL) {
if (tdb->tdb2.transaction == NULL) {
return tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb_transaction_prepare_commit:"
" no transaction");
}
if (tdb->transaction->prepared) {
if (tdb->tdb2.transaction->prepared) {
_tdb_transaction_cancel(tdb);
return tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
"tdb_transaction_prepare_commit:"
" transaction already prepared");
}
if (tdb->transaction->transaction_error) {
if (tdb->tdb2.transaction->transaction_error) {
_tdb_transaction_cancel(tdb);
return tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_ERROR,
"tdb_transaction_prepare_commit:"
@ -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;
}
/* check for a null transaction */
if (tdb->transaction->blocks == NULL) {
if (tdb->tdb2.transaction->blocks == NULL) {
return TDB_SUCCESS;
}
methods = tdb->transaction->io_methods;
methods = tdb->tdb2.transaction->io_methods;
/* upgrade the main transaction lock region to a write lock */
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)
/* Since we have whole db locked, we don't need the expansion lock. */
if (!(tdb->flags & TDB_NOSYNC)) {
/* Sets up tdb->transaction->recovery and
* tdb->transaction->magic_offset. */
/* Sets up tdb->tdb2.transaction->recovery and
* tdb->tdb2.transaction->magic_offset. */
ecode = transaction_setup_recovery(tdb);
if (ecode != TDB_SUCCESS) {
return ecode;
}
}
tdb->transaction->prepared = true;
tdb->tdb2.transaction->prepared = true;
/* 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;
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 */
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);
if (ecode != TDB_SUCCESS) {
return ecode;
@ -1064,7 +1064,7 @@ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb)
int i;
enum TDB_ERROR ecode;
if (tdb->transaction == NULL) {
if (tdb->tdb2.transaction == NULL) {
return tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL,
TDB_LOG_USE_ERROR,
"tdb_transaction_commit:"
@ -1073,18 +1073,18 @@ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb)
tdb_trace(tdb, "tdb_transaction_commit");
if (tdb->transaction->nesting != 0) {
tdb->transaction->nesting--;
if (tdb->tdb2.transaction->nesting != 0) {
tdb->tdb2.transaction->nesting--;
return tdb->last_error = TDB_SUCCESS;
}
/* check for a null transaction */
if (tdb->transaction->blocks == NULL) {
if (tdb->tdb2.transaction->blocks == NULL) {
_tdb_transaction_cancel(tdb);
return tdb->last_error = TDB_SUCCESS;
}
if (!tdb->transaction->prepared) {
if (!tdb->tdb2.transaction->prepared) {
ecode = _tdb_transaction_prepare_commit(tdb);
if (ecode != TDB_SUCCESS) {
_tdb_transaction_cancel(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 */
for (i=0;i<tdb->transaction->num_blocks;i++) {
for (i=0;i<tdb->tdb2.transaction->num_blocks;i++) {
tdb_off_t offset;
tdb_len_t length;
if (tdb->transaction->blocks[i] == NULL) {
if (tdb->tdb2.transaction->blocks[i] == NULL) {
continue;
}
offset = i * PAGESIZE;
length = PAGESIZE;
if (i == tdb->transaction->num_blocks-1) {
length = tdb->transaction->last_block_size;
if (i == tdb->tdb2.transaction->num_blocks-1) {
length = tdb->tdb2.transaction->last_block_size;
}
ecode = methods->twrite(tdb, offset,
tdb->transaction->blocks[i], length);
tdb->tdb2.transaction->blocks[i], length);
if (ecode != TDB_SUCCESS) {
/* we've overwritten part of the data and
possibly expanded the file, so we need to
run the crash recovery code */
tdb->methods = methods;
tdb->tdb2.io = methods;
tdb_transaction_recover(tdb);
_tdb_transaction_cancel(tdb);
return tdb->last_error = ecode;
}
SAFE_FREE(tdb->transaction->blocks[i]);
SAFE_FREE(tdb->tdb2.transaction->blocks[i]);
}
SAFE_FREE(tdb->transaction->blocks);
tdb->transaction->num_blocks = 0;
SAFE_FREE(tdb->tdb2.transaction->blocks);
tdb->tdb2.transaction->num_blocks = 0;
/* ensure the new data is on disk */
ecode = transaction_sync(tdb, 0, tdb->file->map_size);
@ -1151,7 +1151,7 @@ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb)
/* use a transaction cancel to free memory and remove the
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);
return tdb->last_error = TDB_SUCCESS;
@ -1212,7 +1212,7 @@ enum TDB_ERROR tdb_transaction_recover(struct tdb_context *tdb)
}
/* 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);
if (ecode != TDB_SUCCESS) {
return tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
@ -1230,7 +1230,7 @@ enum TDB_ERROR tdb_transaction_recover(struct tdb_context *tdb)
memcpy(&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) {
free(data);
return tdb_logerr(tdb, ecode, TDB_LOG_ERROR,