X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Fio.c;h=8c5f45f30827c9e722227e3787797288713e056e;hp=7e5dcb73160f4a441e6e978349e04c2bca5cbaa4;hb=18fe5ef012a96014b9e61e48616e682b4a5708a2;hpb=41e027e11e0b15100e50c14e49aaa4c2b418f431 diff --git a/ccan/tdb2/io.c b/ccan/tdb2/io.c index 7e5dcb73..8c5f45f3 100644 --- a/ccan/tdb2/io.c +++ b/ccan/tdb2/io.c @@ -48,8 +48,13 @@ void tdb_mmap(struct tdb_context *tdb) if (tdb->flags & TDB_NOMMAP) return; - tdb->file->map_ptr = mmap(NULL, tdb->file->map_size, tdb->mmap_flags, - MAP_SHARED, tdb->file->fd, 0); + /* size_t can be smaller than off_t. */ + if ((size_t)tdb->file->map_size == tdb->file->map_size) { + tdb->file->map_ptr = mmap(NULL, tdb->file->map_size, + tdb->mmap_flags, + MAP_SHARED, tdb->file->fd, 0); + } else + tdb->file->map_ptr = MAP_FAILED; /* * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! @@ -125,6 +130,7 @@ static enum TDB_ERROR tdb_oob(struct tdb_context *tdb, tdb_off_t len, /* Endian conversion: we only ever deal with 8 byte quantities */ void *tdb_convert(const struct tdb_context *tdb, void *buf, tdb_len_t size) { + assert(size % 8 == 0); if (unlikely((tdb->flags & TDB_CONVERT)) && buf) { uint64_t i, *p = (uint64_t *)buf; for (i = 0; i < size / 8; i++) @@ -342,7 +348,7 @@ enum TDB_ERROR tdb_write_off(struct tdb_context *tdb, static void *_tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len, unsigned int prefix) { - void *buf; + unsigned char *buf; enum TDB_ERROR ecode; /* some systems don't like zero length malloc */ @@ -439,7 +445,7 @@ static enum TDB_ERROR tdb_expand_file(struct tdb_context *tdb, const void *tdb_access_read(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, bool convert) { - const void *ret = NULL; + void *ret = NULL; if (likely(!(tdb->flags & TDB_CONVERT))) { ret = tdb->methods->direct(tdb, off, len, false); @@ -563,10 +569,33 @@ static void *tdb_direct(struct tdb_context *tdb, tdb_off_t off, size_t len, return (char *)tdb->file->map_ptr + off; } -void add_stat_(struct tdb_context *tdb, uint64_t *s, size_t val) +void tdb_inc_seqnum(struct tdb_context *tdb) { - if ((uintptr_t)s < (uintptr_t)tdb->stats + tdb->stats->size) - *s += val; + tdb_off_t seq; + + if (likely(!(tdb->flags & TDB_CONVERT))) { + int64_t *direct; + + direct = tdb->methods->direct(tdb, + offsetof(struct tdb_header, + seqnum), + sizeof(*direct), true); + if (likely(direct)) { + /* Don't let it go negative, even briefly */ + if (unlikely((*direct) + 1) < 0) + *direct = 0; + (*direct)++; + return; + } + } + + seq = tdb_read_off(tdb, offsetof(struct tdb_header, seqnum)); + if (!TDB_OFF_IS_ERR(seq)) { + seq++; + if (unlikely((int64_t)seq < 0)) + seq = 0; + tdb_write_off(tdb, offsetof(struct tdb_header, seqnum), seq); + } } static const struct tdb_methods io_methods = {