summaryrefslogtreecommitdiff
path: root/lib/tdb/common
diff options
context:
space:
mode:
authorbubulle <bubulle@alioth.debian.org>2010-01-15 21:59:36 +0000
committerbubulle <bubulle@alioth.debian.org>2010-01-15 21:59:36 +0000
commit4689cc0418955c954941e513b6e65747b10695af (patch)
tree0e30a8cc95d344c11f201ac8a938e8e263358be0 /lib/tdb/common
parentdfd163a320555d5e2674a49005327c516074472f (diff)
downloadsamba-4689cc0418955c954941e513b6e65747b10695af.tar.gz
Merge upstream 3.5.0~rc1~dfsg
git-svn-id: svn://svn.debian.org/svn/pkg-samba/branches/samba/experimental@3228 fc4039ab-9d04-0410-8cac-899223bdd6b0
Diffstat (limited to 'lib/tdb/common')
-rw-r--r--lib/tdb/common/open.c28
-rw-r--r--lib/tdb/common/tdb.c30
-rw-r--r--lib/tdb/common/transaction.c19
3 files changed, 72 insertions, 5 deletions
diff --git a/lib/tdb/common/open.c b/lib/tdb/common/open.c
index 1ba2e7bd11..4d4f95a3da 100644
--- a/lib/tdb/common/open.c
+++ b/lib/tdb/common/open.c
@@ -163,6 +163,9 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
}
tdb_io_init(tdb);
tdb->fd = -1;
+#ifdef TDB_TRACE
+ tdb->tracefd = -1;
+#endif
tdb->name = NULL;
tdb->map_ptr = NULL;
tdb->flags = tdb_flags;
@@ -199,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);
@@ -207,10 +227,6 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!"));
goto fail;
}
-#ifdef TDB_TRACE
- /* All tracing will fail. That's ok. */
- tdb->tracefd = -1;
-#endif
goto internal;
}
@@ -403,8 +419,10 @@ int tdb_close(struct tdb_context *tdb)
tdb_munmap(tdb);
}
SAFE_FREE(tdb->name);
- if (tdb->fd != -1)
+ if (tdb->fd != -1) {
ret = close(tdb->fd);
+ tdb->fd = -1;
+ }
SAFE_FREE(tdb->lockrecs);
/* Remove from contexts list */
diff --git a/lib/tdb/common/tdb.c b/lib/tdb/common/tdb.c
index 564c5fed5c..d2688def04 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 035b4e1d54..20f2bfc2cd 100644
--- a/lib/tdb/common/transaction.c
+++ b/lib/tdb/common/transaction.c
@@ -85,6 +85,21 @@
still available, but no transaction recovery area is used and no
fsync/msync calls are made.
+ - if TDB_ALLOW_NESTING is passed to flags in tdb open, or added using
+ 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.
*/
@@ -427,6 +442,10 @@ int tdb_transaction_start(struct tdb_context *tdb)
/* cope with nested tdb_transaction_start() calls */
if (tdb->transaction != NULL) {
+ if (!(tdb->flags & TDB_ALLOW_NESTING)) {
+ tdb->ecode = TDB_ERR_NESTING;
+ return -1;
+ }
tdb->transaction->nesting++;
TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_start: nesting %d\n",
tdb->transaction->nesting));