Commit 3835bb95 authored by Rusty Russell's avatar Rusty Russell

tdb2: rework free.c functions to return enum TDB_ERROR.

parent c02f63e6
This diff is collapsed.
......@@ -448,8 +448,8 @@ static enum TDB_ERROR COLD add_to_chain(struct tdb_context *tdb,
if (!next) {
next = alloc(tdb, 0, sizeof(struct tdb_chain), 0,
TDB_CHAIN_MAGIC, false);
if (next == TDB_OFF_ERR)
return tdb->ecode;
if (TDB_OFF_IS_ERR(next))
return next;
ecode = zero_out(tdb,
next+sizeof(struct tdb_used_record),
sizeof(struct tdb_chain));
......@@ -521,8 +521,8 @@ static enum TDB_ERROR expand_group(struct tdb_context *tdb, struct hash_info *h)
}
subhash = alloc(tdb, 0, subsize, 0, magic, false);
if (subhash == TDB_OFF_ERR) {
return tdb->ecode;
if (TDB_OFF_IS_ERR(subhash)) {
return subhash;
}
ecode = zero_out(tdb, subhash + sizeof(struct tdb_used_record),
......
......@@ -73,7 +73,6 @@ typedef uint64_t tdb_off_t;
#define TDB_RECOVERY_MAGIC (0xf53bc0e7ad124589ULL)
#define TDB_RECOVERY_INVALID_MAGIC (0x0ULL)
#define TDB_OFF_ERR ((tdb_off_t)-1)
#define TDB_OFF_IS_ERR(off) unlikely(off >= (tdb_off_t)TDB_ERR_LAST)
/* Packing errors into pointers and v.v. */
......@@ -429,25 +428,25 @@ enum TDB_ERROR delete_from_hash(struct tdb_context *tdb, struct hash_info *h);
bool is_subhash(tdb_off_t val);
/* free.c: */
int tdb_ftable_init(struct tdb_context *tdb);
enum TDB_ERROR tdb_ftable_init(struct tdb_context *tdb);
/* check.c needs these to iterate through free lists. */
tdb_off_t first_ftable(struct tdb_context *tdb);
tdb_off_t next_ftable(struct tdb_context *tdb, tdb_off_t ftable);
/* This returns space or TDB_OFF_ERR. */
/* This returns space or -ve error number. */
tdb_off_t alloc(struct tdb_context *tdb, size_t keylen, size_t datalen,
uint64_t hash, unsigned magic, bool growing);
/* Put this record in a free list. */
int add_free_record(struct tdb_context *tdb,
tdb_off_t off, tdb_len_t len_with_header);
enum TDB_ERROR add_free_record(struct tdb_context *tdb,
tdb_off_t off, tdb_len_t len_with_header);
/* Set up header for a used/ftable/htable/chain record. */
int set_header(struct tdb_context *tdb,
struct tdb_used_record *rec,
unsigned magic, uint64_t keylen, uint64_t datalen,
uint64_t actuallen, unsigned hashlow);
enum TDB_ERROR set_header(struct tdb_context *tdb,
struct tdb_used_record *rec,
unsigned magic, uint64_t keylen, uint64_t datalen,
uint64_t actuallen, unsigned hashlow);
/* Used by tdb_check to verify. */
unsigned int size_to_bucket(tdb_len_t data_len);
......
......@@ -117,9 +117,13 @@ static int tdb_new_database(struct tdb_context *tdb,
/* Free is empty. */
newdb.hdr.free_table = offsetof(struct new_database, ftable);
memset(&newdb.ftable, 0, sizeof(newdb.ftable));
set_header(NULL, &newdb.ftable.hdr, TDB_FTABLE_MAGIC, 0,
sizeof(newdb.ftable) - sizeof(newdb.ftable.hdr),
sizeof(newdb.ftable) - sizeof(newdb.ftable.hdr), 0);
tdb->ecode = set_header(NULL, &newdb.ftable.hdr, TDB_FTABLE_MAGIC, 0,
sizeof(newdb.ftable) - sizeof(newdb.ftable.hdr),
sizeof(newdb.ftable) - sizeof(newdb.ftable.hdr),
0);
if (tdb->ecode != TDB_SUCCESS) {
return -1;
}
/* Magic food */
memset(newdb.hdr.magic_food, 0, sizeof(newdb.hdr.magic_food));
......@@ -354,8 +358,10 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
}
}
if (tdb_ftable_init(tdb) == -1)
tdb->ecode = tdb_ftable_init(tdb);
if (tdb->ecode != TDB_SUCCESS) {
goto fail;
}
tdb->next = tdbs;
tdbs = tdb;
......@@ -415,9 +421,12 @@ static int update_rec_hdr(struct tdb_context *tdb,
uint64_t dataroom = rec_data_length(rec) + rec_extra_padding(rec);
enum TDB_ERROR ecode;
if (set_header(tdb, rec, TDB_USED_MAGIC, keylen, datalen,
keylen + dataroom, h))
ecode = set_header(tdb, rec, TDB_USED_MAGIC, keylen, datalen,
keylen + dataroom, h);
if (ecode != TDB_SUCCESS) {
tdb->ecode = ecode;
return -1;
}
ecode = tdb_write_convert(tdb, off, rec, sizeof(*rec));
if (ecode != TDB_SUCCESS) {
......@@ -440,16 +449,19 @@ static int replace_data(struct tdb_context *tdb,
/* Allocate a new record. */
new_off = alloc(tdb, key.dsize, dbuf.dsize, h->h, TDB_USED_MAGIC,
growing);
if (unlikely(new_off == TDB_OFF_ERR))
if (TDB_OFF_IS_ERR(new_off)) {
tdb->ecode = new_off;
return -1;
}
/* We didn't like the existing one: remove it. */
if (old_off) {
add_stat(tdb, frees, 1);
add_free_record(tdb, old_off,
sizeof(struct tdb_used_record)
+ key.dsize + old_room);
ecode = replace_in_hash(tdb, h, new_off);
ecode = add_free_record(tdb, old_off,
sizeof(struct tdb_used_record)
+ key.dsize + old_room);
if (ecode == TDB_SUCCESS)
ecode = replace_in_hash(tdb, h, new_off);
} else {
ecode = add_to_hash(tdb, h, new_off);
}
......@@ -676,12 +688,15 @@ int tdb_delete(struct tdb_context *tdb, struct tdb_data key)
/* Free the deleted entry. */
add_stat(tdb, frees, 1);
if (add_free_record(tdb, off,
sizeof(struct tdb_used_record)
+ rec_key_length(&rec)
+ rec_data_length(&rec)
+ rec_extra_padding(&rec)) != 0)
ecode = add_free_record(tdb, off,
sizeof(struct tdb_used_record)
+ rec_key_length(&rec)
+ rec_data_length(&rec)
+ rec_extra_padding(&rec));
if (ecode != TDB_SUCCESS) {
tdb->ecode = ecode;
goto unlock_err;
}
tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range, F_WRLCK);
return 0;
......
......@@ -11,8 +11,8 @@
#include "logging.h"
/* FIXME: Check these! */
#define INITIAL_TDB_MALLOC "tdb.c", 178, FAILTEST_MALLOC
#define LOGGING_MALLOC "tdb.c", 734, FAILTEST_MALLOC
#define INITIAL_TDB_MALLOC "tdb.c", 182, FAILTEST_MALLOC
#define LOGGING_MALLOC "tdb.c", 792, FAILTEST_MALLOC
#define URANDOM_OPEN "tdb.c", 49, FAILTEST_OPEN
#define URANDOM_READ "tdb.c", 29, FAILTEST_READ
......
......@@ -67,7 +67,7 @@ int main(int argc, char *argv[])
/* Allocate a new record. */
new_off = alloc(tdb, key.dsize, dbuf.dsize, h.h,
TDB_USED_MAGIC, false);
ok1(new_off != TDB_OFF_ERR);
ok1(!TDB_OFF_IS_ERR(new_off));
/* We should be able to add it now. */
ok1(add_to_hash(tdb, &h, new_off) == 0);
......@@ -228,7 +228,7 @@ int main(int argc, char *argv[])
/* Allocate a new record. */
new_off = alloc(tdb, key.dsize, dbuf.dsize, h.h,
TDB_USED_MAGIC, false);
ok1(new_off != TDB_OFF_ERR);
ok1(!TDB_OFF_IS_ERR(new_off));
ok1(add_to_hash(tdb, &h, new_off) == 0);
/* Make sure we fill it in for later finding. */
......
......@@ -681,9 +681,10 @@ static int tdb_recovery_allocate(struct tdb_context *tdb,
the transaction) */
if (recovery_head != 0) {
add_stat(tdb, frees, 1);
if (add_free_record(tdb, recovery_head,
sizeof(rec) + rec.max_len) != 0) {
tdb_logerr(tdb, tdb->ecode, TDB_LOG_ERROR,
ecode = add_free_record(tdb, recovery_head,
sizeof(rec) + rec.max_len);
if (ecode != TDB_SUCCESS) {
tdb_logerr(tdb, ecode, TDB_LOG_ERROR,
"tdb_recovery_allocate:"
" failed to free previous recovery area");
return -1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment