diff options
Diffstat (limited to 'lib/tdb/common')
-rw-r--r-- | lib/tdb/common/io.c | 49 | ||||
-rw-r--r-- | lib/tdb/common/open.c | 4 | ||||
-rw-r--r-- | lib/tdb/common/tdb_private.h | 2 |
3 files changed, 35 insertions, 20 deletions
diff --git a/lib/tdb/common/io.c b/lib/tdb/common/io.c index ac21e3f67a..24c2d615ab 100644 --- a/lib/tdb/common/io.c +++ b/lib/tdb/common/io.c @@ -88,8 +88,7 @@ static int tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, return -1; } tdb->map_size = st.st_size; - tdb_mmap(tdb); - return 0; + return tdb_mmap(tdb); } /* write a lump of data at a specified offset */ @@ -111,6 +110,10 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, if (tdb->map_ptr) { memcpy(off + (char *)tdb->map_ptr, buf, len); } else { +#ifdef HAVE_INCOHERENT_MMAP + tdb->ecode = TDB_ERR_IO; + return -1; +#else ssize_t written = pwrite(tdb->fd, buf, len, off); if ((written != (ssize_t)len) && (written != -1)) { /* try once more */ @@ -135,6 +138,7 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, len, off)); return -1; } +#endif } return 0; } @@ -160,6 +164,10 @@ static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, if (tdb->map_ptr) { memcpy(buf, off + (char *)tdb->map_ptr, len); } else { +#ifdef HAVE_INCOHERENT_MMAP + tdb->ecode = TDB_ERR_IO; + return -1; +#else ssize_t ret = pread(tdb->fd, buf, len, off); if (ret != (ssize_t)len) { /* Ensure ecode is set for log fn. */ @@ -170,6 +178,7 @@ static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, (int)tdb->map_size)); return -1; } +#endif } if (cv) { tdb_convert(buf, len); @@ -222,13 +231,23 @@ int tdb_munmap(struct tdb_context *tdb) return 0; } -void tdb_mmap(struct tdb_context *tdb) +/* If mmap isn't coherent, *everyone* must always mmap. */ +static bool should_mmap(const struct tdb_context *tdb) +{ +#ifdef HAVE_INCOHERENT_MMAP + return true; +#else + return !(tdb->flags & TDB_NOMMAP); +#endif +} + +int tdb_mmap(struct tdb_context *tdb) { if (tdb->flags & TDB_INTERNAL) return; #ifdef HAVE_MMAP - if (!(tdb->flags & TDB_NOMMAP)) { + if (should_mmap(tdb)) { tdb->map_ptr = mmap(NULL, tdb->map_size, PROT_READ|(tdb->read_only? 0:PROT_WRITE), MAP_SHARED|MAP_FILE, tdb->fd, 0); @@ -241,6 +260,10 @@ void tdb_mmap(struct tdb_context *tdb) tdb->map_ptr = NULL; TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_mmap failed for size %d (%s)\n", tdb->map_size, strerror(errno))); +#ifdef HAVE_INCOHERENT_MMAP + tdb->ecode = TDB_ERR_IO; + return -1; +#endif } } else { tdb->map_ptr = NULL; @@ -248,6 +271,7 @@ void tdb_mmap(struct tdb_context *tdb) #else tdb->map_ptr = NULL; #endif + return 0; } /* expand a file. we prefer to use ftruncate, as that is what posix @@ -360,12 +384,6 @@ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) if (!(tdb->flags & TDB_INTERNAL)) tdb_munmap(tdb); - /* - * We must ensure the file is unmapped before doing this - * to ensure consistency with systems like OpenBSD where - * writes and mmaps are not consistent. - */ - /* expand the file itself */ if (!(tdb->flags & TDB_INTERNAL)) { if (tdb->methods->tdb_expand_file(tdb, tdb->map_size, size) != 0) @@ -383,14 +401,9 @@ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) } tdb->map_ptr = new_map_ptr; } else { - /* - * We must ensure the file is remapped before adding the space - * to ensure consistency with systems like OpenBSD where - * writes and mmaps are not consistent. - */ - - /* We're ok if the mmap fails as we'll fallback to read/write */ - tdb_mmap(tdb); + if (tdb_mmap(tdb) != 0) { + goto fail; + } } /* form a new freelist record */ diff --git a/lib/tdb/common/open.c b/lib/tdb/common/open.c index 2965ea77b5..8836f8442e 100644 --- a/lib/tdb/common/open.c +++ b/lib/tdb/common/open.c @@ -587,7 +587,9 @@ static int tdb_reopen_internal(struct tdb_context *tdb, bool active_lock) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n")); goto fail; } - tdb_mmap(tdb); + if (tdb_mmap(tdb) != 0) { + goto fail; + } #endif /* fake pread or pwrite */ /* We may still think we hold the active lock. */ diff --git a/lib/tdb/common/tdb_private.h b/lib/tdb/common/tdb_private.h index 9913284f3c..0441fb287f 100644 --- a/lib/tdb/common/tdb_private.h +++ b/lib/tdb/common/tdb_private.h @@ -222,7 +222,7 @@ struct tdb_context { internal prototypes */ int tdb_munmap(struct tdb_context *tdb); -void tdb_mmap(struct tdb_context *tdb); +int tdb_mmap(struct tdb_context *tdb); int tdb_lock(struct tdb_context *tdb, int list, int ltype); int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype); int tdb_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype, |