svn commit: samba r14799 - in branches/SAMBA_4_0/source/lib/tdb: common include

tridge at samba.org tridge at samba.org
Thu Mar 30 04:52:39 GMT 2006


Author: tridge
Date: 2006-03-30 04:52:39 +0000 (Thu, 30 Mar 2006)
New Revision: 14799

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=14799

Log:

added a tdb_get_seqnum() call, and the TDB_SEQNUM flag. This allows
for an extremely lightweight test to see if a tdb has possibly
changed.

Modified:
   branches/SAMBA_4_0/source/lib/tdb/common/tdb.c
   branches/SAMBA_4_0/source/lib/tdb/common/tdb_private.h
   branches/SAMBA_4_0/source/lib/tdb/common/transaction.c
   branches/SAMBA_4_0/source/lib/tdb/include/tdb.h


Changeset:
Modified: branches/SAMBA_4_0/source/lib/tdb/common/tdb.c
===================================================================
--- branches/SAMBA_4_0/source/lib/tdb/common/tdb.c	2006-03-30 04:39:37 UTC (rev 14798)
+++ branches/SAMBA_4_0/source/lib/tdb/common/tdb.c	2006-03-30 04:52:39 UTC (rev 14799)
@@ -30,6 +30,33 @@
 
 TDB_DATA tdb_null;
 
+/*
+  increment the tdb sequence number if the tdb has been opened using
+  the TDB_SEQNUM flag
+*/
+static void tdb_increment_seqnum(struct tdb_context *tdb)
+{
+	tdb_off_t seqnum=0;
+	
+	if (!(tdb->flags & TDB_SEQNUM)) {
+		return;
+	}
+
+	if (tdb_brlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, F_SETLKW, 1) != 0) {
+		return;
+	}
+
+	/* we ignore errors from this, as we have no sane way of
+	   dealing with them.
+	*/
+	tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum);
+	seqnum++;
+	tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum);
+
+	tdb_brlock(tdb, TDB_SEQNUM_OFS, F_UNLCK, F_SETLKW, 1);
+}
+
+
 /* Returns 0 on fail.  On success, return offset of record, and fills
    in rec */
 static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, u32 hash,
@@ -203,6 +230,11 @@
 	if (!(rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, &rec)))
 		return -1;
 	ret = tdb_do_delete(tdb, rec_ptr, &rec);
+
+	if (ret == 0) {
+		tdb_increment_seqnum(tdb);
+	}
+
 	if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0)
 		TDB_LOG((tdb, 0, "tdb_delete: WARNING tdb_unlock failed!\n"));
 	return ret;
@@ -295,6 +327,9 @@
 		/* Need to tdb_unallocate() here */
 		goto fail;
 	}
+
+	tdb_increment_seqnum(tdb);
+
  out:
 	SAFE_FREE(p); 
 	tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
@@ -369,3 +404,22 @@
 {
 	return tdb->log_fn;
 }
+
+
+/*
+  get the tdb sequence number. Only makes sense if the writers opened
+  with TDB_SEQNUM set. Note that this sequence number will wrap quite
+  quickly, so it should only be used for a 'has something changed'
+  test, not for code that relies on the count of the number of changes
+  made. If you want a counter then use a tdb record.
+
+  The aim of this sequence number is to allow for a very lightweight
+  test of a possible tdb change.
+*/
+int tdb_get_seqnum(struct tdb_context *tdb)
+{
+	tdb_off_t seqnum=0;
+
+	tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum);
+	return seqnum;
+}

Modified: branches/SAMBA_4_0/source/lib/tdb/common/tdb_private.h
===================================================================
--- branches/SAMBA_4_0/source/lib/tdb/common/tdb_private.h	2006-03-30 04:39:37 UTC (rev 14798)
+++ branches/SAMBA_4_0/source/lib/tdb/common/tdb_private.h	2006-03-30 04:52:39 UTC (rev 14799)
@@ -94,6 +94,7 @@
 #define TDB_HASHTABLE_SIZE(tdb) ((tdb->header.hash_size+1)*sizeof(tdb_off_t))
 #define TDB_DATA_START(hash_size) TDB_HASH_TOP(hash_size-1)
 #define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start)
+#define TDB_SEQNUM_OFS    offsetof(struct tdb_header, sequence_number)
 #define TDB_PAD_BYTE 0x42
 #define TDB_PAD_U32  0x42424242
 
@@ -155,7 +156,8 @@
 	u32 hash_size; /* number of hash entries */
 	tdb_off_t rwlocks; /* obsolete - kept to detect old formats */
 	tdb_off_t recovery_start; /* offset of transaction recovery region */
-	tdb_off_t reserved[30];
+	tdb_off_t sequence_number; /* used when TDB_SEQNUM is set */
+	tdb_off_t reserved[29];
 };
 
 struct tdb_lock_type {

Modified: branches/SAMBA_4_0/source/lib/tdb/common/transaction.c
===================================================================
--- branches/SAMBA_4_0/source/lib/tdb/common/transaction.c	2006-03-30 04:39:37 UTC (rev 14798)
+++ branches/SAMBA_4_0/source/lib/tdb/common/transaction.c	2006-03-30 04:52:39 UTC (rev 14799)
@@ -892,6 +892,12 @@
 
 	tdb_brlock_len(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1);
 
+	/*
+	  TODO: maybe write to some dummy hdr field, or write to magic
+	  offset without mmap, before the last sync, instead of the
+	  utime() call
+	*/
+
 	/* on some systems (like Linux 2.6.x) changes via mmap/msync
 	   don't change the mtime of the file, this means the file may
 	   not be backed up (as tdb rounding to block sizes means that

Modified: branches/SAMBA_4_0/source/lib/tdb/include/tdb.h
===================================================================
--- branches/SAMBA_4_0/source/lib/tdb/include/tdb.h	2006-03-30 04:39:37 UTC (rev 14798)
+++ branches/SAMBA_4_0/source/lib/tdb/include/tdb.h	2006-03-30 04:52:39 UTC (rev 14799)
@@ -46,6 +46,7 @@
 #define TDB_CONVERT 16 /* convert endian (internal use) */
 #define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */
 #define TDB_NOSYNC   64 /* don't use synchronous transactions */
+#define TDB_SEQNUM   128 /* maintain a sequence number */
 
 #define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret)
 
@@ -109,6 +110,7 @@
 int tdb_transaction_commit(struct tdb_context *tdb);
 int tdb_transaction_cancel(struct tdb_context *tdb);
 int tdb_transaction_recover(struct tdb_context *tdb);
+int tdb_get_seqnum(struct tdb_context *tdb);
 
 /* Low level locking functions: use with care */
 int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key);



More information about the samba-cvs mailing list