diff options
author | Jeremy Allison <jra@samba.org> | 2001-05-04 22:23:37 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2001-05-04 22:23:37 +0000 |
commit | 887d796a28a0aa28db84f1c02a1873f7f9f0cb0d (patch) | |
tree | 59159577b32e630f791309c841b570feb608768d | |
parent | f35157f39293f9fa240a28642c41708b55d301c8 (diff) | |
download | samba-887d796a28a0aa28db84f1c02a1873f7f9f0cb0d.tar.gz samba-887d796a28a0aa28db84f1c02a1873f7f9f0cb0d.tar.bz2 samba-887d796a28a0aa28db84f1c02a1873f7f9f0cb0d.zip |
Fix problem with OpenBSD mmap and write not being coherent.
Jeremy.
(This used to be commit 4c6a8273c6dd3e2aeda5a63c4a62aa55bc133099)
-rw-r--r-- | source3/tdb/tdb.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index b1335728ab..bf94e4cbd3 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -429,6 +429,7 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size) struct list_struct rec; tdb_off offset; char b = 0; + void *old_map_ptr; if (tdb_lock(tdb, -1, F_WRLCK) == -1) return 0; @@ -439,20 +440,43 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size) the database up to a multiple of TDB_PAGE_SIZE */ size = TDB_ALIGN(tdb->map_size + size*10, TDB_PAGE_SIZE) - tdb->map_size; - /* expand the file itself */ - if (!(tdb->flags & TDB_INTERNAL)) { - lseek(tdb->fd, tdb->map_size + size - 1, SEEK_SET); - if (write(tdb->fd, &b, 1) != 1) goto fail; - } + old_map_ptr = tdb->map_ptr; if (!(tdb->flags & TDB_INTERNAL) && tdb->map_ptr) tdb->map_ptr = tdb_munmap(tdb->map_ptr, tdb->map_size); + /* + * 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 (lseek(tdb->fd, tdb->map_size + size - 1, SEEK_SET)!=tdb->map_size + size - 1) + goto fail; + if (write(tdb->fd, &b, 1) != 1) + goto fail; + } + tdb->map_size += size; if (tdb->flags & TDB_INTERNAL) tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size); + /* + * 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. + */ + + if (!(tdb->flags & TDB_NOMMAP)) { + tdb->map_ptr = tdb_mmap(tdb->map_size, 0, tdb->fd); + /* if old_map_ptr was != NULL but the new one is, we have an error. */ + if (old_map_ptr && (tdb->map_ptr == NULL)) + goto fail; + } + /* form a new freelist record */ memset(&rec,'\0',sizeof(rec)); rec.rec_len = size - sizeof(rec); @@ -461,9 +485,6 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size) offset = tdb->map_size - size; if (tdb_free(tdb, offset, &rec) == -1) goto fail; - if (!(tdb->flags & TDB_NOMMAP)) - tdb->map_ptr = tdb_mmap(tdb->map_size, 0, tdb->fd); - tdb_unlock(tdb, -1, F_WRLCK); return 0; fail: |