Rev 329: global lock should imply the transaction lock in http://samba.org/~tridge/ctdb

tridge at samba.org tridge at samba.org
Tue May 22 03:14:53 GMT 2007


------------------------------------------------------------
revno: 329
revision-id: tridge at samba.org-20070522031451-628wjb3bbna6p4vc
parent: tridge at samba.org-20070519111106-hmbognp9baltnxgw
committer: Andrew Tridgell <tridge at samba.org>
branch nick: tridge
timestamp: Tue 2007-05-22 13:14:51 +1000
message:
  global lock should imply the transaction lock
modified:
  lib/tdb/common/lock.c          lock.c-20070220022425-m1wibgjq7n5hahs6-7
  lib/tdb/common/tdb_private.h   tdb_private.h-20070220022425-m1wibgjq7n5hahs6-10
  lib/tdb/common/transaction.c   transaction.c-20070220022425-m1wibgjq7n5hahs6-11
  lib/tdb/common/traverse.c      traverse.c-20070220022425-m1wibgjq7n5hahs6-12
=== modified file 'lib/tdb/common/lock.c'
--- a/lib/tdb/common/lock.c	2007-05-12 04:33:10 +0000
+++ b/lib/tdb/common/lock.c	2007-05-22 03:14:51 +0000
@@ -285,6 +285,41 @@
 	return ret;
 }
 
+/*
+  get the transaction lock
+ */
+int tdb_transaction_lock(struct tdb_context *tdb, int ltype)
+{
+	if (tdb->have_transaction_lock || tdb->global_lock.count) {
+		return 0;
+	}
+	if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, ltype, 
+				     F_SETLKW, 0, 1) == -1) {
+		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_lock: failed to get transaction lock\n"));
+		tdb->ecode = TDB_ERR_LOCK;
+		return -1;
+	}
+	tdb->have_transaction_lock = 1;
+	return 0;
+}
+
+/*
+  release the transaction lock
+ */
+int tdb_transaction_unlock(struct tdb_context *tdb)
+{
+	int ret;
+	if (!tdb->have_transaction_lock) {
+		return 0;
+	}
+	ret = tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+	if (ret == 0) {
+		tdb->have_transaction_lock = 0;
+	}
+	return ret;
+}
+
+
 
 
 /* lock/unlock entire database */

=== modified file 'lib/tdb/common/tdb_private.h'
--- a/lib/tdb/common/tdb_private.h	2007-04-21 08:09:37 +0000
+++ b/lib/tdb/common/tdb_private.h	2007-05-22 03:14:51 +0000
@@ -170,6 +170,7 @@
 	struct tdb_transaction *transaction;
 	int page_size;
 	int max_dead_records;
+	bool have_transaction_lock;
 };
 
 
@@ -181,6 +182,8 @@
 int tdb_lock(struct tdb_context *tdb, int list, int ltype);
 int tdb_unlock(struct tdb_context *tdb, int list, int ltype);
 int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len);
+int tdb_transaction_lock(struct tdb_context *tdb, int ltype);
+int tdb_transaction_unlock(struct tdb_context *tdb);
 int tdb_brlock_upgrade(struct tdb_context *tdb, tdb_off_t offset, size_t len);
 int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off);
 int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off);

=== modified file 'lib/tdb/common/transaction.c'
--- a/lib/tdb/common/transaction.c	2007-04-16 12:52:58 +0000
+++ b/lib/tdb/common/transaction.c	2007-05-22 03:14:51 +0000
@@ -423,9 +423,7 @@
 	/* get the transaction write lock. This is a blocking lock. As
 	   discussed with Volker, there are a number of ways we could
 	   make this async, which we will probably do in the future */
-	if (tdb_brlock(tdb, TRANSACTION_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) {
-		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get transaction lock\n"));
-		tdb->ecode = TDB_ERR_LOCK;
+	if (tdb_transaction_lock(tdb, F_WRLCK) == -1) {
 		SAFE_FREE(tdb->transaction);
 		return -1;
 	}
@@ -469,6 +467,7 @@
 			      TDB_HASHTABLE_SIZE(tdb)) != 0) {
 		TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to prime hash table\n"));
 		tdb->ecode = TDB_ERR_IO;
+		tdb->methods = tdb->transaction->io_methods;
 		goto fail;
 	}
 
@@ -476,7 +475,7 @@
 	
 fail:
 	tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
-	tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+	tdb_transaction_unlock(tdb);
 	SAFE_FREE(tdb->transaction->hash_heads);
 	SAFE_FREE(tdb->transaction);
 	return -1;
@@ -531,7 +530,7 @@
 	tdb->methods = tdb->transaction->io_methods;
 
 	tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
-	tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+	tdb_transaction_unlock(tdb);
 	SAFE_FREE(tdb->transaction->hash_heads);
 	SAFE_FREE(tdb->transaction);
 	

=== modified file 'lib/tdb/common/traverse.c'
--- a/lib/tdb/common/traverse.c	2007-02-20 02:24:45 +0000
+++ b/lib/tdb/common/traverse.c	2007-05-22 03:14:51 +0000
@@ -205,12 +205,10 @@
 {
 	struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
 	int ret;
-	
+
 	/* we need to get a read lock on the transaction lock here to
 	   cope with the lock ordering semantics of solaris10 */
-	if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1) {
-		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse_read: failed to get transaction lock\n"));
-		tdb->ecode = TDB_ERR_LOCK;
+	if (tdb_transaction_lock(tdb, F_RDLCK)) {
 		return -1;
 	}
 
@@ -218,7 +216,7 @@
 	ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
 	tdb->traverse_read--;
 
-	tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+	tdb_transaction_unlock(tdb);
 
 	return ret;
 }
@@ -237,15 +235,13 @@
 		return tdb_traverse_read(tdb, fn, private_data);
 	}
 	
-	if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) {
-		TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse: failed to get transaction lock\n"));
-		tdb->ecode = TDB_ERR_LOCK;
+	if (tdb_transaction_lock(tdb, F_WRLCK)) {
 		return -1;
 	}
 
 	ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
 
-	tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+	tdb_transaction_unlock(tdb);
 
 	return ret;
 }



More information about the samba-cvs mailing list