Browse Source

tdb2: use tdb->flags & TDB_RDONLY instead of tdb->read_only for TDB1 code.

There's also a semantic change here: for tdb1, being read-only meant no
locking, and it was an error to try to lock a r/o database.  For TDB2, you'd
need to specify TDB_NOLOCK, which suppresses locking silently.
Rusty Russell 14 years ago
parent
commit
4dc29a338f

+ 2 - 3
ccan/tdb2/tdb1_check.c

@@ -334,9 +334,8 @@ int tdb1_check(struct tdb1_context *tdb,
 	tdb1_len_t dead;
 	bool locked;
 
-	/* Read-only databases use no locking at all: it's best-effort.
-	 * We may have a write lock already, so skip that case too. */
-	if (tdb->read_only || tdb->file->allrecord_lock.count != 0) {
+	/* We may have a write lock already, so don't re-lock. */
+	if (tdb->file->allrecord_lock.count != 0) {
 		locked = false;
 	} else {
 		if (tdb1_lockall_read(tdb) == -1)

+ 9 - 3
ccan/tdb2/tdb1_io.c

@@ -82,7 +82,7 @@ static int tdb1_write(struct tdb1_context *tdb, tdb1_off_t off,
 		return 0;
 	}
 
-	if (tdb->read_only || tdb->traverse_read) {
+	if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) {
 		tdb->last_error = TDB_ERR_RDONLY;
 		return -1;
 	}
@@ -213,8 +213,14 @@ void tdb1_mmap(struct tdb1_context *tdb)
 
 #if HAVE_MMAP
 	if (!(tdb->flags & TDB_NOMMAP)) {
+		int mmap_flags;
+		if ((tdb->open_flags & O_ACCMODE) == O_RDONLY)
+			mmap_flags = PROT_READ;
+		else
+			mmap_flags = PROT_READ | PROT_WRITE;
+
 		tdb->file->map_ptr = mmap(NULL, tdb->file->map_size,
-				    PROT_READ|(tdb->read_only? 0:PROT_WRITE),
+				    mmap_flags,
 				    MAP_SHARED|MAP_FILE, tdb->file->fd, 0);
 
 		/*
@@ -241,7 +247,7 @@ static int tdb1_expand_file(struct tdb1_context *tdb, tdb1_off_t size, tdb1_off_
 {
 	char buf[8192];
 
-	if (tdb->read_only || tdb->traverse_read) {
+	if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) {
 		tdb->last_error = TDB_ERR_RDONLY;
 		return -1;
 	}

+ 2 - 2
ccan/tdb2/tdb1_lock.c

@@ -329,8 +329,8 @@ int tdb1_allrecord_lock(struct tdb1_context *tdb, int ltype,
 /* unlock entire db */
 int tdb1_allrecord_unlock(struct tdb1_context *tdb, int ltype)
 {
-	/* There are no locks on read-only dbs */
-	if (tdb->read_only || tdb->traverse_read) {
+	/* Don't try this during r/o traversal! */
+	if (tdb->traverse_read) {
 		tdb->last_error = TDB_ERR_LOCK;
 		return -1;
 	}

+ 1 - 1
ccan/tdb2/tdb1_open.c

@@ -250,7 +250,7 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag
 	if (hash_size == 0)
 		hash_size = TDB1_DEFAULT_HASH_SIZE;
 	if ((open_flags & O_ACCMODE) == O_RDONLY) {
-		tdb->read_only = 1;
+		tdb->flags |= TDB_RDONLY;
 		/* read only databases don't do locking */
 		tdb->flags |= TDB_NOLOCK;
 	}

+ 0 - 1
ccan/tdb2/tdb1_private.h

@@ -217,7 +217,6 @@ struct tdb1_context {
 	void *hash_data;
 	uint64_t hash_seed;
 
-	bool read_only; /* opened read-only */
 	int traverse_read; /* read-only traversal */
 	int traverse_write; /* read-write traversal */
 	struct tdb1_header header; /* a cached copy of the header */

+ 2 - 3
ccan/tdb2/tdb1_summary.c

@@ -94,9 +94,8 @@ char *tdb1_summary(struct tdb1_context *tdb)
 	size_t len, unc = 0;
 	struct tdb1_record recovery;
 
-	/* Read-only databases use no locking at all: it's best-effort.
-	 * We may have a write lock already, so skip that case too. */
-	if (tdb->read_only || tdb->file->allrecord_lock.count != 0) {
+	/* We may have a write lock already, so don't lock. */
+	if (tdb->file->allrecord_lock.count != 0) {
 		locked = false;
 	} else {
 		if (tdb1_lockall_read(tdb) == -1)

+ 2 - 2
ccan/tdb2/tdb1_tdb.c

@@ -283,7 +283,7 @@ int tdb1_do_delete(struct tdb1_context *tdb, tdb1_off_t rec_ptr, struct tdb1_rec
 	tdb1_off_t last_ptr, i;
 	struct tdb1_record lastrec;
 
-	if (tdb->read_only || tdb->traverse_read) return -1;
+	if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) return -1;
 
 	if (((tdb->traverse_write != 0) && (!TDB1_DEAD(rec))) ||
 	    tdb1_write_lock_record(tdb, rec_ptr) == -1) {
@@ -601,7 +601,7 @@ int tdb1_store(struct tdb1_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
 	uint32_t hash;
 	int ret;
 
-	if (tdb->read_only || tdb->traverse_read) {
+	if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) {
 		tdb->last_error = TDB_ERR_RDONLY;
 		return -1;
 	}

+ 2 - 2
ccan/tdb2/tdb1_transaction.c

@@ -418,7 +418,7 @@ static const struct tdb1_methods transaction1_methods = {
 static int _tdb1_transaction_start(struct tdb1_context *tdb)
 {
 	/* some sanity checks */
-	if (tdb->read_only || (tdb->flags & TDB_INTERNAL) || tdb->traverse_read) {
+	if ((tdb->flags & TDB_RDONLY) || (tdb->flags & TDB_INTERNAL) || tdb->traverse_read) {
 		tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL, TDB_LOG_USE_ERROR,
 					"tdb1_transaction_start: cannot start a"
 					" transaction on a read-only or"
@@ -1198,7 +1198,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb)
 		return 0;
 	}
 
-	if (tdb->read_only) {
+	if (tdb->flags & TDB_RDONLY) {
 		tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
 					"tdb1_transaction_recover:"
 					" attempt to recover read only"

+ 2 - 2
ccan/tdb2/tdb1_traverse.c

@@ -119,7 +119,7 @@ static tdb1_off_t tdb1_next_lock(struct tdb1_context *tdb, struct tdb1_traverse_
 			/* Try to clean dead ones from old traverses */
 			current = tlock->off;
 			tlock->off = rec->next;
-			if (!(tdb->read_only || tdb->traverse_read) &&
+			if (!((tdb->flags & TDB_RDONLY) || tdb->traverse_read) &&
 			    tdb1_do_delete(tdb, current, rec) != 0)
 				goto fail;
 		}
@@ -249,7 +249,7 @@ int tdb1_traverse(struct tdb1_context *tdb,
 	struct tdb1_traverse_lock tl = { NULL, 0, 0, F_WRLCK };
 	int ret;
 
-	if (tdb->read_only || tdb->traverse_read) {
+	if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) {
 		return tdb1_traverse_read(tdb, fn, private_data);
 	}
 

+ 1 - 1
ccan/tdb2/test/run-tdb1-3G-file.c

@@ -10,7 +10,7 @@ static int tdb1_expand_file_sparse(struct tdb1_context *tdb,
 				  tdb1_off_t size,
 				  tdb1_off_t addition)
 {
-	if (tdb->read_only || tdb->traverse_read) {
+	if ((tdb->flags & TDB_RDONLY) || tdb->traverse_read) {
 		tdb->last_error = TDB_ERR_RDONLY;
 		return -1;
 	}