]> git.ozlabs.org Git - ccan/blobdiff - ccan/tdb2/io.c
tdb2: fix msync() arg
[ccan] / ccan / tdb2 / io.c
index 7e5dcb73160f4a441e6e978349e04c2bca5cbaa4..8c5f45f30827c9e722227e3787797288713e056e 100644 (file)
@@ -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 = {