tdb: add TDB_DISALLOW_NESTING and make TDB_ALLOW_NESTING the default behavior
authorStefan Metzmacher <metze@samba.org>
Thu, 19 Nov 2009 08:34:05 +0000 (09:34 +0100)
committerStefan Metzmacher <metze@samba.org>
Wed, 16 Dec 2009 07:03:54 +0000 (08:03 +0100)
We need to keep TDB_ALLOW_NESTING as default behavior,
so that existing code continues to work.

However we may change the default together with a major version
number change in future.

metze
(cherry picked from samba commit 3b9f19ed919fef2e88b2f92ae541e07bc7379cd1)

Signed-off-by: Stefan Metzmacher <metze@samba.org>
lib/tdb/common/open.c
lib/tdb/common/tdb.c
lib/tdb/common/transaction.c
lib/tdb/docs/README
lib/tdb/include/tdb.h

index 4ea4499dc14225a042de7adb287a8de6ba44fe23..4d4f95a3daa7e7c57a1349467c7503a077ba8df4 100644 (file)
@@ -202,6 +202,23 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
                tdb->flags &= ~TDB_CLEAR_IF_FIRST;
        }
 
+       if ((tdb->flags & TDB_ALLOW_NESTING) &&
+           (tdb->flags & TDB_DISALLOW_NESTING)) {
+               tdb->ecode = TDB_ERR_NESTING;
+               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
+                       "allow_nesting and disallow_nesting are not allowed together!"));
+               errno = EINVAL;
+               goto fail;
+       }
+
+       /*
+        * TDB_ALLOW_NESTING is the default behavior.
+        * Note: this may change in future versions!
+        */
+       if (!(tdb->flags & TDB_DISALLOW_NESTING)) {
+               tdb->flags |= TDB_ALLOW_NESTING;
+       }
+
        /* internal databases don't mmap or lock, and start off cleared */
        if (tdb->flags & TDB_INTERNAL) {
                tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP);
index 564c5fed5c8331fcd713a0267e6478588559bfbd..d2688def04743ae4e03cc84489cf251bec30dc8b 100644 (file)
@@ -730,11 +730,41 @@ int tdb_get_flags(struct tdb_context *tdb)
 
 void tdb_add_flags(struct tdb_context *tdb, unsigned flags)
 {
+       if ((flags & TDB_ALLOW_NESTING) &&
+           (flags & TDB_DISALLOW_NESTING)) {
+               tdb->ecode = TDB_ERR_NESTING;
+               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_add_flags: "
+                       "allow_nesting and disallow_nesting are not allowed together!"));
+               return;
+       }
+
+       if (flags & TDB_ALLOW_NESTING) {
+               tdb->flags &= ~TDB_DISALLOW_NESTING;
+       }
+       if (flags & TDB_DISALLOW_NESTING) {
+               tdb->flags &= ~TDB_ALLOW_NESTING;
+       }
+
        tdb->flags |= flags;
 }
 
 void tdb_remove_flags(struct tdb_context *tdb, unsigned flags)
 {
+       if ((flags & TDB_ALLOW_NESTING) &&
+           (flags & TDB_DISALLOW_NESTING)) {
+               tdb->ecode = TDB_ERR_NESTING;
+               TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_remove_flags: "
+                       "allow_nesting and disallow_nesting are not allowed together!"));
+               return;
+       }
+
+       if (flags & TDB_ALLOW_NESTING) {
+               tdb->flags |= TDB_DISALLOW_NESTING;
+       }
+       if (flags & TDB_DISALLOW_NESTING) {
+               tdb->flags |= TDB_ALLOW_NESTING;
+       }
+
        tdb->flags &= ~flags;
 }
 
index 501cd62b96ee367626f148f24eebbfd07a5de3b2..20f2bfc2cd4595a27114fc9662c483c83b72b29d 100644 (file)
     fsync/msync calls are made.
 
   - if TDB_ALLOW_NESTING is passed to flags in tdb open, or added using
-    tdb_add_flags() transaction is enabled.
-    The default is that transaction nesting is not allowed and an attempt
-    to create a nested transaction will fail with TDB_ERR_NESTING.
+    tdb_add_flags() transaction nesting is enabled.
+    It resets the TDB_DISALLOW_NESTING flag, as both cannot be used together.
+    The default is that transaction nesting is allowed.
+    Note: this default may change in future versions of tdb.
 
     Beware. when transactions are nested a transaction successfully
     completed with tdb_transaction_commit() can be silently unrolled later.
+
+  - if TDB_DISALLOW_NESTING is passed to flags in tdb open, or added using
+    tdb_add_flags() transaction nesting is disabled.
+    It resets the TDB_ALLOW_NESTING flag, as both cannot be used together.
+    An attempt create a nested transaction will fail with TDB_ERR_NESTING.
+    The default is that transaction nesting is allowed.
+    Note: this default may change in future versions of tdb.
 */
 
 
index 7bf485408c4562d9c18dd44f441824d228994358..c02ee0e030ad9e1ae6b71947d18cbd5b23433705 100644 (file)
@@ -69,6 +69,10 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
     TDB_NOLOCK - don't do any locking
     TDB_NOMMAP - don't use mmap
     TDB_NOSYNC - don't synchronise transactions to disk
+    TDB_SEQNUM - maintain a sequence number
+    TDB_VOLATILE - activate the per-hashchain freelist, default 5
+    TDB_ALLOW_NESTING - allow transactions to nest
+    TDB_DISALLOW_NESTING - disallow transactions to nest
 
 ----------------------------------------------------------------------
 TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags,
index 5cc1eecdd114c6ff689055bc5e2cc8d2179fe3af..db9ce4ad276f094c1ec421d783970f4efaabd428 100644 (file)
@@ -49,6 +49,7 @@ extern "C" {
 #define TDB_SEQNUM   128 /* maintain a sequence number */
 #define TDB_VOLATILE   256 /* Activate the per-hashchain freelist, default 5 */
 #define TDB_ALLOW_NESTING 512 /* Allow transactions to nest */
+#define TDB_DISALLOW_NESTING 1024 /* Disallow transactions to nest */
 
 /* error codes */
 enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK,