From 3b9f19ed919fef2e88b2f92ae541e07bc7379cd1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Nov 2009 09:34:05 +0100 Subject: tdb: add TDB_DISALLOW_NESTING and make TDB_ALLOW_NESTING the default behavior 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 --- lib/tdb/common/open.c | 17 +++++++++++++++++ lib/tdb/common/tdb.c | 30 ++++++++++++++++++++++++++++++ lib/tdb/common/transaction.c | 14 +++++++++++--- lib/tdb/docs/README | 4 ++++ lib/tdb/include/tdb.h | 1 + 5 files changed, 63 insertions(+), 3 deletions(-) diff --git a/lib/tdb/common/open.c b/lib/tdb/common/open.c index 4ea4499dc14..4d4f95a3daa 100644 --- a/lib/tdb/common/open.c +++ b/lib/tdb/common/open.c @@ -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); diff --git a/lib/tdb/common/tdb.c b/lib/tdb/common/tdb.c index 564c5fed5c8..d2688def047 100644 --- a/lib/tdb/common/tdb.c +++ b/lib/tdb/common/tdb.c @@ -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; } diff --git a/lib/tdb/common/transaction.c b/lib/tdb/common/transaction.c index 501cd62b96e..20f2bfc2cd4 100644 --- a/lib/tdb/common/transaction.c +++ b/lib/tdb/common/transaction.c @@ -86,12 +86,20 @@ 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. */ diff --git a/lib/tdb/docs/README b/lib/tdb/docs/README index 7bf485408c4..c02ee0e030a 100644 --- a/lib/tdb/docs/README +++ b/lib/tdb/docs/README @@ -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, diff --git a/lib/tdb/include/tdb.h b/lib/tdb/include/tdb.h index 5cc1eecdd11..db9ce4ad276 100644 --- a/lib/tdb/include/tdb.h +++ b/lib/tdb/include/tdb.h @@ -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, -- cgit v1.2.1