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)
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;
}
#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);
/*
{
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;
}
/* 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;
}
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;
}
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 */
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)
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) {
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;
}
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"
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"
/* 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;
}
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);
}
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;
}