Rev 686: merge tdb fixes from ctdb branch in http://samba.org/~tridge/3_0-ctdb

tridge at samba.org tridge at samba.org
Tue Jan 15 02:31:58 GMT 2008


------------------------------------------------------------
revno: 686
revision-id:tridge at samba.org-20080115023113-vli7oc3sc5gnsy08
parent: tridge at samba.org-20080109224502-aj8ydjwefl6ycby3
committer: Andrew Tridgell <tridge at samba.org>
branch nick: s3-ctdb-tridge
timestamp: Tue 2008-01-15 13:31:13 +1100
message:
  merge tdb fixes from ctdb branch
modified:
  source/lib/tdb/common/tdb.c    tdb.c-20070416112700-wu1jh7in2kvfbr2w-21
  source/lib/tdb/common/transaction.c transaction.c-20070416112700-wu1jh7in2kvfbr2w-24
=== modified file 'source/lib/tdb/common/tdb.c'
--- a/source/lib/tdb/common/tdb.c	2008-01-08 21:52:16 +0000
+++ b/source/lib/tdb/common/tdb.c	2008-01-15 02:31:13 +0000
@@ -715,6 +715,11 @@
 		goto failed;
 	}
 
+	if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &offset) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write recovery head\n"));
+		goto failed;		
+	}
+
 	/* add all the rest of the file to the freelist */
 	data_len = (tdb->map_size - TDB_DATA_START(tdb->header.hash_size)) - sizeof(struct list_struct);
 	if (data_len > 0) {

=== modified file 'source/lib/tdb/common/transaction.c'
--- a/source/lib/tdb/common/transaction.c	2008-01-08 21:52:16 +0000
+++ b/source/lib/tdb/common/transaction.c	2008-01-15 02:31:13 +0000
@@ -87,6 +87,7 @@
 
 */
 
+
 /*
   hold the context of any current transaction
 */
@@ -280,6 +281,63 @@
 	return -1;
 }
 
+
+/*
+  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 transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, 
+				      const void *buf, tdb_len_t len)
+{
+	uint32_t blk;
+
+	/* break it up into block sized chunks */
+	while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) {
+		tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size);
+		if (transaction_write_existing(tdb, off, buf, len2) != 0) {
+			return -1;
+		}
+		len -= len2;
+		off += len2;
+		if (buf != NULL) {
+			buf = (const void *)(len2 + (const char *)buf);
+		}
+	}
+
+	if (len == 0) {
+		return 0;
+	}
+
+	blk = off / tdb->transaction->block_size;
+	off = off % tdb->transaction->block_size;
+
+	if (tdb->transaction->num_blocks <= blk ||
+	    tdb->transaction->blocks[blk] == NULL) {
+		return 0;
+	}
+
+	/* overwrite part of an existing block */
+	if (buf == NULL) {
+		memset(tdb->transaction->blocks[blk] + off, 0, len);
+	} else {
+		memcpy(tdb->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;
+		}
+	}
+
+	return 0;
+
+fail:
+	TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", 
+		 (blk*tdb->transaction->block_size) + off, len));
+	tdb->transaction->transaction_error = 1;
+	return -1;
+}
+
+
 /*
   accelerated hash chain head search, using the cached hash heads
 */
@@ -629,6 +687,10 @@
 		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n"));
 		return -1;
 	}
+	if (transaction_write_existing(tdb, TDB_RECOVERY_HEAD, &recovery_head, sizeof(tdb_off_t)) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n"));
+		return -1;
+	}
 
 	return 0;
 }
@@ -726,6 +788,12 @@
 		tdb->ecode = TDB_ERR_IO;
 		return -1;
 	}
+	if (transaction_write_existing(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery data\n"));
+		free(data);
+		tdb->ecode = TDB_ERR_IO;
+		return -1;
+	}
 
 	/* as we don't have ordered writes, we have to sync the recovery
 	   data before we update the magic to indicate that the recovery
@@ -747,6 +815,11 @@
 		tdb->ecode = TDB_ERR_IO;
 		return -1;
 	}
+	if (transaction_write_existing(tdb, *magic_offset, &magic, sizeof(magic)) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery magic\n"));
+		tdb->ecode = TDB_ERR_IO;
+		return -1;
+	}
 
 	/* ensure the recovery magic marker is on disk */
 	if (transaction_sync(tdb, *magic_offset, sizeof(magic)) == -1) {
@@ -778,6 +851,7 @@
 		return -1;
 	}
 
+
 	if (tdb->transaction->nesting != 0) {
 		tdb->transaction->nesting--;
 		return 0;
@@ -916,6 +990,7 @@
 	/* use a transaction cancel to free memory and remove the
 	   transaction locks */
 	tdb_transaction_cancel(tdb);
+
 	return 0;
 }
 



More information about the samba-cvs mailing list