diff options
author | Michael Adam <obnox@samba.org> | 2014-02-10 01:31:50 +0100 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2014-06-26 10:00:11 +0200 |
commit | f5a777a36ca1767df70087dfd084e86d4e97d242 (patch) | |
tree | 087ce078278e60d1ddcec1fd7e7d0f278da764db | |
parent | 8fa0cde05f41ba9a37ed9d1fdb7b515d661426d8 (diff) | |
download | samba-f5a777a36ca1767df70087dfd084e86d4e97d242.tar.gz samba-f5a777a36ca1767df70087dfd084e86d4e97d242.tar.xz samba-f5a777a36ca1767df70087dfd084e86d4e97d242.zip |
tdb: factor read_record_on_left() out of tdb_free()
Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
-rw-r--r-- | lib/tdb/common/freelist.c | 79 |
1 files changed, 49 insertions, 30 deletions
diff --git a/lib/tdb/common/freelist.c b/lib/tdb/common/freelist.c index 2aeeb1c383..e6f7db511f 100644 --- a/lib/tdb/common/freelist.c +++ b/lib/tdb/common/freelist.c @@ -97,10 +97,58 @@ static int update_tailer(struct tdb_context *tdb, tdb_off_t offset, &totalsize); } +/** + * Read the record directly on the left. + * Fail if there is no record on the left. + */ +static int read_record_on_left(struct tdb_context *tdb, tdb_off_t offset, + tdb_off_t *left_p, + struct tdb_record *left_r) +{ + tdb_off_t left = offset - sizeof(tdb_off_t); + struct tdb_record l; + tdb_off_t leftsize; + + if (offset - sizeof(tdb_off_t) > TDB_DATA_START(tdb->hash_size)) { + + /* Read in tailer and jump back to header */ + if (tdb_ofs_read(tdb, left, &leftsize) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left offset read failed at %u\n", left)); + return -1; + } + + /* it could be uninitialised data */ + if (leftsize == 0 || leftsize == TDB_PAD_U32) { + return -1; + } + + left = offset - leftsize; + + if (leftsize > offset || + left < TDB_DATA_START(tdb->hash_size)) { + return -1; + } + + /* Now read in the left record */ + if (tdb->methods->tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); + return -1; + } + + *left_p = left; + *left_r = l; + } + + return -1; +} + /* Add an element into the freelist. Merge adjacent records if necessary. */ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) { + tdb_off_t left; + struct tdb_record l; + /* Allocation and tailer lock */ if (tdb_lock(tdb, -1, F_WRLCK) != 0) return -1; @@ -138,36 +186,7 @@ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) left: #endif - /* Look left */ - if (offset - sizeof(tdb_off_t) > TDB_DATA_START(tdb->hash_size)) { - tdb_off_t left = offset - sizeof(tdb_off_t); - struct tdb_record l; - tdb_off_t leftsize; - - /* Read in tailer and jump back to header */ - if (tdb_ofs_read(tdb, left, &leftsize) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left offset read failed at %u\n", left)); - goto update; - } - - /* it could be uninitialised data */ - if (leftsize == 0 || leftsize == TDB_PAD_U32) { - goto update; - } - - left = offset - leftsize; - - if (leftsize > offset || - left < TDB_DATA_START(tdb->hash_size)) { - goto update; - } - - /* Now read in the left record */ - if (tdb->methods->tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); - goto update; - } - + if (read_record_on_left(tdb, offset, &left, &l) == 0) { /* If it's free, expand to include it. */ if (l.magic == TDB_FREE_MAGIC) { /* we now merge the new record into the left record, rather than the other |