lib/tdb2: fix OpenBSD incoherent mmap (tdb2 version)
authorRusty Russell <rusty@rustcorp.com.au>
Thu, 22 Mar 2012 00:17:27 +0000 (10:47 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Thu, 22 Mar 2012 00:57:38 +0000 (01:57 +0100)
This handles incoherent mmaps for TDB2 native databases, by forcing
mmap on for such systems, just like we did for tdb1.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
lib/tdb2/io.c
lib/tdb2/private.h
lib/tdb2/tdb.c

index 5634922db3a7b5498601e5a4f54227b1c3f9652d..e27a9fe832fb29acf36e76e43712b42924f3fa76 100644 (file)
@@ -40,15 +40,17 @@ void tdb_munmap(struct tdb_file *file)
        }
 }
 
-void tdb_mmap(struct tdb_context *tdb)
+enum TDB_ERROR tdb_mmap(struct tdb_context *tdb)
 {
        int mmap_flags;
 
        if (tdb->flags & TDB_INTERNAL)
-               return;
+               return TDB_SUCCESS;
 
+#ifndef HAVE_INCOHERENT_MMAP
        if (tdb->flags & TDB_NOMMAP)
-               return;
+               return TDB_SUCCESS;
+#endif
 
        if ((tdb->open_flags & O_ACCMODE) == O_RDONLY)
                mmap_flags = PROT_READ;
@@ -68,10 +70,19 @@ void tdb_mmap(struct tdb_context *tdb)
         */
        if (tdb->file->map_ptr == MAP_FAILED) {
                tdb->file->map_ptr = NULL;
+#ifdef HAVE_INCOHERENT_MMAP
+               /* Incoherent mmap means everyone must mmap! */
+               return tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR,
+                                 "tdb_mmap failed for size %lld (%s)",
+                                 (long long)tdb->file->map_size,
+                                 strerror(errno));
+#else
                tdb_logerr(tdb, TDB_SUCCESS, TDB_LOG_WARNING,
                           "tdb_mmap failed for size %lld (%s)",
                           (long long)tdb->file->map_size, strerror(errno));
+#endif
        }
+       return TDB_SUCCESS;
 }
 
 /* check for an out of bounds access - if it is out of bounds then
@@ -143,8 +154,7 @@ static enum TDB_ERROR tdb_oob(struct tdb_context *tdb,
        tdb_munmap(tdb->file);
 
        tdb->file->map_size = st.st_size;
-       tdb_mmap(tdb);
-       return TDB_SUCCESS;
+       return tdb_mmap(tdb);
 }
 
 /* Endian conversion: we only ever deal with 8 byte quantities */
@@ -270,6 +280,9 @@ static enum TDB_ERROR tdb_write(struct tdb_context *tdb, tdb_off_t off,
        if (tdb->file->map_ptr) {
                memcpy(off + (char *)tdb->file->map_ptr, buf, len);
        } else {
+#ifdef HAVE_INCOHERENT_MMAP
+               return TDB_ERR_IO;
+#else
                ssize_t ret;
                ret = pwrite(tdb->file->fd, buf, len, off);
                if (ret != len) {
@@ -282,6 +295,7 @@ static enum TDB_ERROR tdb_write(struct tdb_context *tdb, tdb_off_t off,
                                          ret, (size_t)off, (size_t)len,
                                          strerror(errno));
                }
+#endif
        }
        return TDB_SUCCESS;
 }
@@ -300,6 +314,9 @@ static enum TDB_ERROR tdb_read(struct tdb_context *tdb, tdb_off_t off,
        if (tdb->file->map_ptr) {
                memcpy(buf, off + (char *)tdb->file->map_ptr, len);
        } else {
+#ifdef HAVE_INCOHERENT_MMAP
+               return TDB_ERR_IO;
+#else
                ssize_t r = pread(tdb->file->fd, buf, len, off);
                if (r != len) {
                        return tdb_logerr(tdb, TDB_ERR_IO, TDB_LOG_ERROR,
@@ -309,6 +326,7 @@ static enum TDB_ERROR tdb_read(struct tdb_context *tdb, tdb_off_t off,
                                          strerror(errno),
                                          (size_t)tdb->file->map_size);
                }
+#endif
        }
        return TDB_SUCCESS;
 }
@@ -439,6 +457,7 @@ static enum TDB_ERROR tdb_expand_file(struct tdb_context *tdb,
                }
                tdb->file->map_ptr = new;
                tdb->file->map_size += addition;
+               return TDB_SUCCESS;
        } else {
                /* Unmap before trying to write; old TDB claimed OpenBSD had
                 * problem with this otherwise. */
@@ -457,9 +476,8 @@ static enum TDB_ERROR tdb_expand_file(struct tdb_context *tdb,
                if (ecode != TDB_SUCCESS)
                        return ecode;
                tdb->file->map_size += addition;
-               tdb_mmap(tdb);
+               return tdb_mmap(tdb);
        }
-       return TDB_SUCCESS;
 }
 
 const void *tdb_access_read(struct tdb_context *tdb,
index 04a433be3865aee54c31dc54234915a5eeba6de4..0ee8fa4f0959387fdfc93aafb9100fa395fe5602 100644 (file)
@@ -454,7 +454,7 @@ void *tdb_convert(const struct tdb_context *tdb, void *buf, tdb_len_t size);
 
 /* Unmap and try to map the tdb. */
 void tdb_munmap(struct tdb_file *file);
-void tdb_mmap(struct tdb_context *tdb);
+enum TDB_ERROR tdb_mmap(struct tdb_context *tdb);
 
 /* Either alloc a copy, or give direct access.  Release frees or noop. */
 const void *tdb_access_read(struct tdb_context *tdb,
index c9224bdeeddfaf99b268b033cd44f35cec39d262..4ba69246457cc2ecf155a9a68e3b074058af82d6 100644 (file)
@@ -386,7 +386,9 @@ _PUBLIC_ void tdb_add_flag(struct tdb_context *tdb, unsigned flag)
                break;
        case TDB_NOMMAP:
                tdb->flags |= TDB_NOMMAP;
+#ifndef HAVE_INCOHERENT_MMAP
                tdb_munmap(tdb->file);
+#endif
                break;
        case TDB_NOSYNC:
                tdb->flags |= TDB_NOSYNC;
@@ -423,7 +425,10 @@ _PUBLIC_ void tdb_remove_flag(struct tdb_context *tdb, unsigned flag)
                break;
        case TDB_NOMMAP:
                tdb->flags &= ~TDB_NOMMAP;
+#ifndef HAVE_INCOHERENT_MMAP
+               /* If mmap incoherent, we were mmaping anyway. */
                tdb_mmap(tdb);
+#endif
                break;
        case TDB_NOSYNC:
                tdb->flags &= ~TDB_NOSYNC;