From a93e03d27de573988263aa4e39e55e7edbe34069 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 22 Mar 2012 10:47:27 +1030 Subject: lib/tdb2: fix OpenBSD incoherent mmap (tdb2 version) 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 --- lib/tdb2/io.c | 32 +++++++++++++++++++++++++------- lib/tdb2/private.h | 2 +- lib/tdb2/tdb.c | 5 +++++ 3 files changed, 31 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/tdb2/io.c b/lib/tdb2/io.c index 5634922db3..e27a9fe832 100644 --- a/lib/tdb2/io.c +++ b/lib/tdb2/io.c @@ -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, diff --git a/lib/tdb2/private.h b/lib/tdb2/private.h index 04a433be38..0ee8fa4f09 100644 --- a/lib/tdb2/private.h +++ b/lib/tdb2/private.h @@ -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, diff --git a/lib/tdb2/tdb.c b/lib/tdb2/tdb.c index c9224bdeed..4ba6924645 100644 --- a/lib/tdb2/tdb.c +++ b/lib/tdb2/tdb.c @@ -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; -- cgit