diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2012-06-22 09:44:40 +0930 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2012-06-22 07:35:17 +0200 |
commit | bd5c061932d9aaf2e66cd56a39743c9ff34c3a88 (patch) | |
tree | 6bc78039fa38af2af1134f658548c4e4ec722fb7 /lib | |
parent | 0a34f342c3facace0767ff08f05532c9f161e305 (diff) | |
download | samba-bd5c061932d9aaf2e66cd56a39743c9ff34c3a88.tar.gz samba-bd5c061932d9aaf2e66cd56a39743c9ff34c3a88.tar.bz2 samba-bd5c061932d9aaf2e66cd56a39743c9ff34c3a88.zip |
ntdb: allow direct access for NTDB_INTERNAL dbs during expansion.
NTDB_INTERNAL databases need to malloc and copy to keep old versions
around if we expand, in a similar way to the manner in which keep old
mmaps around.
Of course, it only works for read-only accesses, since the two copies
are not synced.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ntdb/io.c | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/lib/ntdb/io.c b/lib/ntdb/io.c index 6749d282d9..7645cddc37 100644 --- a/lib/ntdb/io.c +++ b/lib/ntdb/io.c @@ -36,11 +36,34 @@ static void free_old_mmaps(struct ntdb_context *ntdb) while ((i = ntdb->file->old_mmaps) != NULL) { ntdb->file->old_mmaps = i->next; - munmap(i->map_ptr, i->map_size); + if (ntdb->flags & NTDB_INTERNAL) { + ntdb->free_fn(i->map_ptr, ntdb->alloc_data); + } else { + munmap(i->map_ptr, i->map_size); + } ntdb->free_fn(i, ntdb->alloc_data); } } +static enum NTDB_ERROR save_old_map(struct ntdb_context *ntdb) +{ + struct ntdb_old_mmap *old; + + assert(ntdb->file->direct_count); + + old = ntdb->alloc_fn(ntdb->file, sizeof(*old), ntdb->alloc_data); + if (!old) { + return ntdb_logerr(ntdb, NTDB_ERR_OOM, NTDB_LOG_ERROR, + "save_old_map alloc failed"); + } + old->next = ntdb->file->old_mmaps; + old->map_ptr = ntdb->file->map_ptr; + old->map_size = ntdb->file->map_size; + ntdb->file->old_mmaps = old; + + return NTDB_SUCCESS; +} + enum NTDB_ERROR ntdb_munmap(struct ntdb_context *ntdb) { if (ntdb->file->fd == -1) { @@ -53,16 +76,7 @@ enum NTDB_ERROR ntdb_munmap(struct ntdb_context *ntdb) /* We can't unmap now if there are accessors. */ if (ntdb->file->direct_count) { - struct ntdb_old_mmap *old - = ntdb->alloc_fn(ntdb, sizeof(*old), ntdb->alloc_data); - if (!old) { - return ntdb_logerr(ntdb, NTDB_ERR_OOM, NTDB_LOG_ERROR, - "ntdb_munmap alloc failed"); - } - old->next = ntdb->file->old_mmaps; - old->map_ptr = ntdb->file->map_ptr; - old->map_size = ntdb->file->map_size; - ntdb->file->old_mmaps = old; + return save_old_map(ntdb); } else { munmap(ntdb->file->map_ptr, ntdb->file->map_size); ntdb->file->map_ptr = NULL; @@ -434,9 +448,26 @@ static enum NTDB_ERROR ntdb_expand_file(struct ntdb_context *ntdb, } if (ntdb->flags & NTDB_INTERNAL) { - char *new = ntdb->expand_fn(ntdb->file->map_ptr, - ntdb->file->map_size + addition, - ntdb->alloc_data); + char *new; + + /* Can't free it if we have direct accesses. */ + if (ntdb->file->direct_count) { + ecode = save_old_map(ntdb); + if (ecode) { + return ecode; + } + new = ntdb->alloc_fn(ntdb->file, + ntdb->file->map_size + addition, + ntdb->alloc_data); + if (new) { + memcpy(new, ntdb->file->map_ptr, + ntdb->file->map_size); + } + } else { + new = ntdb->expand_fn(ntdb->file->map_ptr, + ntdb->file->map_size + addition, + ntdb->alloc_data); + } if (!new) { return ntdb_logerr(ntdb, NTDB_ERR_OOM, NTDB_LOG_ERROR, "No memory to expand database"); |