mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
TDB2: more internal cleanups after TDB1 compatibility removal.
This eliminates the separate tdb2 substructure, and makes some tdb1-required functions static. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
cab6e11678
commit
c3dcdf08f3
@ -497,10 +497,10 @@ static enum TDB_ERROR check_free(struct tdb_context *tdb,
|
||||
|
||||
}
|
||||
|
||||
ecode = tdb->tdb2.io->oob(tdb, off,
|
||||
frec_len(frec)
|
||||
+ sizeof(struct tdb_used_record),
|
||||
false);
|
||||
ecode = tdb->io->oob(tdb, off,
|
||||
frec_len(frec)
|
||||
+ sizeof(struct tdb_used_record),
|
||||
false);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
return ecode;
|
||||
}
|
||||
@ -606,7 +606,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->tdb2.io->tread(tdb, off, &c, 1);
|
||||
ecode = tdb->io->tread(tdb, off, &c, 1);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
return TDB_ERR_TO_OFF(ecode);
|
||||
}
|
||||
|
@ -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->tdb2.ftable_off = off = first_ftable(tdb);
|
||||
tdb->tdb2.ftable = 0;
|
||||
tdb->ftable_off = off = first_ftable(tdb);
|
||||
tdb->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->tdb2.ftable_off = off;
|
||||
tdb->tdb2.ftable = count;
|
||||
tdb->ftable_off = off;
|
||||
tdb->ftable = count;
|
||||
max = rnd;
|
||||
}
|
||||
|
||||
@ -218,7 +218,8 @@ static enum TDB_ERROR enqueue_in_free(struct tdb_context *tdb,
|
||||
return TDB_OFF_TO_ERR(head);
|
||||
|
||||
/* We only need to set ftable_and_len; rest is set in enqueue_in_free */
|
||||
new.ftable_and_len = ((uint64_t)tdb->tdb2.ftable << (64 - TDB_OFF_UPPER_STEAL))
|
||||
new.ftable_and_len = ((uint64_t)tdb->ftable
|
||||
<< (64 - TDB_OFF_UPPER_STEAL))
|
||||
| len;
|
||||
|
||||
/* new->next = head. */
|
||||
@ -287,8 +288,8 @@ static tdb_off_t ftable_offset(struct tdb_context *tdb, unsigned int ftable)
|
||||
tdb_off_t off;
|
||||
unsigned int i;
|
||||
|
||||
if (likely(tdb->tdb2.ftable == ftable))
|
||||
return tdb->tdb2.ftable_off;
|
||||
if (likely(tdb->ftable == ftable))
|
||||
return tdb->ftable_off;
|
||||
|
||||
off = first_ftable(tdb);
|
||||
for (i = 0; i < ftable; i++) {
|
||||
@ -595,7 +596,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->tdb2.ftable_off, size_to_bucket(len));
|
||||
b_off = bucket_off(tdb->ftable_off, size_to_bucket(len));
|
||||
ecode = tdb_lock_free_bucket(tdb, b_off, waitflag);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
return ecode;
|
||||
@ -606,7 +607,7 @@ enum TDB_ERROR add_free_record(struct tdb_context *tdb,
|
||||
|
||||
/* Coalescing unlocks free list. */
|
||||
if (!ecode && coalesce_ok)
|
||||
ecode = coalesce_list(tdb, tdb->tdb2.ftable_off, b_off, 2);
|
||||
ecode = coalesce_list(tdb, tdb->ftable_off, b_off, 2);
|
||||
else
|
||||
tdb_unlock_free_bucket(tdb, b_off);
|
||||
return ecode;
|
||||
@ -752,8 +753,8 @@ 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->tdb2.io->twrite(tdb, best_off + sizeof(rec)
|
||||
+ keylen + datalen, "", 1);
|
||||
ecode = tdb->io->twrite(tdb, best_off + sizeof(rec)
|
||||
+ keylen + datalen, "", 1);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
goto unlock_err;
|
||||
}
|
||||
@ -800,9 +801,9 @@ static tdb_off_t get_free(struct tdb_context *tdb,
|
||||
else
|
||||
start_b = size_to_bucket(adjust_size(keylen, datalen));
|
||||
|
||||
ftable_off = tdb->tdb2.ftable_off;
|
||||
ftable = tdb->tdb2.ftable;
|
||||
while (!wrapped || ftable_off != tdb->tdb2.ftable_off) {
|
||||
ftable_off = tdb->ftable_off;
|
||||
ftable = tdb->ftable;
|
||||
while (!wrapped || ftable_off != tdb->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 +820,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->tdb2.ftable_off = ftable_off;
|
||||
tdb->tdb2.ftable = ftable;
|
||||
tdb->ftable_off = ftable_off;
|
||||
tdb->ftable = ftable;
|
||||
return off;
|
||||
}
|
||||
/* Didn't work. Try next bucket. */
|
||||
@ -926,7 +927,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->tdb2.io->oob(tdb, tdb->file->map_size, 1, true);
|
||||
tdb->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;
|
||||
@ -937,7 +938,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->tdb2.io->expand_file(tdb, wanted);
|
||||
ecode = tdb->io->expand_file(tdb, wanted);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
tdb_unlock_expand(tdb, F_WRLCK);
|
||||
return ecode;
|
||||
@ -957,7 +958,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->tdb2.direct_access);
|
||||
assert(!tdb->direct_access);
|
||||
|
||||
for (;;) {
|
||||
enum TDB_ERROR ecode;
|
||||
|
@ -99,7 +99,7 @@ static enum TDB_ERROR tdb_oob(struct tdb_context *tdb,
|
||||
enum TDB_ERROR ecode;
|
||||
|
||||
/* We can't hold pointers during this: we could unmap! */
|
||||
assert(!tdb->tdb2.direct_access
|
||||
assert(!tdb->direct_access
|
||||
|| (tdb->flags & TDB_NOLOCK)
|
||||
|| tdb_has_expansion_lock(tdb));
|
||||
|
||||
@ -216,7 +216,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->tdb2.io->direct(tdb, off, len, true);
|
||||
void *p = tdb->io->direct(tdb, off, len, true);
|
||||
enum TDB_ERROR ecode = TDB_SUCCESS;
|
||||
|
||||
assert(!(tdb->flags & TDB_RDONLY));
|
||||
@ -229,7 +229,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->tdb2.io->twrite(tdb, off, buf, todo);
|
||||
ecode = tdb->io->twrite(tdb, off, buf, todo);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
@ -245,8 +245,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->tdb2.io->direct(tdb, off, sizeof(*p),
|
||||
false);
|
||||
tdb_off_t *p = tdb->io->direct(tdb, off, sizeof(*p), false);
|
||||
if (TDB_PTR_IS_ERR(p)) {
|
||||
return TDB_ERR_TO_OFF(TDB_PTR_ERR(p));
|
||||
}
|
||||
@ -272,7 +271,7 @@ static enum TDB_ERROR tdb_write(struct tdb_context *tdb, tdb_off_t off,
|
||||
"Write to read-only database");
|
||||
}
|
||||
|
||||
ecode = tdb->tdb2.io->oob(tdb, off, len, false);
|
||||
ecode = tdb->io->oob(tdb, off, len, false);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
return ecode;
|
||||
}
|
||||
@ -306,7 +305,7 @@ static enum TDB_ERROR tdb_read(struct tdb_context *tdb, tdb_off_t off,
|
||||
{
|
||||
enum TDB_ERROR ecode;
|
||||
|
||||
ecode = tdb->tdb2.io->oob(tdb, off, len, false);
|
||||
ecode = tdb->io->oob(tdb, off, len, false);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
return ecode;
|
||||
}
|
||||
@ -344,11 +343,11 @@ enum TDB_ERROR tdb_write_convert(struct tdb_context *tdb, tdb_off_t off,
|
||||
" %zu bytes", len);
|
||||
}
|
||||
memcpy(conv, rec, len);
|
||||
ecode = tdb->tdb2.io->twrite(tdb, off,
|
||||
tdb_convert(tdb, conv, len), len);
|
||||
ecode = tdb->io->twrite(tdb, off,
|
||||
tdb_convert(tdb, conv, len), len);
|
||||
free(conv);
|
||||
} else {
|
||||
ecode = tdb->tdb2.io->twrite(tdb, off, rec, len);
|
||||
ecode = tdb->io->twrite(tdb, off, rec, len);
|
||||
}
|
||||
return ecode;
|
||||
}
|
||||
@ -356,7 +355,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->tdb2.io->tread(tdb, off, rec, len);
|
||||
enum TDB_ERROR ecode = tdb->io->tread(tdb, off, rec, len);
|
||||
tdb_convert(tdb, rec, len);
|
||||
return ecode;
|
||||
}
|
||||
@ -370,8 +369,7 @@ enum TDB_ERROR tdb_write_off(struct tdb_context *tdb,
|
||||
}
|
||||
|
||||
if (likely(!(tdb->flags & TDB_CONVERT))) {
|
||||
tdb_off_t *p = tdb->tdb2.io->direct(tdb, off, sizeof(*p),
|
||||
true);
|
||||
tdb_off_t *p = tdb->io->direct(tdb, off, sizeof(*p), true);
|
||||
if (TDB_PTR_IS_ERR(p)) {
|
||||
return TDB_PTR_ERR(p);
|
||||
}
|
||||
@ -397,7 +395,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->tdb2.io->tread(tdb, offset, buf+prefix, len);
|
||||
ecode = tdb->io->tread(tdb, offset, buf+prefix, len);
|
||||
if (unlikely(ecode != TDB_SUCCESS)) {
|
||||
free(buf);
|
||||
return TDB_ERR_PTR(ecode);
|
||||
@ -486,7 +484,7 @@ const void *tdb_access_read(struct tdb_context *tdb,
|
||||
void *ret = NULL;
|
||||
|
||||
if (likely(!(tdb->flags & TDB_CONVERT))) {
|
||||
ret = tdb->tdb2.io->direct(tdb, off, len, false);
|
||||
ret = tdb->io->direct(tdb, off, len, false);
|
||||
|
||||
if (TDB_PTR_IS_ERR(ret)) {
|
||||
return ret;
|
||||
@ -498,14 +496,14 @@ const void *tdb_access_read(struct tdb_context *tdb,
|
||||
if (TDB_PTR_IS_ERR(hdr)) {
|
||||
return hdr;
|
||||
}
|
||||
hdr->next = tdb->tdb2.access;
|
||||
tdb->tdb2.access = hdr;
|
||||
hdr->next = tdb->access;
|
||||
tdb->access = hdr;
|
||||
ret = hdr + 1;
|
||||
if (convert) {
|
||||
tdb_convert(tdb, (void *)ret, len);
|
||||
}
|
||||
} else
|
||||
tdb->tdb2.direct_access++;
|
||||
tdb->direct_access++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -522,7 +520,7 @@ void *tdb_access_write(struct tdb_context *tdb,
|
||||
}
|
||||
|
||||
if (likely(!(tdb->flags & TDB_CONVERT))) {
|
||||
ret = tdb->tdb2.io->direct(tdb, off, len, true);
|
||||
ret = tdb->io->direct(tdb, off, len, true);
|
||||
|
||||
if (TDB_PTR_IS_ERR(ret)) {
|
||||
return ret;
|
||||
@ -535,8 +533,8 @@ void *tdb_access_write(struct tdb_context *tdb,
|
||||
if (TDB_PTR_IS_ERR(hdr)) {
|
||||
return hdr;
|
||||
}
|
||||
hdr->next = tdb->tdb2.access;
|
||||
tdb->tdb2.access = hdr;
|
||||
hdr->next = tdb->access;
|
||||
tdb->access = hdr;
|
||||
hdr->off = off;
|
||||
hdr->len = len;
|
||||
hdr->convert = convert;
|
||||
@ -544,7 +542,7 @@ void *tdb_access_write(struct tdb_context *tdb,
|
||||
if (convert)
|
||||
tdb_convert(tdb, (void *)ret, len);
|
||||
} else
|
||||
tdb->tdb2.direct_access++;
|
||||
tdb->direct_access++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -553,7 +551,7 @@ static struct tdb_access_hdr **find_hdr(struct tdb_context *tdb, const void *p)
|
||||
{
|
||||
struct tdb_access_hdr **hp;
|
||||
|
||||
for (hp = &tdb->tdb2.access; *hp; hp = &(*hp)->next) {
|
||||
for (hp = &tdb->access; *hp; hp = &(*hp)->next) {
|
||||
if (*hp + 1 == p)
|
||||
return hp;
|
||||
}
|
||||
@ -569,7 +567,7 @@ void tdb_access_release(struct tdb_context *tdb, const void *p)
|
||||
*hp = hdr->next;
|
||||
free(hdr);
|
||||
} else
|
||||
tdb->tdb2.direct_access--;
|
||||
tdb->direct_access--;
|
||||
}
|
||||
|
||||
enum TDB_ERROR tdb_access_commit(struct tdb_context *tdb, void *p)
|
||||
@ -586,7 +584,7 @@ enum TDB_ERROR tdb_access_commit(struct tdb_context *tdb, void *p)
|
||||
*hp = hdr->next;
|
||||
free(hdr);
|
||||
} else {
|
||||
tdb->tdb2.direct_access--;
|
||||
tdb->direct_access--;
|
||||
ecode = TDB_SUCCESS;
|
||||
}
|
||||
|
||||
@ -614,10 +612,9 @@ void tdb_inc_seqnum(struct tdb_context *tdb)
|
||||
if (likely(!(tdb->flags & TDB_CONVERT))) {
|
||||
int64_t *direct;
|
||||
|
||||
direct = tdb->tdb2.io->direct(tdb,
|
||||
offsetof(struct tdb_header,
|
||||
seqnum),
|
||||
sizeof(*direct), true);
|
||||
direct = tdb->io->direct(tdb,
|
||||
offsetof(struct tdb_header, seqnum),
|
||||
sizeof(*direct), true);
|
||||
if (likely(direct)) {
|
||||
/* Don't let it go negative, even briefly */
|
||||
if (unlikely((*direct) + 1) < 0)
|
||||
@ -649,5 +646,5 @@ static const struct tdb_methods io_methods = {
|
||||
*/
|
||||
void tdb_io_init(struct tdb_context *tdb)
|
||||
{
|
||||
tdb->tdb2.io = &io_methods;
|
||||
tdb->io = &io_methods;
|
||||
}
|
||||
|
@ -183,9 +183,9 @@ static int unlock(struct tdb_context *tdb, int rw, off_t off, off_t len)
|
||||
|
||||
note that a len of zero means lock to end of file
|
||||
*/
|
||||
enum TDB_ERROR tdb_brlock(struct tdb_context *tdb,
|
||||
int rw_type, tdb_off_t offset, tdb_off_t len,
|
||||
enum tdb_lock_flags flags)
|
||||
static enum TDB_ERROR tdb_brlock(struct tdb_context *tdb,
|
||||
int rw_type, tdb_off_t offset, tdb_off_t len,
|
||||
enum tdb_lock_flags flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -225,8 +225,8 @@ enum TDB_ERROR tdb_brlock(struct tdb_context *tdb,
|
||||
return TDB_SUCCESS;
|
||||
}
|
||||
|
||||
enum TDB_ERROR tdb_brunlock(struct tdb_context *tdb,
|
||||
int rw_type, tdb_off_t offset, size_t len)
|
||||
static enum TDB_ERROR tdb_brunlock(struct tdb_context *tdb,
|
||||
int rw_type, tdb_off_t offset, size_t len)
|
||||
{
|
||||
if (tdb->flags & TDB_NOLOCK) {
|
||||
return TDB_SUCCESS;
|
||||
@ -339,9 +339,9 @@ enum TDB_ERROR tdb_lock_and_recover(struct tdb_context *tdb)
|
||||
}
|
||||
|
||||
/* lock an offset in the database. */
|
||||
enum TDB_ERROR tdb_nest_lock(struct tdb_context *tdb,
|
||||
tdb_off_t offset, int ltype,
|
||||
enum tdb_lock_flags flags)
|
||||
static enum TDB_ERROR tdb_nest_lock(struct tdb_context *tdb,
|
||||
tdb_off_t offset, int ltype,
|
||||
enum tdb_lock_flags flags)
|
||||
{
|
||||
struct tdb_lock *new_lck;
|
||||
enum TDB_ERROR ecode;
|
||||
@ -435,8 +435,8 @@ enum TDB_ERROR tdb_nest_lock(struct tdb_context *tdb,
|
||||
return TDB_SUCCESS;
|
||||
}
|
||||
|
||||
enum TDB_ERROR tdb_nest_unlock(struct tdb_context *tdb,
|
||||
tdb_off_t off, int ltype)
|
||||
static enum TDB_ERROR tdb_nest_unlock(struct tdb_context *tdb,
|
||||
tdb_off_t off, int ltype)
|
||||
{
|
||||
struct tdb_lock *lck;
|
||||
enum TDB_ERROR ecode;
|
||||
@ -491,9 +491,9 @@ void tdb_transaction_unlock(struct tdb_context *tdb, int ltype)
|
||||
|
||||
/* We only need to lock individual bytes, but Linux merges consecutive locks
|
||||
* so we lock in contiguous ranges. */
|
||||
enum TDB_ERROR tdb_lock_gradual(struct tdb_context *tdb,
|
||||
int ltype, enum tdb_lock_flags flags,
|
||||
tdb_off_t off, tdb_off_t len)
|
||||
static enum TDB_ERROR tdb_lock_gradual(struct tdb_context *tdb,
|
||||
int ltype, enum tdb_lock_flags flags,
|
||||
tdb_off_t off, tdb_off_t len)
|
||||
{
|
||||
enum TDB_ERROR ecode;
|
||||
enum tdb_lock_flags nb_flags = (flags & ~TDB_LOCK_WAIT);
|
||||
|
@ -100,9 +100,9 @@ static void tdb2_context_init(struct tdb_context *tdb)
|
||||
{
|
||||
/* Initialize the TDB2 fields here */
|
||||
tdb_io_init(tdb);
|
||||
tdb->tdb2.direct_access = 0;
|
||||
tdb->tdb2.transaction = NULL;
|
||||
tdb->tdb2.access = NULL;
|
||||
tdb->direct_access = 0;
|
||||
tdb->transaction = NULL;
|
||||
tdb->access = NULL;
|
||||
}
|
||||
|
||||
struct new_database {
|
||||
@ -640,7 +640,7 @@ _PUBLIC_ struct tdb_context *tdb_open(const char *name, int tdb_flags,
|
||||
tdb_unlock_open(tdb, openlock);
|
||||
|
||||
/* This makes sure we have current map_size and mmap. */
|
||||
ecode = tdb->tdb2.io->oob(tdb, tdb->file->map_size, 1, true);
|
||||
ecode = tdb->io->oob(tdb, tdb->file->map_size, 1, true);
|
||||
if (unlikely(ecode != TDB_SUCCESS))
|
||||
goto fail;
|
||||
|
||||
@ -722,7 +722,7 @@ _PUBLIC_ int tdb_close(struct tdb_context *tdb)
|
||||
|
||||
tdb_trace(tdb, "tdb_close");
|
||||
|
||||
if (tdb->tdb2.transaction) {
|
||||
if (tdb->transaction) {
|
||||
tdb_transaction_cancel(tdb);
|
||||
}
|
||||
|
||||
|
@ -547,25 +547,6 @@ bool tdb_has_expansion_lock(struct tdb_context *tdb);
|
||||
/* If it needs recovery, grab all the locks and do it. */
|
||||
enum TDB_ERROR tdb_lock_and_recover(struct tdb_context *tdb);
|
||||
|
||||
/* Byte-range lock wrappers for TDB1 to access. */
|
||||
enum TDB_ERROR tdb_brlock(struct tdb_context *tdb,
|
||||
int rw_type, tdb_off_t offset, tdb_off_t len,
|
||||
enum tdb_lock_flags flags);
|
||||
|
||||
enum TDB_ERROR tdb_brunlock(struct tdb_context *tdb,
|
||||
int rw_type, tdb_off_t offset, size_t len);
|
||||
|
||||
enum TDB_ERROR tdb_nest_lock(struct tdb_context *tdb,
|
||||
tdb_off_t offset, int ltype,
|
||||
enum tdb_lock_flags flags);
|
||||
|
||||
enum TDB_ERROR tdb_nest_unlock(struct tdb_context *tdb,
|
||||
tdb_off_t off, int ltype);
|
||||
|
||||
enum TDB_ERROR tdb_lock_gradual(struct tdb_context *tdb,
|
||||
int ltype, enum tdb_lock_flags flags,
|
||||
tdb_off_t off, tdb_off_t len);
|
||||
|
||||
/* Default lock and unlock functions. */
|
||||
int tdb_fcntl_lock(int fd, int rw, off_t off, off_t len, bool waitflag, void *);
|
||||
int tdb_fcntl_unlock(int fd, int rw, off_t off, off_t len, void *);
|
||||
@ -618,24 +599,21 @@ struct tdb_context {
|
||||
/* Last error we returned. */
|
||||
enum TDB_ERROR last_error;
|
||||
|
||||
struct {
|
||||
/* Are we accessing directly? (debugging check). */
|
||||
int direct_access;
|
||||
|
||||
/* Are we accessing directly? (debugging check). */
|
||||
int direct_access;
|
||||
/* Set if we are in a transaction. */
|
||||
struct tdb_transaction *transaction;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* What free table are we using? */
|
||||
tdb_off_t ftable_off;
|
||||
unsigned int ftable;
|
||||
/* IO methods: changes for transactions. */
|
||||
const struct tdb_methods *io;
|
||||
|
||||
/* IO methods: changes for transactions. */
|
||||
const struct tdb_methods *io;
|
||||
|
||||
/* Direct access information */
|
||||
struct tdb_access_hdr *access;
|
||||
} tdb2;
|
||||
/* Direct access information */
|
||||
struct tdb_access_hdr *access;
|
||||
};
|
||||
|
||||
/* tdb.c: */
|
||||
|
@ -72,13 +72,13 @@ static enum TDB_ERROR replace_data(struct tdb_context *tdb,
|
||||
}
|
||||
|
||||
new_off += sizeof(struct tdb_used_record);
|
||||
ecode = tdb->tdb2.io->twrite(tdb, new_off, key.dptr, key.dsize);
|
||||
ecode = tdb->io->twrite(tdb, new_off, key.dptr, key.dsize);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
return ecode;
|
||||
}
|
||||
|
||||
new_off += key.dsize;
|
||||
ecode = tdb->tdb2.io->twrite(tdb, new_off, dbuf.dptr, dbuf.dsize);
|
||||
ecode = tdb->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->tdb2.io->twrite(tdb, off, dbuf.dptr, dbuf.dsize);
|
||||
ecode = tdb->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->tdb2.io->twrite(tdb, off + dbuf.dsize, "", 1);
|
||||
ecode = tdb->io->twrite(tdb, off + dbuf.dsize, "", 1);
|
||||
}
|
||||
if (tdb->flags & TDB_SEQNUM)
|
||||
tdb_inc_seqnum(tdb);
|
||||
@ -213,8 +213,8 @@ _PUBLIC_ enum TDB_ERROR tdb_append(struct tdb_context *tdb,
|
||||
+ dbuf.dsize));
|
||||
goto out;
|
||||
}
|
||||
ecode = tdb->tdb2.io->tread(tdb, off + sizeof(rec) + key.dsize,
|
||||
newdata, old_dlen);
|
||||
ecode = tdb->io->tread(tdb, off + sizeof(rec) + key.dsize,
|
||||
newdata, old_dlen);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
goto out_free_newdata;
|
||||
}
|
||||
@ -328,7 +328,7 @@ _PUBLIC_ unsigned int tdb_get_flags(struct tdb_context *tdb)
|
||||
|
||||
static bool inside_transaction(const struct tdb_context *tdb)
|
||||
{
|
||||
return tdb->tdb2.transaction != NULL;
|
||||
return tdb->transaction != NULL;
|
||||
}
|
||||
|
||||
static bool readonly_changable(struct tdb_context *tdb, const char *caller)
|
||||
|
@ -191,8 +191,8 @@ static void add_to_freetable(struct tdb_context *tdb,
|
||||
unsigned ftable,
|
||||
struct tle_freetable *freetable)
|
||||
{
|
||||
tdb->tdb2.ftable_off = freetable->base.off;
|
||||
tdb->tdb2.ftable = ftable;
|
||||
tdb->ftable_off = freetable->base.off;
|
||||
tdb->ftable = ftable;
|
||||
add_free_record(tdb, eoff, sizeof(struct tdb_used_record) + elen,
|
||||
TDB_LOCK_WAIT, false);
|
||||
}
|
||||
@ -367,7 +367,7 @@ struct tdb_context *tdb_layout_get(struct tdb_layout *layout,
|
||||
}
|
||||
}
|
||||
|
||||
tdb->tdb2.ftable_off = find_ftable(layout, 0)->base.off;
|
||||
tdb->ftable_off = find_ftable(layout, 0)->base.off;
|
||||
return tdb;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,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->tdb2.ftable_off, size_to_bucket(len));
|
||||
b_off = bucket_off(tdb->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;
|
||||
@ -70,7 +70,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->tdb2.ftable_off, size_to_bucket(1024));
|
||||
b_off = bucket_off(tdb->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;
|
||||
@ -97,7 +97,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->tdb2.ftable_off, size_to_bucket(1024));
|
||||
b_off = bucket_off(tdb->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;
|
||||
@ -127,7 +127,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->tdb2.ftable_off, size_to_bucket(1024));
|
||||
b_off = bucket_off(tdb->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;
|
||||
@ -157,7 +157,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->tdb2.ftable_off, size_to_bucket(1024));
|
||||
b_off = bucket_off(tdb->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;
|
||||
|
@ -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->tdb2.io->twrite(tdb, off, key.dptr, key.dsize));
|
||||
ok1(!tdb->io->twrite(tdb, off, key.dptr, key.dsize));
|
||||
off += key.dsize;
|
||||
ok1(!tdb->tdb2.io->twrite(tdb, off, dbuf.dptr, dbuf.dsize));
|
||||
ok1(!tdb->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->tdb2.io->twrite(tdb, off, key.dptr, key.dsize));
|
||||
ok1(!tdb->io->twrite(tdb, off, key.dptr, key.dsize));
|
||||
off += key.dsize;
|
||||
ok1(!tdb->tdb2.io->twrite(tdb, off, dbuf.dptr, dbuf.dsize));
|
||||
ok1(!tdb->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,
|
||||
|
@ -8,7 +8,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->tdb2.ftable_off, &ftab, sizeof(ftab)) != 0)
|
||||
if (tdb_read_convert(tdb, tdb->ftable_off, &ftab, sizeof(ftab)) != 0)
|
||||
abort();
|
||||
|
||||
for (i = 0; i < sizeof(ftab.buckets)/sizeof(ftab.buckets[0]); i++) {
|
||||
|
@ -41,22 +41,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->tdb2.ftable_off == layout->elem[0].base.off);
|
||||
ok1(tdb->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->tdb2.ftable_off == layout->elem[1].base.off);
|
||||
ok1(tdb->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->tdb2.ftable_off == layout->elem[2].base.off);
|
||||
ok1(tdb->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->tdb2.ftable_off == layout->elem[0].base.off);
|
||||
ok1(tdb->ftable_off == layout->elem[0].base.off);
|
||||
|
||||
/* Now we fail. */
|
||||
off = get_free(tdb, 0, 0, 1, TDB_USED_MAGIC, 0);
|
||||
|
@ -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->tdb2.transaction->num_blocks <= blk ||
|
||||
tdb->tdb2.transaction->blocks[blk] == NULL) {
|
||||
if (tdb->transaction->num_blocks <= blk ||
|
||||
tdb->transaction->blocks[blk] == NULL) {
|
||||
/* nope, do a real read */
|
||||
ecode = tdb->tdb2.transaction->io_methods->tread(tdb, off, buf, len);
|
||||
ecode = tdb->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->tdb2.transaction->num_blocks-1) {
|
||||
if (len > tdb->tdb2.transaction->last_block_size) {
|
||||
if (blk == tdb->transaction->num_blocks-1) {
|
||||
if (len > tdb->transaction->last_block_size) {
|
||||
ecode = TDB_ERR_IO;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* now copy it out of this block */
|
||||
memcpy(buf, tdb->tdb2.transaction->blocks[blk] + (off % PAGESIZE), len);
|
||||
memcpy(buf, tdb->transaction->blocks[blk] + (off % PAGESIZE), len);
|
||||
return TDB_SUCCESS;
|
||||
|
||||
fail:
|
||||
tdb->tdb2.transaction->transaction_error = 1;
|
||||
tdb->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->tdb2.transaction->prepared) {
|
||||
if (tdb->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->tdb2.transaction->num_blocks <= blk) {
|
||||
if (tdb->transaction->num_blocks <= blk) {
|
||||
uint8_t **new_blocks;
|
||||
/* expand the blocks array */
|
||||
if (tdb->tdb2.transaction->blocks == NULL) {
|
||||
if (tdb->transaction->blocks == NULL) {
|
||||
new_blocks = (uint8_t **)malloc(
|
||||
(blk+1)*sizeof(uint8_t *));
|
||||
} else {
|
||||
new_blocks = (uint8_t **)realloc(
|
||||
tdb->tdb2.transaction->blocks,
|
||||
tdb->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->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;
|
||||
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;
|
||||
}
|
||||
|
||||
/* allocate and fill a block? */
|
||||
if (tdb->tdb2.transaction->blocks[blk] == NULL) {
|
||||
tdb->tdb2.transaction->blocks[blk] = (uint8_t *)calloc(PAGESIZE, 1);
|
||||
if (tdb->tdb2.transaction->blocks[blk] == NULL) {
|
||||
if (tdb->transaction->blocks[blk] == NULL) {
|
||||
tdb->transaction->blocks[blk] = (uint8_t *)calloc(PAGESIZE, 1);
|
||||
if (tdb->transaction->blocks[blk] == NULL) {
|
||||
ecode = tdb_logerr(tdb, TDB_ERR_OOM, TDB_LOG_ERROR,
|
||||
"transaction_write:"
|
||||
" failed to allocate");
|
||||
goto fail;
|
||||
}
|
||||
if (tdb->tdb2.transaction->old_map_size > blk * PAGESIZE) {
|
||||
if (tdb->transaction->old_map_size > blk * PAGESIZE) {
|
||||
tdb_len_t len2 = PAGESIZE;
|
||||
if (len2 + (blk * PAGESIZE) > tdb->tdb2.transaction->old_map_size) {
|
||||
len2 = tdb->tdb2.transaction->old_map_size - (blk * PAGESIZE);
|
||||
if (len2 + (blk * PAGESIZE) > tdb->transaction->old_map_size) {
|
||||
len2 = tdb->transaction->old_map_size - (blk * PAGESIZE);
|
||||
}
|
||||
ecode = tdb->tdb2.transaction->io_methods->tread(tdb,
|
||||
ecode = tdb->transaction->io_methods->tread(tdb,
|
||||
blk * PAGESIZE,
|
||||
tdb->tdb2.transaction->blocks[blk],
|
||||
tdb->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->tdb2.transaction->blocks[blk]);
|
||||
SAFE_FREE(tdb->transaction->blocks[blk]);
|
||||
goto fail;
|
||||
}
|
||||
if (blk == tdb->tdb2.transaction->num_blocks-1) {
|
||||
tdb->tdb2.transaction->last_block_size = len2;
|
||||
if (blk == tdb->transaction->num_blocks-1) {
|
||||
tdb->transaction->last_block_size = len2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* overwrite part of an existing block */
|
||||
if (buf == NULL) {
|
||||
memset(tdb->tdb2.transaction->blocks[blk] + off, 0, len);
|
||||
memset(tdb->transaction->blocks[blk] + off, 0, len);
|
||||
} else {
|
||||
memcpy(tdb->tdb2.transaction->blocks[blk] + off, buf, len);
|
||||
memcpy(tdb->transaction->blocks[blk] + off, buf, len);
|
||||
}
|
||||
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;
|
||||
if (blk == tdb->transaction->num_blocks-1) {
|
||||
if (len + off > tdb->transaction->last_block_size) {
|
||||
tdb->transaction->last_block_size = len + off;
|
||||
}
|
||||
}
|
||||
|
||||
return TDB_SUCCESS;
|
||||
|
||||
fail:
|
||||
tdb->tdb2.transaction->transaction_error = 1;
|
||||
tdb->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->tdb2.transaction->num_blocks <= blk ||
|
||||
tdb->tdb2.transaction->blocks[blk] == NULL) {
|
||||
if (tdb->transaction->num_blocks <= blk ||
|
||||
tdb->transaction->blocks[blk] == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (blk == tdb->tdb2.transaction->num_blocks-1 &&
|
||||
off + len > tdb->tdb2.transaction->last_block_size) {
|
||||
if (off >= tdb->tdb2.transaction->last_block_size) {
|
||||
if (blk == tdb->transaction->num_blocks-1 &&
|
||||
off + len > tdb->transaction->last_block_size) {
|
||||
if (off >= tdb->transaction->last_block_size) {
|
||||
return;
|
||||
}
|
||||
len = tdb->tdb2.transaction->last_block_size - off;
|
||||
len = tdb->transaction->last_block_size - off;
|
||||
}
|
||||
|
||||
/* overwrite part of an existing block */
|
||||
memcpy(tdb->tdb2.transaction->blocks[blk] + off, buf, len);
|
||||
memcpy(tdb->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->tdb2.transaction->num_blocks
|
||||
|| tdb->tdb2.transaction->blocks[blk] == NULL) {
|
||||
|| blk >= tdb->transaction->num_blocks
|
||||
|| tdb->transaction->blocks[blk] == NULL) {
|
||||
tdb->stats.transaction_write_direct_fail++;
|
||||
return NULL;
|
||||
}
|
||||
return tdb->tdb2.transaction->blocks[blk] + off % PAGESIZE;
|
||||
return tdb->transaction->blocks[blk] + off % PAGESIZE;
|
||||
}
|
||||
|
||||
tdb->stats.transaction_read_direct++;
|
||||
/* Single which we have copied? */
|
||||
if (blk == end_blk
|
||||
&& blk < tdb->tdb2.transaction->num_blocks
|
||||
&& tdb->tdb2.transaction->blocks[blk])
|
||||
return tdb->tdb2.transaction->blocks[blk] + off % PAGESIZE;
|
||||
&& blk < tdb->transaction->num_blocks
|
||||
&& tdb->transaction->blocks[blk])
|
||||
return tdb->transaction->blocks[blk] + off % PAGESIZE;
|
||||
|
||||
/* Otherwise must be all not copied. */
|
||||
while (blk <= end_blk) {
|
||||
if (blk >= tdb->tdb2.transaction->num_blocks)
|
||||
if (blk >= tdb->transaction->num_blocks)
|
||||
break;
|
||||
if (tdb->tdb2.transaction->blocks[blk]) {
|
||||
if (tdb->transaction->blocks[blk]) {
|
||||
tdb->stats.transaction_read_direct_fail++;
|
||||
return NULL;
|
||||
}
|
||||
blk++;
|
||||
}
|
||||
return tdb->tdb2.transaction->io_methods->direct(tdb, off, len, false);
|
||||
return tdb->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->tdb2.transaction == NULL) {
|
||||
if (tdb->transaction == NULL) {
|
||||
tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
|
||||
"tdb_transaction_cancel: no transaction");
|
||||
return;
|
||||
}
|
||||
|
||||
if (tdb->tdb2.transaction->nesting != 0) {
|
||||
tdb->tdb2.transaction->transaction_error = 1;
|
||||
tdb->tdb2.transaction->nesting--;
|
||||
if (tdb->transaction->nesting != 0) {
|
||||
tdb->transaction->transaction_error = 1;
|
||||
tdb->transaction->nesting--;
|
||||
return;
|
||||
}
|
||||
|
||||
tdb->file->map_size = tdb->tdb2.transaction->old_map_size;
|
||||
tdb->file->map_size = tdb->transaction->old_map_size;
|
||||
|
||||
/* free all the transaction blocks */
|
||||
for (i=0;i<tdb->tdb2.transaction->num_blocks;i++) {
|
||||
if (tdb->tdb2.transaction->blocks[i] != NULL) {
|
||||
free(tdb->tdb2.transaction->blocks[i]);
|
||||
for (i=0;i<tdb->transaction->num_blocks;i++) {
|
||||
if (tdb->transaction->blocks[i] != NULL) {
|
||||
free(tdb->transaction->blocks[i]);
|
||||
}
|
||||
}
|
||||
SAFE_FREE(tdb->tdb2.transaction->blocks);
|
||||
SAFE_FREE(tdb->transaction->blocks);
|
||||
|
||||
if (tdb->tdb2.transaction->magic_offset) {
|
||||
const struct tdb_methods *methods = tdb->tdb2.transaction->io_methods;
|
||||
if (tdb->transaction->magic_offset) {
|
||||
const struct tdb_methods *methods = tdb->transaction->io_methods;
|
||||
uint64_t invalid = TDB_RECOVERY_INVALID_MAGIC;
|
||||
|
||||
/* remove the recovery marker */
|
||||
ecode = methods->twrite(tdb, tdb->tdb2.transaction->magic_offset,
|
||||
ecode = methods->twrite(tdb, tdb->transaction->magic_offset,
|
||||
&invalid, sizeof(invalid));
|
||||
if (ecode == TDB_SUCCESS)
|
||||
ecode = transaction_sync(tdb,
|
||||
tdb->tdb2.transaction->magic_offset,
|
||||
tdb->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->tdb2.io = tdb->tdb2.transaction->io_methods;
|
||||
tdb->io = tdb->transaction->io_methods;
|
||||
|
||||
tdb_transaction_unlock(tdb, F_WRLCK);
|
||||
|
||||
if (tdb_has_open_lock(tdb))
|
||||
tdb_unlock_open(tdb, F_WRLCK);
|
||||
|
||||
SAFE_FREE(tdb->tdb2.transaction);
|
||||
SAFE_FREE(tdb->transaction);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -542,7 +542,7 @@ _PUBLIC_ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb)
|
||||
}
|
||||
|
||||
/* cope with nested tdb_transaction_start() calls */
|
||||
if (tdb->tdb2.transaction != NULL) {
|
||||
if (tdb->transaction != NULL) {
|
||||
if (!(tdb->flags & TDB_ALLOW_NESTING)) {
|
||||
return tdb->last_error
|
||||
= tdb_logerr(tdb, TDB_ERR_IO,
|
||||
@ -550,7 +550,7 @@ _PUBLIC_ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb)
|
||||
"tdb_transaction_start:"
|
||||
" already inside transaction");
|
||||
}
|
||||
tdb->tdb2.transaction->nesting++;
|
||||
tdb->transaction->nesting++;
|
||||
tdb->stats.transaction_nest++;
|
||||
return 0;
|
||||
}
|
||||
@ -567,9 +567,9 @@ _PUBLIC_ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb)
|
||||
" held");
|
||||
}
|
||||
|
||||
tdb->tdb2.transaction = (struct tdb_transaction *)
|
||||
tdb->transaction = (struct tdb_transaction *)
|
||||
calloc(sizeof(struct tdb_transaction), 1);
|
||||
if (tdb->tdb2.transaction == NULL) {
|
||||
if (tdb->transaction == NULL) {
|
||||
return tdb->last_error = tdb_logerr(tdb, TDB_ERR_OOM,
|
||||
TDB_LOG_ERROR,
|
||||
"tdb_transaction_start:"
|
||||
@ -581,8 +581,8 @@ _PUBLIC_ 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->tdb2.transaction->blocks);
|
||||
SAFE_FREE(tdb->tdb2.transaction);
|
||||
SAFE_FREE(tdb->transaction->blocks);
|
||||
SAFE_FREE(tdb->transaction);
|
||||
return tdb->last_error = ecode;
|
||||
}
|
||||
|
||||
@ -595,19 +595,19 @@ _PUBLIC_ enum TDB_ERROR tdb_transaction_start(struct tdb_context *tdb)
|
||||
|
||||
/* make sure we know about any file expansions already done by
|
||||
anyone else */
|
||||
tdb->tdb2.io->oob(tdb, tdb->file->map_size, 1, true);
|
||||
tdb->tdb2.transaction->old_map_size = tdb->file->map_size;
|
||||
tdb->io->oob(tdb, tdb->file->map_size, 1, true);
|
||||
tdb->transaction->old_map_size = tdb->file->map_size;
|
||||
|
||||
/* finally hook the io methods, replacing them with
|
||||
transaction specific methods */
|
||||
tdb->tdb2.transaction->io_methods = tdb->tdb2.io;
|
||||
tdb->tdb2.io = &transaction_methods;
|
||||
tdb->transaction->io_methods = tdb->io;
|
||||
tdb->io = &transaction_methods;
|
||||
return tdb->last_error = TDB_SUCCESS;
|
||||
|
||||
fail_allrecord_lock:
|
||||
tdb_transaction_unlock(tdb, F_WRLCK);
|
||||
SAFE_FREE(tdb->tdb2.transaction->blocks);
|
||||
SAFE_FREE(tdb->tdb2.transaction);
|
||||
SAFE_FREE(tdb->transaction->blocks);
|
||||
SAFE_FREE(tdb->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->tdb2.transaction->num_blocks;i++) {
|
||||
if (i * PAGESIZE >= tdb->tdb2.transaction->old_map_size) {
|
||||
for (i=0;i<tdb->transaction->num_blocks;i++) {
|
||||
if (i * PAGESIZE >= tdb->transaction->old_map_size) {
|
||||
break;
|
||||
}
|
||||
if (tdb->tdb2.transaction->blocks[i] == NULL) {
|
||||
if (tdb->transaction->blocks[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
recovery_size += 2*sizeof(tdb_off_t);
|
||||
if (i == tdb->tdb2.transaction->num_blocks-1) {
|
||||
recovery_size += tdb->tdb2.transaction->last_block_size;
|
||||
if (i == tdb->transaction->num_blocks-1) {
|
||||
recovery_size += tdb->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->tdb2.io;
|
||||
const struct tdb_methods *old_methods = tdb->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->tdb2.io = tdb->tdb2.transaction->io_methods;
|
||||
tdb->io = tdb->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->tdb2.transaction->num_blocks;i++) {
|
||||
for (i=0;i<tdb->transaction->num_blocks;i++) {
|
||||
tdb_off_t offset;
|
||||
tdb_len_t length;
|
||||
unsigned int off;
|
||||
const unsigned char *buffer;
|
||||
|
||||
if (tdb->tdb2.transaction->blocks[i] == NULL) {
|
||||
if (tdb->transaction->blocks[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
offset = i * PAGESIZE;
|
||||
length = PAGESIZE;
|
||||
if (i == tdb->tdb2.transaction->num_blocks-1) {
|
||||
length = tdb->tdb2.transaction->last_block_size;
|
||||
if (i == tdb->transaction->num_blocks-1) {
|
||||
length = tdb->transaction->last_block_size;
|
||||
}
|
||||
|
||||
if (offset >= tdb->tdb2.transaction->old_map_size) {
|
||||
if (offset >= tdb->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->tdb2.transaction->old_map_size) {
|
||||
if (offset + length > tdb->transaction->old_map_size) {
|
||||
/* Short read at EOF. */
|
||||
length = tdb->tdb2.transaction->old_map_size - offset;
|
||||
length = tdb->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->tdb2.transaction->blocks[i], buffer, length);
|
||||
off = same(tdb->transaction->blocks[i], buffer, length);
|
||||
offset += off;
|
||||
|
||||
while (off < length) {
|
||||
tdb_len_t len1;
|
||||
unsigned int samelen;
|
||||
|
||||
len1 = different(tdb->tdb2.transaction->blocks[i] + off,
|
||||
len1 = different(tdb->transaction->blocks[i] + off,
|
||||
buffer + off, length - off,
|
||||
sizeof(offset) + sizeof(len1) + 1,
|
||||
&samelen);
|
||||
@ -806,12 +806,12 @@ static struct tdb_recovery_record *alloc_recovery(struct tdb_context *tdb,
|
||||
}
|
||||
|
||||
*len = p - (unsigned char *)(rec + 1);
|
||||
tdb->tdb2.io = old_methods;
|
||||
tdb->io = old_methods;
|
||||
return rec;
|
||||
|
||||
fail:
|
||||
free(rec);
|
||||
tdb->tdb2.io = old_methods;
|
||||
tdb->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->tdb2.transaction->io_methods;
|
||||
const struct tdb_methods *methods = tdb->transaction->io_methods;
|
||||
|
||||
/* round up to a multiple of page size. Overallocate, since each
|
||||
* such allocation forces us to expand the file. */
|
||||
@ -839,9 +839,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->tdb2.transaction->old_map_size) +
|
||||
addition = (tdb->file->map_size - tdb->transaction->old_map_size) +
|
||||
sizeof(*rec) + rec->max_len;
|
||||
tdb->file->map_size = tdb->tdb2.transaction->old_map_size;
|
||||
tdb->file->map_size = tdb->transaction->old_map_size;
|
||||
tdb->stats.transaction_expand_file++;
|
||||
ecode = methods->expand_file(tdb, addition);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
@ -854,7 +854,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->tdb2.transaction->old_map_size = tdb->file->map_size;
|
||||
tdb->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 */
|
||||
@ -881,9 +881,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->tdb2.transaction->old_map_size;
|
||||
tdb_off_t old_map_size = tdb->transaction->old_map_size;
|
||||
struct tdb_recovery_record *recovery;
|
||||
const struct tdb_methods *methods = tdb->tdb2.transaction->io_methods;
|
||||
const struct tdb_methods *methods = tdb->transaction->io_methods;
|
||||
uint64_t magic;
|
||||
enum TDB_ERROR ecode;
|
||||
|
||||
@ -955,21 +955,21 @@ static enum TDB_ERROR transaction_setup_recovery(struct tdb_context *tdb)
|
||||
magic = TDB_RECOVERY_MAGIC;
|
||||
tdb_convert(tdb, &magic, sizeof(magic));
|
||||
|
||||
tdb->tdb2.transaction->magic_offset
|
||||
tdb->transaction->magic_offset
|
||||
= recovery_off + offsetof(struct tdb_recovery_record, magic);
|
||||
|
||||
ecode = methods->twrite(tdb, tdb->tdb2.transaction->magic_offset,
|
||||
ecode = methods->twrite(tdb, tdb->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->tdb2.transaction->magic_offset,
|
||||
transaction_write_existing(tdb, tdb->transaction->magic_offset,
|
||||
&magic, sizeof(magic));
|
||||
|
||||
/* ensure the recovery magic marker is on disk */
|
||||
return transaction_sync(tdb, tdb->tdb2.transaction->magic_offset,
|
||||
return transaction_sync(tdb, tdb->transaction->magic_offset,
|
||||
sizeof(magic));
|
||||
}
|
||||
|
||||
@ -978,20 +978,20 @@ static enum TDB_ERROR _tdb_transaction_prepare_commit(struct tdb_context *tdb)
|
||||
const struct tdb_methods *methods;
|
||||
enum TDB_ERROR ecode;
|
||||
|
||||
if (tdb->tdb2.transaction == NULL) {
|
||||
if (tdb->transaction == NULL) {
|
||||
return tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
|
||||
"tdb_transaction_prepare_commit:"
|
||||
" no transaction");
|
||||
}
|
||||
|
||||
if (tdb->tdb2.transaction->prepared) {
|
||||
if (tdb->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->tdb2.transaction->transaction_error) {
|
||||
if (tdb->transaction->transaction_error) {
|
||||
_tdb_transaction_cancel(tdb);
|
||||
return tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_ERROR,
|
||||
"tdb_transaction_prepare_commit:"
|
||||
@ -999,16 +999,16 @@ static enum TDB_ERROR _tdb_transaction_prepare_commit(struct tdb_context *tdb)
|
||||
}
|
||||
|
||||
|
||||
if (tdb->tdb2.transaction->nesting != 0) {
|
||||
if (tdb->transaction->nesting != 0) {
|
||||
return TDB_SUCCESS;
|
||||
}
|
||||
|
||||
/* check for a null transaction */
|
||||
if (tdb->tdb2.transaction->blocks == NULL) {
|
||||
if (tdb->transaction->blocks == NULL) {
|
||||
return TDB_SUCCESS;
|
||||
}
|
||||
|
||||
methods = tdb->tdb2.transaction->io_methods;
|
||||
methods = tdb->transaction->io_methods;
|
||||
|
||||
/* upgrade the main transaction lock region to a write lock */
|
||||
ecode = tdb_allrecord_upgrade(tdb, TDB_HASH_LOCK_START);
|
||||
@ -1025,23 +1025,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->tdb2.transaction->recovery and
|
||||
* tdb->tdb2.transaction->magic_offset. */
|
||||
/* Sets up tdb->transaction->recovery and
|
||||
* tdb->transaction->magic_offset. */
|
||||
ecode = transaction_setup_recovery(tdb);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
return ecode;
|
||||
}
|
||||
}
|
||||
|
||||
tdb->tdb2.transaction->prepared = true;
|
||||
tdb->transaction->prepared = true;
|
||||
|
||||
/* expand the file to the new size if needed */
|
||||
if (tdb->file->map_size != tdb->tdb2.transaction->old_map_size) {
|
||||
if (tdb->file->map_size != tdb->transaction->old_map_size) {
|
||||
tdb_len_t add;
|
||||
|
||||
add = tdb->file->map_size - tdb->tdb2.transaction->old_map_size;
|
||||
add = tdb->file->map_size - tdb->transaction->old_map_size;
|
||||
/* Restore original map size for tdb_expand_file */
|
||||
tdb->file->map_size = tdb->tdb2.transaction->old_map_size;
|
||||
tdb->file->map_size = tdb->transaction->old_map_size;
|
||||
ecode = methods->expand_file(tdb, add);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
return ecode;
|
||||
@ -1069,7 +1069,7 @@ _PUBLIC_ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb)
|
||||
int i;
|
||||
enum TDB_ERROR ecode;
|
||||
|
||||
if (tdb->tdb2.transaction == NULL) {
|
||||
if (tdb->transaction == NULL) {
|
||||
return tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL,
|
||||
TDB_LOG_USE_ERROR,
|
||||
"tdb_transaction_commit:"
|
||||
@ -1078,18 +1078,18 @@ _PUBLIC_ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb)
|
||||
|
||||
tdb_trace(tdb, "tdb_transaction_commit");
|
||||
|
||||
if (tdb->tdb2.transaction->nesting != 0) {
|
||||
tdb->tdb2.transaction->nesting--;
|
||||
if (tdb->transaction->nesting != 0) {
|
||||
tdb->transaction->nesting--;
|
||||
return tdb->last_error = TDB_SUCCESS;
|
||||
}
|
||||
|
||||
/* check for a null transaction */
|
||||
if (tdb->tdb2.transaction->blocks == NULL) {
|
||||
if (tdb->transaction->blocks == NULL) {
|
||||
_tdb_transaction_cancel(tdb);
|
||||
return tdb->last_error = TDB_SUCCESS;
|
||||
}
|
||||
|
||||
if (!tdb->tdb2.transaction->prepared) {
|
||||
if (!tdb->transaction->prepared) {
|
||||
ecode = _tdb_transaction_prepare_commit(tdb);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
_tdb_transaction_cancel(tdb);
|
||||
@ -1097,41 +1097,41 @@ _PUBLIC_ enum TDB_ERROR tdb_transaction_commit(struct tdb_context *tdb)
|
||||
}
|
||||
}
|
||||
|
||||
methods = tdb->tdb2.transaction->io_methods;
|
||||
methods = tdb->transaction->io_methods;
|
||||
|
||||
/* perform all the writes */
|
||||
for (i=0;i<tdb->tdb2.transaction->num_blocks;i++) {
|
||||
for (i=0;i<tdb->transaction->num_blocks;i++) {
|
||||
tdb_off_t offset;
|
||||
tdb_len_t length;
|
||||
|
||||
if (tdb->tdb2.transaction->blocks[i] == NULL) {
|
||||
if (tdb->transaction->blocks[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
offset = i * PAGESIZE;
|
||||
length = PAGESIZE;
|
||||
if (i == tdb->tdb2.transaction->num_blocks-1) {
|
||||
length = tdb->tdb2.transaction->last_block_size;
|
||||
if (i == tdb->transaction->num_blocks-1) {
|
||||
length = tdb->transaction->last_block_size;
|
||||
}
|
||||
|
||||
ecode = methods->twrite(tdb, offset,
|
||||
tdb->tdb2.transaction->blocks[i], length);
|
||||
tdb->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->tdb2.io = methods;
|
||||
tdb->io = methods;
|
||||
tdb_transaction_recover(tdb);
|
||||
|
||||
_tdb_transaction_cancel(tdb);
|
||||
|
||||
return tdb->last_error = ecode;
|
||||
}
|
||||
SAFE_FREE(tdb->tdb2.transaction->blocks[i]);
|
||||
SAFE_FREE(tdb->transaction->blocks[i]);
|
||||
}
|
||||
|
||||
SAFE_FREE(tdb->tdb2.transaction->blocks);
|
||||
tdb->tdb2.transaction->num_blocks = 0;
|
||||
SAFE_FREE(tdb->transaction->blocks);
|
||||
tdb->transaction->num_blocks = 0;
|
||||
|
||||
/* ensure the new data is on disk */
|
||||
ecode = transaction_sync(tdb, 0, tdb->file->map_size);
|
||||
@ -1156,7 +1156,7 @@ _PUBLIC_ 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->tdb2.transaction->old_map_size = tdb->file->map_size;
|
||||
tdb->transaction->old_map_size = tdb->file->map_size;
|
||||
_tdb_transaction_cancel(tdb);
|
||||
|
||||
return tdb->last_error = TDB_SUCCESS;
|
||||
@ -1218,7 +1218,7 @@ enum TDB_ERROR tdb_transaction_recover(struct tdb_context *tdb)
|
||||
}
|
||||
|
||||
/* read the full recovery data */
|
||||
ecode = tdb->tdb2.io->tread(tdb, recovery_head + sizeof(rec), data,
|
||||
ecode = tdb->io->tread(tdb, recovery_head + sizeof(rec), data,
|
||||
rec.len);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
return tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
|
||||
@ -1236,7 +1236,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->tdb2.io->twrite(tdb, ofs, p, len);
|
||||
ecode = tdb->io->twrite(tdb, ofs, p, len);
|
||||
if (ecode != TDB_SUCCESS) {
|
||||
free(data);
|
||||
return tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
|
||||
|
Loading…
x
Reference in New Issue
Block a user