summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2014-02-10 01:31:50 +0100
committerVolker Lendecke <vl@samba.org>2014-06-26 10:00:11 +0200
commitf5a777a36ca1767df70087dfd084e86d4e97d242 (patch)
tree087ce078278e60d1ddcec1fd7e7d0f278da764db
parent8fa0cde05f41ba9a37ed9d1fdb7b515d661426d8 (diff)
downloadsamba-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.c79
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