summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/tdb2/io.c5
-rw-r--r--lib/tdb2/private.h2
-rw-r--r--lib/tdb2/tdb.c15
-rw-r--r--lib/tdb2/tdb1.h4
-rw-r--r--lib/tdb2/test/run-tdb1-seqnum-wrap.c39
5 files changed, 60 insertions, 5 deletions
diff --git a/lib/tdb2/io.c b/lib/tdb2/io.c
index 6f92a809ba..3648505f12 100644
--- a/lib/tdb2/io.c
+++ b/lib/tdb2/io.c
@@ -584,6 +584,11 @@ void tdb_inc_seqnum(struct tdb_context *tdb)
{
tdb_off_t seq;
+ if (tdb->flags & TDB_VERSION1) {
+ tdb1_increment_seqnum_nonblock(tdb);
+ return;
+ }
+
if (likely(!(tdb->flags & TDB_CONVERT))) {
int64_t *direct;
diff --git a/lib/tdb2/private.h b/lib/tdb2/private.h
index 50c48fa9a5..71ef07538e 100644
--- a/lib/tdb2/private.h
+++ b/lib/tdb2/private.h
@@ -691,6 +691,8 @@ enum TDB_ERROR tdb1_parse_record(struct tdb_context *tdb, TDB_DATA key,
TDB_DATA data,
void *private_data),
void *private_data);
+void tdb1_increment_seqnum_nonblock(struct tdb_context *tdb);
+int tdb1_get_seqnum(struct tdb_context *tdb);
/* tdb1_transaction.c: */
int tdb1_transaction_start(struct tdb_context *tdb);
diff --git a/lib/tdb2/tdb.c b/lib/tdb2/tdb.c
index 787ee7bd50..d4036d99be 100644
--- a/lib/tdb2/tdb.c
+++ b/lib/tdb2/tdb.c
@@ -565,7 +565,20 @@ const char *tdb_name(const struct tdb_context *tdb)
int64_t tdb_get_seqnum(struct tdb_context *tdb)
{
- tdb_off_t off = tdb_read_off(tdb, offsetof(struct tdb_header, seqnum));
+ tdb_off_t off;
+
+ if (tdb->flags & TDB_VERSION1) {
+ tdb1_off_t val;
+ tdb->last_error = TDB_SUCCESS;
+ val = tdb1_get_seqnum(tdb);
+
+ if (tdb->last_error != TDB_SUCCESS)
+ return tdb->last_error;
+ else
+ return val;
+ }
+
+ off = tdb_read_off(tdb, offsetof(struct tdb_header, seqnum));
if (TDB_OFF_IS_ERR(off))
tdb->last_error = off;
else
diff --git a/lib/tdb2/tdb1.h b/lib/tdb2/tdb1.h
index 59c2dd0d1d..90cd7fa14a 100644
--- a/lib/tdb2/tdb1.h
+++ b/lib/tdb2/tdb1.h
@@ -38,10 +38,6 @@
void tdb1_set_max_dead(struct tdb_context *tdb, int max_dead);
-int tdb1_get_seqnum(struct tdb_context *tdb);
-
-void tdb1_increment_seqnum_nonblock(struct tdb_context *tdb);
-
uint64_t tdb1_incompatible_hash(const void *key, size_t len, uint64_t seed, void *);
/* @} ******************************************************************/
diff --git a/lib/tdb2/test/run-tdb1-seqnum-wrap.c b/lib/tdb2/test/run-tdb1-seqnum-wrap.c
new file mode 100644
index 0000000000..c3eb278e1a
--- /dev/null
+++ b/lib/tdb2/test/run-tdb1-seqnum-wrap.c
@@ -0,0 +1,39 @@
+#include "tdb2-source.h"
+#include <ccan/tap/tap.h>
+#include <stdlib.h>
+#include <err.h>
+#include "logging.h"
+
+int main(int argc, char *argv[])
+{
+ struct tdb_context *tdb;
+ unsigned int i;
+ struct tdb1_header hdr;
+ struct tdb_data key = { (unsigned char *)&hdr, sizeof(hdr) };
+ struct tdb_data data = { (unsigned char *)&hdr, sizeof(hdr) };
+ int flags[] = { TDB_DEFAULT, TDB_NOMMAP,
+ TDB_CONVERT, TDB_NOMMAP|TDB_CONVERT };
+
+ plan_tests(sizeof(flags) / sizeof(flags[0]) * 7);
+ for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
+ tdb = tdb_open("run-tdb1-seqnum-wrap.tdb1",
+ flags[i]|TDB_VERSION1|TDB_SEQNUM,
+ O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
+ ok1(tdb);
+ if (!tdb)
+ break;
+ ok1(pread(tdb->file->fd, &hdr, sizeof(hdr), 0) == sizeof(hdr));
+ hdr.sequence_number = 0xFFFFFFFF;
+ ok1(pwrite(tdb->file->fd, &hdr, sizeof(hdr), 0) == sizeof(hdr));
+
+ /* Must not be negative: that would mean an error! */
+ ok1(tdb_get_seqnum(tdb) == 0xFFFFFFFF);
+
+ ok1(tdb_store(tdb, key, data, TDB_INSERT) == TDB_SUCCESS);
+ ok1(tdb_get_seqnum(tdb) == 0);
+ tdb_close(tdb);
+ ok1(tap_log_messages == 0);
+ }
+
+ return exit_status();
+}