From 60210a73ec08a7b34ba637ad19e6749cf6dc1952 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 31 Aug 2011 15:23:16 +0930 Subject: [PATCH] tdb2: Make tdb1 use the tdb_file structure. Because tdb2 allows multiple opens of the same TDB, we separate out the file information from the struct tdb_context. Do the same for tdb1. --- ccan/tdb2/private.h | 5 +- ccan/tdb2/tdb1_check.c | 18 +-- ccan/tdb2/tdb1_io.c | 93 +++++++------ ccan/tdb2/tdb1_lock.c | 130 +++++++++--------- ccan/tdb2/tdb1_open.c | 65 +++++---- ccan/tdb2/tdb1_private.h | 17 +-- ccan/tdb2/tdb1_summary.c | 20 +-- ccan/tdb2/tdb1_tdb.c | 6 +- ccan/tdb2/tdb1_transaction.c | 36 ++--- ccan/tdb2/test/run-tdb1-3G-file.c | 6 +- ccan/tdb2/test/run-tdb1-corrupt.c | 10 +- .../test/run-tdb1-die-during-transaction.c | 2 +- 12 files changed, 206 insertions(+), 202 deletions(-) diff --git a/ccan/tdb2/private.h b/ccan/tdb2/private.h index f6ed65a9..89e69610 100644 --- a/ccan/tdb2/private.h +++ b/ccan/tdb2/private.h @@ -339,6 +339,9 @@ struct tdb_context { /* Last error we returned. */ enum TDB_ERROR last_error; + /* The actual file information */ + struct tdb_file *file; + /* Open flags passed to tdb_open. */ int open_flags; @@ -378,8 +381,6 @@ struct tdb_context { /* Direct access information */ struct tdb_access_hdr *access; - /* The actual file information */ - struct tdb_file *file; }; struct tdb_methods { diff --git a/ccan/tdb2/tdb1_check.c b/ccan/tdb2/tdb1_check.c index 74b3a02d..51b8b594 100644 --- a/ccan/tdb2/tdb1_check.c +++ b/ccan/tdb2/tdb1_check.c @@ -139,8 +139,8 @@ static TDB_DATA get_bytes(struct tdb1_context *tdb, d.dsize = len; - if (tdb->transaction == NULL && tdb->map_ptr != NULL) - d.dptr = (unsigned char *)tdb->map_ptr + off; + if (tdb->transaction == NULL && tdb->file->map_ptr != NULL) + d.dptr = (unsigned char *)tdb->file->map_ptr + off; else d.dptr = tdb1_alloc_read(tdb, off, d.dsize); return d; @@ -149,7 +149,7 @@ static TDB_DATA get_bytes(struct tdb1_context *tdb, /* Frees data if we're not able to simply use mmap. */ static void put_bytes(struct tdb1_context *tdb, TDB_DATA d) { - if (tdb->transaction == NULL && tdb->map_ptr != NULL) + if (tdb->transaction == NULL && tdb->file->map_ptr != NULL) return; free(d.dptr); } @@ -312,7 +312,7 @@ size_t tdb1_dead_space(struct tdb1_context *tdb, tdb1_off_t off) { size_t len; - for (len = 0; off + len < tdb->map_size; len++) { + for (len = 0; off + len < tdb->file->map_size; len++) { char c; if (tdb->methods->tdb1_read(tdb, off, &c, 1, 0)) return 0; @@ -336,7 +336,7 @@ int tdb1_check(struct tdb1_context *tdb, /* 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->allrecord_lock.count != 0) { + if (tdb->read_only || tdb->file->allrecord_lock.count != 0) { locked = false; } else { if (tdb1_lockall_read(tdb) == -1) @@ -345,14 +345,14 @@ int tdb1_check(struct tdb1_context *tdb, } /* Make sure we know true size of the underlying file. */ - tdb->methods->tdb1_oob(tdb, tdb->map_size + 1, 1); + tdb->methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1); /* Header must be OK: also gets us the recovery ptr, if any. */ if (!tdb1_check_header(tdb, &recovery_start)) goto unlock; /* We should have the whole header, too. */ - if (tdb->map_size < TDB1_DATA_START(tdb->header.hash_size)) { + if (tdb->file->map_size < TDB1_DATA_START(tdb->header.hash_size)) { tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, "File too short for hashes\n"); goto unlock; @@ -383,7 +383,7 @@ int tdb1_check(struct tdb1_context *tdb, /* For each record, read it in and check it's ok. */ for (off = TDB1_DATA_START(tdb->header.hash_size); - off < tdb->map_size; + off < tdb->file->map_size; off += sizeof(rec) + rec.rec_len) { if (tdb->methods->tdb1_read(tdb, off, &rec, sizeof(rec), TDB1_DOCONV()) == -1) @@ -412,7 +412,7 @@ int tdb1_check(struct tdb1_context *tdb, tdb_logerr(tdb, TDB_SUCCESS, TDB_LOG_WARNING, "Dead space at %d-%d (of %u)\n", - off, off + dead, tdb->map_size); + off, off + dead, tdb->file->map_size); rec.rec_len = dead - sizeof(rec); break; case TDB1_RECOVERY_MAGIC: diff --git a/ccan/tdb2/tdb1_io.c b/ccan/tdb2/tdb1_io.c index d5684dc7..f61db51e 100644 --- a/ccan/tdb2/tdb1_io.c +++ b/ccan/tdb2/tdb1_io.c @@ -39,18 +39,18 @@ static int tdb1_oob(struct tdb1_context *tdb, tdb1_off_t len, int probe) { struct stat st; - if (len <= tdb->map_size) + if (len <= tdb->file->map_size) return 0; if (tdb->flags & TDB_INTERNAL) { if (!probe) { tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, "tdb1_oob len %d beyond internal malloc size %d", - (int)len, (int)tdb->map_size); + (int)len, (int)tdb->file->map_size); } return -1; } - if (fstat(tdb->fd, &st) == -1) { + if (fstat(tdb->file->fd, &st) == -1) { tdb->last_error = TDB_ERR_IO; return -1; } @@ -69,7 +69,7 @@ static int tdb1_oob(struct tdb1_context *tdb, tdb1_off_t len, int probe) tdb->last_error = TDB_ERR_IO; return -1; } - tdb->map_size = st.st_size; + tdb->file->map_size = st.st_size; tdb1_mmap(tdb); return 0; } @@ -90,16 +90,17 @@ static int tdb1_write(struct tdb1_context *tdb, tdb1_off_t off, if (tdb->methods->tdb1_oob(tdb, off + len, 0) != 0) return -1; - if (tdb->map_ptr) { - memcpy(off + (char *)tdb->map_ptr, buf, len); + if (tdb->file->map_ptr) { + memcpy(off + (char *)tdb->file->map_ptr, buf, len); } else { - ssize_t written = pwrite(tdb->fd, buf, len, off); + ssize_t written = pwrite(tdb->file->fd, buf, len, off); if ((written != (ssize_t)len) && (written != -1)) { tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_WARNING, "tdb1_write: wrote only " "%d of %d bytes at %d, trying once more", (int)written, len, off); - written = pwrite(tdb->fd, (const char *)buf+written, + written = pwrite(tdb->file->fd, + (const char *)buf+written, len-written, off+written); } @@ -139,10 +140,10 @@ static int tdb1_read(struct tdb1_context *tdb, tdb1_off_t off, void *buf, return -1; } - if (tdb->map_ptr) { - memcpy(buf, off + (char *)tdb->map_ptr, len); + if (tdb->file->map_ptr) { + memcpy(buf, off + (char *)tdb->file->map_ptr, len); } else { - ssize_t ret = pread(tdb->fd, buf, len, off); + ssize_t ret = pread(tdb->file->fd, buf, len, off); if (ret != (ssize_t)len) { /* Ensure ecode is set for log fn. */ tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, @@ -150,7 +151,7 @@ static int tdb1_read(struct tdb1_context *tdb, tdb1_off_t off, void *buf, "len=%d ret=%d (%s) map_size=%d", (int)off, (int)len, (int)ret, strerror(errno), - (int)tdb->map_size); + (int)tdb->file->map_size); return -1; } } @@ -169,9 +170,9 @@ static int tdb1_read(struct tdb1_context *tdb, tdb1_off_t off, void *buf, static void tdb1_next_hash_chain(struct tdb1_context *tdb, uint32_t *chain) { uint32_t h = *chain; - if (tdb->map_ptr) { + if (tdb->file->map_ptr) { for (;h < tdb->header.hash_size;h++) { - if (0 != *(uint32_t *)(TDB1_HASH_TOP(h) + (unsigned char *)tdb->map_ptr)) { + if (0 != *(uint32_t *)(TDB1_HASH_TOP(h) + (unsigned char *)tdb->file->map_ptr)) { break; } } @@ -193,15 +194,15 @@ int tdb1_munmap(struct tdb1_context *tdb) return 0; #if HAVE_MMAP - if (tdb->map_ptr) { + if (tdb->file->map_ptr) { int ret; - ret = munmap(tdb->map_ptr, tdb->map_size); + ret = munmap(tdb->file->map_ptr, tdb->file->map_size); if (ret != 0) return ret; } #endif - tdb->map_ptr = NULL; + tdb->file->map_ptr = NULL; return 0; } @@ -212,25 +213,25 @@ void tdb1_mmap(struct tdb1_context *tdb) #if HAVE_MMAP if (!(tdb->flags & TDB_NOMMAP)) { - tdb->map_ptr = mmap(NULL, tdb->map_size, + tdb->file->map_ptr = mmap(NULL, tdb->file->map_size, PROT_READ|(tdb->read_only? 0:PROT_WRITE), - MAP_SHARED|MAP_FILE, tdb->fd, 0); + MAP_SHARED|MAP_FILE, tdb->file->fd, 0); /* * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! */ - if (tdb->map_ptr == MAP_FAILED) { - tdb->map_ptr = NULL; + if (tdb->file->map_ptr == MAP_FAILED) { + tdb->file->map_ptr = NULL; tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_WARNING, "tdb1_mmap failed for size %d (%s)", - tdb->map_size, strerror(errno)); + tdb->file->map_size, strerror(errno)); } } else { - tdb->map_ptr = NULL; + tdb->file->map_ptr = NULL; } #else - tdb->map_ptr = NULL; + tdb->file->map_ptr = NULL; #endif } @@ -245,12 +246,14 @@ static int tdb1_expand_file(struct tdb1_context *tdb, tdb1_off_t size, tdb1_off_ return -1; } - if (ftruncate(tdb->fd, size+addition) == -1) { + if (ftruncate(tdb->file->fd, size+addition) == -1) { char b = 0; - ssize_t written = pwrite(tdb->fd, &b, 1, (size+addition) - 1); + ssize_t written = pwrite(tdb->file->fd, &b, 1, + (size+addition) - 1); if (written == 0) { /* try once more, potentially revealing errno */ - written = pwrite(tdb->fd, &b, 1, (size+addition) - 1); + written = pwrite(tdb->file->fd, &b, 1, + (size+addition) - 1); } if (written == 0) { /* again - give up, guessing errno */ @@ -271,10 +274,10 @@ static int tdb1_expand_file(struct tdb1_context *tdb, tdb1_off_t size, tdb1_off_ memset(buf, TDB1_PAD_BYTE, sizeof(buf)); while (addition) { size_t n = addition>sizeof(buf)?sizeof(buf):addition; - ssize_t written = pwrite(tdb->fd, buf, n, size); + ssize_t written = pwrite(tdb->file->fd, buf, n, size); if (written == 0) { /* prevent infinite loops: try _once_ more */ - written = pwrite(tdb->fd, buf, n, size); + written = pwrite(tdb->file->fd, buf, n, size); } if (written == 0) { /* give up, trying to provide a useful errno */ @@ -316,28 +319,28 @@ int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size) } /* must know about any previous expansions by another process */ - tdb->methods->tdb1_oob(tdb, tdb->map_size + 1, 1); + tdb->methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1); /* limit size in order to avoid using up huge amounts of memory for * in memory tdbs if an oddball huge record creeps in */ if (size > 100 * 1024) { - top_size = tdb->map_size + size * 2; + top_size = tdb->file->map_size + size * 2; } else { - top_size = tdb->map_size + size * 100; + top_size = tdb->file->map_size + size * 100; } /* always make room for at least top_size more records, and at least 25% more space. if the DB is smaller than 100MiB, otherwise grow it by 10% only. */ - if (tdb->map_size > 100 * 1024 * 1024) { - map_size = tdb->map_size * 1.10; + if (tdb->file->map_size > 100 * 1024 * 1024) { + map_size = tdb->file->map_size * 1.10; } else { - map_size = tdb->map_size * 1.25; + map_size = tdb->file->map_size * 1.25; } /* Round the database up to a multiple of the page size */ new_size = MAX(top_size, map_size); - size = TDB1_ALIGN(new_size, tdb->page_size) - tdb->map_size; + size = TDB1_ALIGN(new_size, tdb->page_size) - tdb->file->map_size; if (!(tdb->flags & TDB_INTERNAL)) tdb1_munmap(tdb); @@ -350,20 +353,20 @@ int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size) /* expand the file itself */ if (!(tdb->flags & TDB_INTERNAL)) { - if (tdb->methods->tdb1_expand_file(tdb, tdb->map_size, size) != 0) + if (tdb->methods->tdb1_expand_file(tdb, tdb->file->map_size, size) != 0) goto fail; } - tdb->map_size += size; + tdb->file->map_size += size; if (tdb->flags & TDB_INTERNAL) { - char *new_map_ptr = (char *)realloc(tdb->map_ptr, - tdb->map_size); + char *new_map_ptr = (char *)realloc(tdb->file->map_ptr, + tdb->file->map_size); if (!new_map_ptr) { - tdb->map_size -= size; + tdb->file->map_size -= size; goto fail; } - tdb->map_ptr = new_map_ptr; + tdb->file->map_ptr = new_map_ptr; } else { /* * We must ensure the file is remapped before adding the space @@ -380,7 +383,7 @@ int tdb1_expand(struct tdb1_context *tdb, tdb1_off_t size) rec.rec_len = size - sizeof(rec); /* link it into the free list */ - offset = tdb->map_size - size; + offset = tdb->file->map_size - size; if (tdb1_free(tdb, offset, &rec) == -1) goto fail; @@ -438,7 +441,7 @@ int tdb1_parse_data(struct tdb1_context *tdb, TDB_DATA key, data.dsize = len; - if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) { + if ((tdb->transaction == NULL) && (tdb->file->map_ptr != NULL)) { /* * Optimize by avoiding the malloc/memcpy/free, point the * parser directly at the mmap area. @@ -446,7 +449,7 @@ int tdb1_parse_data(struct tdb1_context *tdb, TDB_DATA key, if (tdb->methods->tdb1_oob(tdb, offset+len, 0) != 0) { return -1; } - data.dptr = offset + (unsigned char *)tdb->map_ptr; + data.dptr = offset + (unsigned char *)tdb->file->map_ptr; return parser(key, data, private_data); } diff --git a/ccan/tdb2/tdb1_lock.c b/ccan/tdb2/tdb1_lock.c index 0fba7423..85348df0 100644 --- a/ccan/tdb2/tdb1_lock.c +++ b/ccan/tdb2/tdb1_lock.c @@ -39,9 +39,9 @@ static int fcntl_lock(struct tdb1_context *tdb, fl.l_pid = 0; if (waitflag) - return fcntl(tdb->fd, F_SETLKW, &fl); + return fcntl(tdb->file->fd, F_SETLKW, &fl); else - return fcntl(tdb->fd, F_SETLK, &fl); + return fcntl(tdb->file->fd, F_SETLK, &fl); } static int fcntl_unlock(struct tdb1_context *tdb, int rw, off_t off, off_t len) @@ -111,7 +111,7 @@ static int fcntl_unlock(struct tdb1_context *tdb, int rw, off_t off, off_t len) fl.l_len = len; fl.l_pid = 0; - return fcntl(tdb->fd, F_SETLKW, &fl); + return fcntl(tdb->file->fd, F_SETLKW, &fl); } /* list -1 is the alloc list, otherwise a hash chain. */ @@ -156,7 +156,7 @@ int tdb1_brlock(struct tdb1_context *tdb, if (!(flags & TDB_LOCK_PROBE) && errno != EAGAIN) { tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR, "tdb1_brlock failed (fd=%d) at offset %d rw_type=%d flags=%d len=%d", - tdb->fd, offset, rw_type, flags, (int)len); + tdb->file->fd, offset, rw_type, flags, (int)len); } return -1; } @@ -180,7 +180,7 @@ int tdb1_brunlock(struct tdb1_context *tdb, tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR, "tdb1_brunlock failed (fd=%d) at offset" " %d rw_type=%d len=%d", - tdb->fd, offset, rw_type, (int)len); + tdb->file->fd, offset, rw_type, (int)len); } return ret; } @@ -195,15 +195,15 @@ int tdb1_allrecord_upgrade(struct tdb1_context *tdb) { int count = 1000; - if (tdb->allrecord_lock.count != 1) { + if (tdb->file->allrecord_lock.count != 1) { tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR, "tdb1_allrecord_upgrade failed: " "count %u too high", - tdb->allrecord_lock.count); + tdb->file->allrecord_lock.count); return -1; } - if (tdb->allrecord_lock.off != 1) { + if (tdb->file->allrecord_lock.off != 1) { tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR, "tdb1_allrecord_upgrade failed:" " already upgraded?"); @@ -214,8 +214,8 @@ int tdb1_allrecord_upgrade(struct tdb1_context *tdb) struct timeval tv; if (tdb1_brlock(tdb, F_WRLCK, TDB1_FREELIST_TOP, 0, TDB_LOCK_WAIT|TDB_LOCK_PROBE) == 0) { - tdb->allrecord_lock.ltype = F_WRLCK; - tdb->allrecord_lock.off = 0; + tdb->file->allrecord_lock.ltype = F_WRLCK; + tdb->file->allrecord_lock.off = 0; return 0; } if (errno != EDEADLK) { @@ -231,14 +231,14 @@ int tdb1_allrecord_upgrade(struct tdb1_context *tdb) return -1; } -static struct tdb1_lock_type *tdb1_find_nestlock(struct tdb1_context *tdb, - tdb1_off_t offset) +static struct tdb_lock *tdb1_find_nestlock(struct tdb1_context *tdb, + tdb1_off_t offset) { unsigned int i; - for (i=0; inum_lockrecs; i++) { - if (tdb->lockrecs[i].off == offset) { - return &tdb->lockrecs[i]; + for (i=0; ifile->num_lockrecs; i++) { + if (tdb->file->lockrecs[i].off == offset) { + return &tdb->file->lockrecs[i]; } } return NULL; @@ -248,7 +248,7 @@ static struct tdb1_lock_type *tdb1_find_nestlock(struct tdb1_context *tdb, int tdb1_nest_lock(struct tdb1_context *tdb, uint32_t offset, int ltype, enum tdb_lock_flags flags) { - struct tdb1_lock_type *new_lck; + struct tdb_lock *new_lck; if (offset >= lock_offset(tdb->header.hash_size)) { tdb->last_error = tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR, @@ -270,14 +270,14 @@ int tdb1_nest_lock(struct tdb1_context *tdb, uint32_t offset, int ltype, return 0; } - new_lck = (struct tdb1_lock_type *)realloc( - tdb->lockrecs, - sizeof(*tdb->lockrecs) * (tdb->num_lockrecs+1)); + new_lck = (struct tdb_lock *)realloc( + tdb->file->lockrecs, + sizeof(*tdb->file->lockrecs) * (tdb->file->num_lockrecs+1)); if (new_lck == NULL) { errno = ENOMEM; return -1; } - tdb->lockrecs = new_lck; + tdb->file->lockrecs = new_lck; /* Since fcntl locks don't nest, we do a lock for the first one, and simply bump the count for future ones */ @@ -285,10 +285,10 @@ int tdb1_nest_lock(struct tdb1_context *tdb, uint32_t offset, int ltype, return -1; } - tdb->lockrecs[tdb->num_lockrecs].off = offset; - tdb->lockrecs[tdb->num_lockrecs].count = 1; - tdb->lockrecs[tdb->num_lockrecs].ltype = ltype; - tdb->num_lockrecs++; + tdb->file->lockrecs[tdb->file->num_lockrecs].off = offset; + tdb->file->lockrecs[tdb->file->num_lockrecs].count = 1; + tdb->file->lockrecs[tdb->file->num_lockrecs].ltype = ltype; + tdb->file->num_lockrecs++; return 0; } @@ -319,8 +319,8 @@ static bool have_data_locks(const struct tdb1_context *tdb) { unsigned int i; - for (i = 0; i < tdb->num_lockrecs; i++) { - if (tdb->lockrecs[i].off >= lock_offset(-1)) + for (i = 0; i < tdb->file->num_lockrecs; i++) { + if (tdb->file->lockrecs[i].off >= lock_offset(-1)) return true; } return false; @@ -333,12 +333,12 @@ static int tdb1_lock_list(struct tdb1_context *tdb, int list, int ltype, bool check = false; /* a allrecord lock allows us to avoid per chain locks */ - if (tdb->allrecord_lock.count && - (ltype == tdb->allrecord_lock.ltype || ltype == F_RDLCK)) { + if (tdb->file->allrecord_lock.count && + (ltype == tdb->file->allrecord_lock.ltype || ltype == F_RDLCK)) { return 0; } - if (tdb->allrecord_lock.count) { + if (tdb->file->allrecord_lock.count) { tdb->last_error = TDB_ERR_LOCK; ret = -1; } else { @@ -375,7 +375,7 @@ int tdb1_lock(struct tdb1_context *tdb, int list, int ltype) int tdb1_nest_unlock(struct tdb1_context *tdb, uint32_t offset, int ltype) { int ret = -1; - struct tdb1_lock_type *lck; + struct tdb_lock *lck; if (tdb->flags & TDB_NOLOCK) return 0; @@ -413,15 +413,15 @@ int tdb1_nest_unlock(struct tdb1_context *tdb, uint32_t offset, int ltype) * Shrink the array by overwriting the element just unlocked with the * last array element. */ - *lck = tdb->lockrecs[--tdb->num_lockrecs]; + *lck = tdb->file->lockrecs[--tdb->file->num_lockrecs]; /* * We don't bother with realloc when the array shrinks, but if we have * a completely idle tdb we should get rid of the locked array. */ - if (tdb->num_lockrecs == 0) { - SAFE_FREE(tdb->lockrecs); + if (tdb->file->num_lockrecs == 0) { + SAFE_FREE(tdb->file->lockrecs); } return ret; @@ -430,12 +430,12 @@ int tdb1_nest_unlock(struct tdb1_context *tdb, uint32_t offset, int ltype) int tdb1_unlock(struct tdb1_context *tdb, int list, int ltype) { /* a global lock allows us to avoid per chain locks */ - if (tdb->allrecord_lock.count && - (ltype == tdb->allrecord_lock.ltype || ltype == F_RDLCK)) { + if (tdb->file->allrecord_lock.count && + (ltype == tdb->file->allrecord_lock.ltype || ltype == F_RDLCK)) { return 0; } - if (tdb->allrecord_lock.count) { + if (tdb->file->allrecord_lock.count) { tdb->last_error = TDB_ERR_LOCK; return -1; } @@ -470,12 +470,12 @@ static int tdb1_allrecord_check(struct tdb1_context *tdb, int ltype, return -1; } - if (tdb->allrecord_lock.count && tdb->allrecord_lock.ltype == ltype) { - tdb->allrecord_lock.count++; + if (tdb->file->allrecord_lock.count && tdb->file->allrecord_lock.ltype == ltype) { + tdb->file->allrecord_lock.count++; return 0; } - if (tdb->allrecord_lock.count) { + if (tdb->file->allrecord_lock.count) { /* a global lock of a different type exists */ tdb->last_error = TDB_ERR_LOCK; return -1; @@ -562,11 +562,11 @@ int tdb1_allrecord_lock(struct tdb1_context *tdb, int ltype, return -1; } - tdb->allrecord_lock.count = 1; + tdb->file->allrecord_lock.count = 1; /* If it's upgradable, it's actually exclusive so we can treat * it as a write lock. */ - tdb->allrecord_lock.ltype = upgradable ? F_WRLCK : ltype; - tdb->allrecord_lock.off = upgradable; + tdb->file->allrecord_lock.ltype = upgradable ? F_WRLCK : ltype; + tdb->file->allrecord_lock.off = upgradable; if (tdb1_needs_recovery(tdb)) { tdb1_allrecord_unlock(tdb, ltype); @@ -590,20 +590,20 @@ int tdb1_allrecord_unlock(struct tdb1_context *tdb, int ltype) return -1; } - if (tdb->allrecord_lock.count == 0) { + if (tdb->file->allrecord_lock.count == 0) { tdb->last_error = TDB_ERR_LOCK; return -1; } /* Upgradable locks are marked as write locks. */ - if (tdb->allrecord_lock.ltype != ltype - && (!tdb->allrecord_lock.off || ltype != F_RDLCK)) { + if (tdb->file->allrecord_lock.ltype != ltype + && (!tdb->file->allrecord_lock.off || ltype != F_RDLCK)) { tdb->last_error = TDB_ERR_LOCK; return -1; } - if (tdb->allrecord_lock.count > 1) { - tdb->allrecord_lock.count--; + if (tdb->file->allrecord_lock.count > 1) { + tdb->file->allrecord_lock.count--; return 0; } @@ -613,8 +613,8 @@ int tdb1_allrecord_unlock(struct tdb1_context *tdb, int ltype) return -1; } - tdb->allrecord_lock.count = 0; - tdb->allrecord_lock.ltype = 0; + tdb->file->allrecord_lock.count = 0; + tdb->file->allrecord_lock.ltype = 0; return 0; } @@ -671,7 +671,7 @@ int tdb1_chainunlock_read(struct tdb1_context *tdb, TDB_DATA key) /* record lock stops delete underneath */ int tdb1_lock_record(struct tdb1_context *tdb, tdb1_off_t off) { - if (tdb->allrecord_lock.count) { + if (tdb->file->allrecord_lock.count) { return 0; } return off ? tdb1_brlock(tdb, F_RDLCK, off, 1, TDB_LOCK_WAIT) : 0; @@ -688,8 +688,8 @@ int tdb1_write_lock_record(struct tdb1_context *tdb, tdb1_off_t off) for (i = &tdb->travlocks; i; i = i->next) if (i->off == off) return -1; - if (tdb->allrecord_lock.count) { - if (tdb->allrecord_lock.ltype == F_WRLCK) { + if (tdb->file->allrecord_lock.count) { + if (tdb->file->allrecord_lock.ltype == F_WRLCK) { return 0; } return -1; @@ -699,7 +699,7 @@ int tdb1_write_lock_record(struct tdb1_context *tdb, tdb1_off_t off) int tdb1_write_unlock_record(struct tdb1_context *tdb, tdb1_off_t off) { - if (tdb->allrecord_lock.count) { + if (tdb->file->allrecord_lock.count) { return 0; } return tdb1_brunlock(tdb, F_WRLCK, off, 1); @@ -711,7 +711,7 @@ int tdb1_unlock_record(struct tdb1_context *tdb, tdb1_off_t off) struct tdb1_traverse_lock *i; uint32_t count = 0; - if (tdb->allrecord_lock.count) { + if (tdb->file->allrecord_lock.count) { return 0; } @@ -725,10 +725,10 @@ int tdb1_unlock_record(struct tdb1_context *tdb, tdb1_off_t off) bool tdb1_have_extra_locks(struct tdb1_context *tdb) { - unsigned int extra = tdb->num_lockrecs; + unsigned int extra = tdb->file->num_lockrecs; /* A transaction holds the lock for all records. */ - if (!tdb->transaction && tdb->allrecord_lock.count) { + if (!tdb->transaction && tdb->file->allrecord_lock.count) { return true; } @@ -751,23 +751,23 @@ void tdb1_release_transaction_locks(struct tdb1_context *tdb) { unsigned int i, active = 0; - if (tdb->allrecord_lock.count != 0) { - tdb1_brunlock(tdb, tdb->allrecord_lock.ltype, TDB1_FREELIST_TOP, 0); - tdb->allrecord_lock.count = 0; + if (tdb->file->allrecord_lock.count != 0) { + tdb1_brunlock(tdb, tdb->file->allrecord_lock.ltype, TDB1_FREELIST_TOP, 0); + tdb->file->allrecord_lock.count = 0; } - for (i=0;inum_lockrecs;i++) { - struct tdb1_lock_type *lck = &tdb->lockrecs[i]; + for (i=0;ifile->num_lockrecs;i++) { + struct tdb_lock *lck = &tdb->file->lockrecs[i]; /* Don't release the active lock! Copy it to first entry. */ if (lck->off == TDB1_ACTIVE_LOCK) { - tdb->lockrecs[active++] = *lck; + tdb->file->lockrecs[active++] = *lck; } else { tdb1_brunlock(tdb, lck->ltype, lck->off, 1); } } - tdb->num_lockrecs = active; - if (tdb->num_lockrecs == 0) { - SAFE_FREE(tdb->lockrecs); + tdb->file->num_lockrecs = active; + if (tdb->file->num_lockrecs == 0) { + SAFE_FREE(tdb->file->lockrecs); } } diff --git a/ccan/tdb2/tdb1_open.c b/ccan/tdb2/tdb1_open.c index d02a33eb..5c4f62f6 100644 --- a/ccan/tdb2/tdb1_open.c +++ b/ccan/tdb2/tdb1_open.c @@ -76,17 +76,18 @@ static int tdb1_new_database(struct tdb1_context *tdb, int hash_size) newdb->rwlocks = TDB1_HASH_RWLOCK_MAGIC; if (tdb->flags & TDB_INTERNAL) { - tdb->map_size = size; - tdb->map_ptr = (char *)newdb; + tdb->file->fd = -1; + tdb->file->map_size = size; + tdb->file->map_ptr = (char *)newdb; memcpy(&tdb->header, newdb, sizeof(tdb->header)); /* Convert the `ondisk' version if asked. */ TDB1_CONV(*newdb); return 0; } - if (lseek(tdb->fd, 0, SEEK_SET) == -1) + if (lseek(tdb->file->fd, 0, SEEK_SET) == -1) goto fail; - if (ftruncate(tdb->fd, 0) == -1) + if (ftruncate(tdb->file->fd, 0) == -1) goto fail; /* This creates an endian-converted header, as if read from disk */ @@ -95,7 +96,7 @@ static int tdb1_new_database(struct tdb1_context *tdb, int hash_size) /* Don't endian-convert the magic food! */ memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); /* we still have "ret == -1" here */ - if (tdb1_write_all(tdb->fd, newdb, size)) + if (tdb1_write_all(tdb->file->fd, newdb, size)) ret = 0; fail: @@ -111,7 +112,7 @@ static int tdb1_already_open(dev_t device, struct tdb1_context *i; for (i = tdb1s; i; i = i->next) { - if (i->device == device && i->inode == ino) { + if (i->file->device == device && i->file->inode == ino) { return 1; } } @@ -176,10 +177,16 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag errno = ENOMEM; goto fail; } + tdb->file = calloc(1, sizeof *tdb->file); + if (!tdb->file) { + free(tdb); + errno = ENOMEM; + goto fail; + } tdb1_io_init(tdb); - tdb->fd = -1; + tdb->file->fd = -1; tdb->name = NULL; - tdb->map_ptr = NULL; + tdb->file->map_ptr = NULL; tdb->flags = tdb1_flags|TDB_VERSION1; tdb->open_flags = open_flags; if (log_ctx) { @@ -262,7 +269,7 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag goto internal; } - if ((tdb->fd = open(name, open_flags, mode)) == -1) { + if ((tdb->file->fd = open(name, open_flags, mode)) == -1) { tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, "tdb1_open_ex: could not open file %s: %s", name, strerror(errno)); @@ -270,8 +277,8 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag } /* on exec, don't inherit the fd */ - v = fcntl(tdb->fd, F_GETFD, 0); - fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC); + v = fcntl(tdb->file->fd, F_GETFD, 0); + fcntl(tdb->file->fd, F_SETFD, v | FD_CLOEXEC); /* ensure there is only one process initialising at once */ if (tdb1_nest_lock(tdb, TDB1_OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) { @@ -282,7 +289,7 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag } errno = 0; - if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header) + if (read(tdb->file->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header) || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0) { if (!(open_flags & O_CREAT) || tdb1_new_database(tdb, hash_size) == -1) { if (errno == 0) { @@ -303,7 +310,7 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag tdb->flags |= TDB_CONVERT; tdb1_convert(&tdb->header, sizeof(tdb->header)); } - if (fstat(tdb->fd, &st) == -1) + if (fstat(tdb->file->fd, &st) == -1) goto fail; if (tdb->header.rwlocks != 0 && @@ -343,9 +350,9 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag goto fail; } - tdb->map_size = st.st_size; - tdb->device = st.st_dev; - tdb->inode = st.st_ino; + tdb->file->map_size = st.st_size; + tdb->file->device = st.st_dev; + tdb->file->inode = st.st_ino; tdb1_mmap(tdb); /* if needed, run recovery */ @@ -370,17 +377,20 @@ struct tdb1_context *tdb1_open_ex(const char *name, int hash_size, int tdb1_flag if (!tdb) return NULL; - if (tdb->map_ptr) { + if (tdb->file->map_ptr) { if (tdb->flags & TDB_INTERNAL) - SAFE_FREE(tdb->map_ptr); + SAFE_FREE(tdb->file->map_ptr); else tdb1_munmap(tdb); } - if (tdb->fd != -1) - if (close(tdb->fd) != 0) + if (tdb->file->fd != -1) + if (close(tdb->file->fd) != 0) tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, "tdb1_open_ex: failed to close tdb->fd on error!"); - SAFE_FREE(tdb->lockrecs); + if (tdb->file) { + SAFE_FREE(tdb->file->lockrecs); + SAFE_FREE(tdb->file); + } SAFE_FREE(tdb->name); SAFE_FREE(tdb); errno = save_errno; @@ -411,18 +421,19 @@ int tdb1_close(struct tdb1_context *tdb) tdb1_transaction_cancel(tdb); } - if (tdb->map_ptr) { + if (tdb->file->map_ptr) { if (tdb->flags & TDB_INTERNAL) - SAFE_FREE(tdb->map_ptr); + SAFE_FREE(tdb->file->map_ptr); else tdb1_munmap(tdb); } SAFE_FREE(tdb->name); - if (tdb->fd != -1) { - ret = close(tdb->fd); - tdb->fd = -1; + if (tdb->file->fd != -1) { + ret = close(tdb->file->fd); + tdb->file->fd = -1; } - SAFE_FREE(tdb->lockrecs); + SAFE_FREE(tdb->file->lockrecs); + SAFE_FREE(tdb->file); /* Remove from contexts list */ for (i = &tdb1s; *i; i = &(*i)->next) { diff --git a/ccan/tdb2/tdb1_private.h b/ccan/tdb2/tdb1_private.h index 0d40d7a9..5470955a 100644 --- a/ccan/tdb2/tdb1_private.h +++ b/ccan/tdb2/tdb1_private.h @@ -135,12 +135,6 @@ struct tdb1_header { tdb1_off_t reserved[27]; }; -struct tdb1_lock_type { - uint32_t off; - uint32_t count; - uint32_t ltype; -}; - struct tdb1_traverse_lock { struct tdb1_traverse_lock *next; uint32_t off; @@ -174,20 +168,15 @@ struct tdb1_context { /* Last error we returned. */ enum TDB_ERROR last_error; /* error code for last tdb error */ - void *map_ptr; /* where it is currently mapped */ - int fd; /* open file descriptor for the database */ - tdb1_len_t map_size; /* how much space has been mapped */ + /* The actual file information */ + struct tdb_file *file; + int read_only; /* opened read-only */ int traverse_read; /* read-only traversal */ int traverse_write; /* read-write traversal */ - struct tdb1_lock_type allrecord_lock; /* .offset == upgradable */ - int num_lockrecs; - struct tdb1_lock_type *lockrecs; /* only real locks, all with count>0 */ struct tdb1_header header; /* a cached copy of the header */ uint32_t flags; /* the flags passed to tdb1_open */ struct tdb1_traverse_lock travlocks; /* current traversal locks */ - dev_t device; /* uniquely identifies this tdb */ - ino_t inode; /* uniquely identifies this tdb */ unsigned int (*hash_fn)(TDB_DATA *key); int open_flags; /* flags used in the open - needed by reopen */ const struct tdb1_methods *methods; diff --git a/ccan/tdb2/tdb1_summary.c b/ccan/tdb2/tdb1_summary.c index b6889bc4..329cb268 100644 --- a/ccan/tdb2/tdb1_summary.c +++ b/ccan/tdb2/tdb1_summary.c @@ -96,7 +96,7 @@ char *tdb1_summary(struct tdb1_context *tdb) /* 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->allrecord_lock.count != 0) { + if (tdb->read_only || tdb->file->allrecord_lock.count != 0) { locked = false; } else { if (tdb1_lockall_read(tdb) == -1) @@ -117,7 +117,7 @@ char *tdb1_summary(struct tdb1_context *tdb) tally1_init(&uncoal); for (off = TDB1_DATA_START(tdb->header.hash_size); - off < tdb->map_size - 1; + off < tdb->file->map_size - 1; off += sizeof(rec) + rec.rec_len) { if (tdb->methods->tdb1_read(tdb, off, &rec, sizeof(rec), TDB1_DOCONV()) == -1) @@ -171,7 +171,7 @@ char *tdb1_summary(struct tdb1_context *tdb) goto unlock; snprintf(ret, len, SUMMARY_FORMAT1, - tdb->map_size, keys.total+data.total, + (tdb1_len_t)tdb->file->map_size, keys.total+data.total, keys.num, keys.min, tally1_mean(&keys), keys.max, data.min, tally1_mean(&data), data.max, @@ -184,16 +184,16 @@ char *tdb1_summary(struct tdb1_context *tdb) hash.min, tally1_mean(&hash), hash.max, uncoal.total, uncoal.min, tally1_mean(&uncoal), uncoal.max, - keys.total * 100.0 / tdb->map_size, - data.total * 100.0 / tdb->map_size, - extra.total * 100.0 / tdb->map_size, - freet.total * 100.0 / tdb->map_size, - dead.total * 100.0 / tdb->map_size, + keys.total * 100.0 / tdb->file->map_size, + data.total * 100.0 / tdb->file->map_size, + extra.total * 100.0 / tdb->file->map_size, + freet.total * 100.0 / tdb->file->map_size, + dead.total * 100.0 / tdb->file->map_size, (keys.num + freet.num + dead.num) * (sizeof(struct tdb1_record) + sizeof(uint32_t)) - * 100.0 / tdb->map_size, + * 100.0 / tdb->file->map_size, tdb->header.hash_size * sizeof(tdb1_off_t) - * 100.0 / tdb->map_size); + * 100.0 / (tdb1_len_t)tdb->file->map_size); unlock: if (locked) { diff --git a/ccan/tdb2/tdb1_tdb.c b/ccan/tdb2/tdb1_tdb.c index a1a06438..c69c61d0 100644 --- a/ccan/tdb2/tdb1_tdb.c +++ b/ccan/tdb2/tdb1_tdb.c @@ -698,7 +698,7 @@ static int tdb1_free_region(struct tdb1_context *tdb, tdb1_off_t offset, ssize_t /* the region is not worth adding */ return 0; } - if (length + offset > tdb->map_size) { + if (length + offset > tdb->file->map_size) { tdb->last_error = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR, "tdb1_free_region: adding region beyond" " end of file"); @@ -774,7 +774,7 @@ int tdb1_wipe_all(struct tdb1_context *tdb) for the recovery area */ if (recovery_size == 0) { /* the simple case - the whole file can be used as a freelist */ - data_len = (tdb->map_size - TDB1_DATA_START(tdb->header.hash_size)); + data_len = (tdb->file->map_size - TDB1_DATA_START(tdb->header.hash_size)); if (tdb1_free_region(tdb, TDB1_DATA_START(tdb->header.hash_size), data_len) != 0) { goto failed; } @@ -792,7 +792,7 @@ int tdb1_wipe_all(struct tdb1_context *tdb) goto failed; } /* and the 2nd free list entry after the recovery area - if any */ - data_len = tdb->map_size - (recovery_head+recovery_size); + data_len = tdb->file->map_size - (recovery_head+recovery_size); if (tdb1_free_region(tdb, recovery_head+recovery_size, data_len) != 0) { goto failed; } diff --git a/ccan/tdb2/tdb1_transaction.c b/ccan/tdb2/tdb1_transaction.c index d35c4bc4..8d25f96a 100644 --- a/ccan/tdb2/tdb1_transaction.c +++ b/ccan/tdb2/tdb1_transaction.c @@ -378,7 +378,7 @@ static void transaction1_next_hash_chain(struct tdb1_context *tdb, uint32_t *cha */ static int transaction1_oob(struct tdb1_context *tdb, tdb1_off_t len, int probe) { - if (len <= tdb->map_size) { + if (len <= tdb->file->map_size) { return 0; } tdb->last_error = TDB_ERR_IO; @@ -500,8 +500,8 @@ static int _tdb1_transaction_start(struct tdb1_context *tdb) /* make sure we know about any file expansions already done by anyone else */ - tdb->methods->tdb1_oob(tdb, tdb->map_size + 1, 1); - tdb->transaction->old_map_size = tdb->map_size; + tdb->methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1); + tdb->transaction->old_map_size = tdb->file->map_size; /* finally hook the io methods, replacing them with transaction specific methods */ @@ -535,18 +535,18 @@ static int transaction1_sync(struct tdb1_context *tdb, tdb1_off_t offset, tdb1_l } #if HAVE_FDATASYNC - if (fdatasync(tdb->fd) != 0) { + if (fdatasync(tdb->file->fd) != 0) { #else - if (fsync(tdb->fd) != 0) { + if (fsync(tdb->file->fd) != 0) { #endif tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, "tdb1_transaction: fsync failed"); return -1; } #if HAVE_MMAP - if (tdb->map_ptr) { + if (tdb->file->map_ptr) { tdb1_off_t moffset = offset & ~(tdb->page_size-1); - if (msync(moffset + (char *)tdb->map_ptr, + if (msync(moffset + (char *)tdb->file->map_ptr, length + (offset - moffset), MS_SYNC) != 0) { tdb->last_error = tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR, "tdb1_transaction:" @@ -577,7 +577,7 @@ static int _tdb1_transaction_cancel(struct tdb1_context *tdb) return 0; } - tdb->map_size = tdb->transaction->old_map_size; + tdb->file->map_size = tdb->transaction->old_map_size; /* free all the transaction blocks */ for (i=0;itransaction->num_blocks;i++) { @@ -724,11 +724,11 @@ static int tdb1_recovery_allocate(struct tdb1_context *tdb, /* round up to a multiple of page size */ *recovery_max_size = TDB1_ALIGN(sizeof(rec) + *recovery_size, tdb->page_size) - sizeof(rec); - *recovery_offset = tdb->map_size; + *recovery_offset = tdb->file->map_size; recovery_head = *recovery_offset; if (methods->tdb1_expand_file(tdb, tdb->transaction->old_map_size, - (tdb->map_size - tdb->transaction->old_map_size) + + (tdb->file->map_size - tdb->transaction->old_map_size) + sizeof(rec) + *recovery_max_size) == -1) { tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, "tdb1_recovery_allocate:" @@ -737,11 +737,11 @@ static int tdb1_recovery_allocate(struct tdb1_context *tdb, } /* remap the file (if using mmap) */ - methods->tdb1_oob(tdb, tdb->map_size + 1, 1); + methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1); /* we have to reset the old map size so that we don't try to expand the file again in the transaction commit, which would destroy the recovery area */ - tdb->transaction->old_map_size = tdb->map_size; + tdb->transaction->old_map_size = tdb->file->map_size; /* write the recovery header offset and sync - we can sync without a race here as the magic ptr in the recovery record has not been set */ @@ -986,9 +986,9 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb) tdb->transaction->prepared = true; /* expand the file to the new size if needed */ - if (tdb->map_size != tdb->transaction->old_map_size) { + if (tdb->file->map_size != tdb->transaction->old_map_size) { if (methods->tdb1_expand_file(tdb, tdb->transaction->old_map_size, - tdb->map_size - + tdb->file->map_size - tdb->transaction->old_map_size) == -1) { tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, "tdb1_transaction_prepare_commit:" @@ -996,8 +996,8 @@ static int _tdb1_transaction_prepare_commit(struct tdb1_context *tdb) _tdb1_transaction_cancel(tdb); return -1; } - tdb->map_size = tdb->transaction->old_map_size; - methods->tdb1_oob(tdb, tdb->map_size + 1, 1); + tdb->file->map_size = tdb->transaction->old_map_size; + methods->tdb1_oob(tdb, tdb->file->map_size + 1, 1); } /* Keep the open lock until the actual commit */ @@ -1123,7 +1123,7 @@ int tdb1_transaction_commit(struct tdb1_context *tdb) tdb->transaction->num_blocks = 0; /* ensure the new data is on disk */ - if (transaction1_sync(tdb, 0, tdb->map_size) == -1) { + if (transaction1_sync(tdb, 0, tdb->file->map_size) == -1) { return -1; } @@ -1242,7 +1242,7 @@ int tdb1_transaction_recover(struct tdb1_context *tdb) free(data); - if (transaction1_sync(tdb, 0, tdb->map_size) == -1) { + if (transaction1_sync(tdb, 0, tdb->file->map_size) == -1) { tdb_logerr(tdb, tdb->last_error, TDB_LOG_ERROR, "tdb1_transaction_recover: failed to sync recovery"); return -1; diff --git a/ccan/tdb2/test/run-tdb1-3G-file.c b/ccan/tdb2/test/run-tdb1-3G-file.c index 98e3a300..43e9f2ad 100644 --- a/ccan/tdb2/test/run-tdb1-3G-file.c +++ b/ccan/tdb2/test/run-tdb1-3G-file.c @@ -15,12 +15,12 @@ static int tdb1_expand_file_sparse(struct tdb1_context *tdb, return -1; } - if (ftruncate(tdb->fd, size+addition) == -1) { + if (ftruncate(tdb->file->fd, size+addition) == -1) { char b = 0; - ssize_t written = pwrite(tdb->fd, &b, 1, (size+addition) - 1); + ssize_t written = pwrite(tdb->file->fd, &b, 1, (size+addition) - 1); if (written == 0) { /* try once more, potentially revealing errno */ - written = pwrite(tdb->fd, &b, 1, (size+addition) - 1); + written = pwrite(tdb->file->fd, &b, 1, (size+addition) - 1); } if (written == 0) { /* again - give up, guessing errno */ diff --git a/ccan/tdb2/test/run-tdb1-corrupt.c b/ccan/tdb2/test/run-tdb1-corrupt.c index 2a8d31bf..5aa37ec4 100644 --- a/ccan/tdb2/test/run-tdb1-corrupt.c +++ b/ccan/tdb2/test/run-tdb1-corrupt.c @@ -28,14 +28,14 @@ static void tdb1_flip_bit(struct tdb1_context *tdb, unsigned int bit) unsigned int off = bit / CHAR_BIT; unsigned char mask = (1 << (bit % CHAR_BIT)); - if (tdb->map_ptr) - ((unsigned char *)tdb->map_ptr)[off] ^= mask; + if (tdb->file->map_ptr) + ((unsigned char *)tdb->file->map_ptr)[off] ^= mask; else { unsigned char c; - if (pread(tdb->fd, &c, 1, off) != 1) + if (pread(tdb->file->fd, &c, 1, off) != 1) err(1, "pread"); c ^= mask; - if (pwrite(tdb->fd, &c, 1, off) != 1) + if (pwrite(tdb->file->fd, &c, 1, off) != 1) err(1, "pwrite"); } } @@ -78,7 +78,7 @@ static void check_test(struct tdb1_context *tdb) verifiable += ksize + dsize; /* Flip one bit at a time, make sure it detects verifiable bytes. */ - for (i = 0, corrupt = 0; i < tdb->map_size * CHAR_BIT; i++) { + for (i = 0, corrupt = 0; i < tdb->file->map_size * CHAR_BIT; i++) { tdb1_flip_bit(tdb, i); memset(sizes, 0, sizeof(sizes)); if (tdb1_check(tdb, check, sizes) != 0) diff --git a/ccan/tdb2/test/run-tdb1-die-during-transaction.c b/ccan/tdb2/test/run-tdb1-die-during-transaction.c index 592f7573..bcd24df5 100644 --- a/ccan/tdb2/test/run-tdb1-die-during-transaction.c +++ b/ccan/tdb2/test/run-tdb1-die-during-transaction.c @@ -94,7 +94,7 @@ reset: if (setjmp(jmpbuf) != 0) { /* We're partway through. Simulate our death. */ - close(tdb->fd); + close(tdb->file->fd); forget_locking1(); in_transaction = false; -- 2.39.2