[dovecot-cvs] dovecot/src/lib-index mail-index-lock.c, 1.8,
1.9 mail-index-private.h, 1.6, 1.7 mail-index-sync-update.c,
1.6, 1.7 mail-index.c, 1.110, 1.111
cras at procontrol.fi
cras at procontrol.fi
Wed Apr 28 23:51:24 EEST 2004
Update of /home/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv13353/lib-index
Modified Files:
mail-index-lock.c mail-index-private.h
mail-index-sync-update.c mail-index.c
Log Message:
fixes
Index: mail-index-lock.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-lock.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- mail-index-lock.c 28 Apr 2004 19:16:23 -0000 1.8
+++ mail-index-lock.c 28 Apr 2004 20:51:22 -0000 1.9
@@ -123,7 +123,7 @@
lock_type == F_WRLCK ? (PROT_READ|PROT_WRITE) :
PROT_READ;
if (mprotect(index->map->mmap_base,
- index->map->file_size, prot) < 0) {
+ index->map->mmap_size, prot) < 0) {
mail_index_set_syscall_error(index, "mprotect()");
return -1;
}
Index: mail-index-private.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-private.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- mail-index-private.h 28 Apr 2004 19:41:21 -0000 1.6
+++ mail-index-private.h 28 Apr 2004 20:51:22 -0000 1.7
@@ -41,7 +41,7 @@
unsigned int records_count;
void *mmap_base;
- size_t file_size, file_used_size;
+ size_t mmap_size, mmap_used_size;
buffer_t *buffer;
Index: mail-index-sync-update.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index-sync-update.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- mail-index-sync-update.c 28 Apr 2004 19:41:21 -0000 1.6
+++ mail-index-sync-update.c 28 Apr 2004 20:51:22 -0000 1.7
@@ -98,34 +98,39 @@
static int mail_index_grow(struct mail_index *index, unsigned int count)
{
struct mail_index_map *map = index->map;
- size_t size, file_used_size;
unsigned int records_count;
+ size_t size;
if (MAIL_INDEX_MAP_IS_IN_MEMORY(map)) {
(void)buffer_append_space_unsafe(map->buffer,
count * sizeof(struct mail_index_record));
+ map->records = buffer_get_modifyable_data(map->buffer, NULL);
return 0;
}
+ size = map->hdr->header_size +
+ (map->records_count + count) * sizeof(struct mail_index_record);
+ if (size <= map->mmap_size)
+ return 0;
+
/* when we grow fast, do it exponentially */
if (count < index->last_grow_count)
count = index->last_grow_count;
count = nearest_power(count);
index->last_grow_count = count;
- size = map->file_used_size + count * sizeof(struct mail_index_record);
+ size = map->hdr->header_size +
+ (map->records_count + count) * sizeof(struct mail_index_record);
if (file_set_size(index->fd, (off_t)size) < 0)
return mail_index_set_syscall_error(index, "file_set_size()");
records_count = map->records_count;
- file_used_size = map->file_used_size;
if (mail_index_map(index, TRUE) <= 0)
return -1;
- i_assert(map->file_size >= size);
+ i_assert(map->mmap_size >= size);
map->records_count = records_count;
- map->file_used_size = file_used_size;
return 0;
}
@@ -135,14 +140,10 @@
{
struct mail_index_map *map = ctx->index->map;
unsigned int i;
- size_t space;
uint32_t next_uid;
- space = (map->file_size - map->file_used_size) / sizeof(*appends);
- if (space < count) {
- if (mail_index_grow(ctx->index, count) < 0)
- return -1;
- }
+ if (mail_index_grow(ctx->index, count) < 0)
+ return -1;
next_uid = ctx->hdr.next_uid;
for (i = 0; i < count; i++) {
@@ -166,7 +167,6 @@
memcpy(map->records + map->records_count, appends,
count * sizeof(*appends));
map->records_count += count;
- map->file_used_size += count * sizeof(struct mail_index_record);
return 0;
}
@@ -254,8 +254,6 @@
dest_idx += count;
map->records_count = dest_idx;
- map->file_used_size = index->hdr->header_size +
- map->records_count * sizeof(struct mail_index_record);
}
ret = 0;
@@ -269,8 +267,11 @@
ctx.hdr.log_file_offset = file_offset;
if (!MAIL_INDEX_MAP_IS_IN_MEMORY(map)) {
+ map->mmap_used_size = index->hdr->header_size +
+ map->records_count * sizeof(struct mail_index_record);
+
memcpy(map->mmap_base, &ctx.hdr, sizeof(ctx.hdr));
- if (msync(map->mmap_base, map->file_used_size, MS_SYNC) < 0) {
+ if (msync(map->mmap_base, map->mmap_used_size, MS_SYNC) < 0) {
mail_index_set_syscall_error(index, "msync()");
ret = -1;
}
Index: mail-index.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mail-index.c,v
retrieving revision 1.110
retrieving revision 1.111
diff -u -d -r1.110 -r1.111
--- mail-index.c 28 Apr 2004 18:52:06 -0000 1.110
+++ mail-index.c 28 Apr 2004 20:51:22 -0000 1.111
@@ -36,36 +36,11 @@
i_free(index);
}
-static int mail_index_check_quick_header(struct mail_index *index,
- struct mail_index_map *map)
-{
- if ((map->hdr->flags & MAIL_INDEX_HDR_FLAG_CORRUPTED) != 0) {
- /* either a crash or we've already complained about it */
- return -1;
- }
-
- if (map->file_used_size > map->file_size) {
- map->records_count =
- (map->file_size - map->hdr->header_size) /
- sizeof(struct mail_index_record);
- map->file_used_size = map->file_size;
-
- mail_index_set_error(index, "Corrupted index file %s: "
- "messages_count too large (%u > %u)",
- index->filepath, map->hdr->messages_count,
- map->records_count);
- return 0;
- }
-
- return 1;
-}
-
static int mail_index_check_header(struct mail_index *index,
struct mail_index_map *map)
{
const struct mail_index_header *hdr = map->hdr;
unsigned char compat_data[3];
- int ret;
#ifndef WORDS_BIGENDIAN
compat_data[0] = MAIL_INDEX_COMPAT_LITTLE_ENDIAN;
@@ -84,8 +59,10 @@
return -1;
}
- if ((ret = mail_index_check_quick_header(index, map)) <= 0)
- return ret;
+ if ((map->hdr->flags & MAIL_INDEX_HDR_FLAG_CORRUPTED) != 0) {
+ /* either a crash or we've already complained about it */
+ return -1;
+ }
/* following some extra checks that only take a bit of CPU */
if (hdr->uid_validity == 0) {
@@ -117,14 +94,14 @@
map->buffer = NULL;
} else if (map->mmap_base != NULL) {
i_assert(map->buffer == NULL);
- if (munmap(map->mmap_base, map->file_size) < 0)
+ if (munmap(map->mmap_base, map->mmap_size) < 0)
mail_index_set_syscall_error(index, "munmap()");
map->mmap_base = NULL;
}
if (map->refcount > 0) {
- map->file_size = 0;
- map->file_used_size = 0;
+ map->mmap_size = 0;
+ map->mmap_used_size = 0;
map->hdr = NULL;
map->records = NULL;
map->records_count = 0;
@@ -148,31 +125,92 @@
mail_index_unmap(index, map);
}
-static int mail_index_read_map(struct mail_index *index,
- struct mail_index_map *map)
+static int mail_index_mmap(struct mail_index *index, struct mail_index_map *map)
{
- struct stat st;
- void *data;
- size_t file_size;
- int ret;
+ const struct mail_index_header *hdr;
+ unsigned int records_count;
- if (fstat(index->fd, &st) < 0) {
- if (errno == ESTALE)
- return 0;
- mail_index_set_syscall_error(index, "fstat()");
+ map->mmap_base = index->lock_type != F_WRLCK ?
+ mmap_ro_file(index->fd, &map->mmap_size) :
+ mmap_rw_file(index->fd, &map->mmap_size);
+ if (map->mmap_base == MAP_FAILED) {
+ map->mmap_base = NULL;
+ mail_index_set_syscall_error(index, "mmap()");
return -1;
}
- file_size = st.st_size;
- if (map->buffer == NULL) {
- map->buffer = buffer_create_dynamic(default_pool,
- file_size, (size_t)-1);
+ if (map->mmap_size < MAIL_INDEX_HEADER_MIN_SIZE) {
+ mail_index_set_error(index, "Corrupted index file %s: "
+ "File too small (%"PRIuSIZE_T")",
+ index->filepath, map->mmap_size);
+ return 0;
}
- /* @UNSAFE */
- buffer_set_used_size(map->buffer, 0);
- data = buffer_append_space_unsafe(map->buffer, file_size);
- ret = pread_full(index->fd, data, file_size, 0);
+ hdr = map->mmap_base;
+ map->mmap_used_size = hdr->header_size +
+ hdr->messages_count * sizeof(struct mail_index_record);
+
+ if (map->mmap_used_size > map->mmap_size) {
+ records_count = (map->mmap_size - hdr->header_size) /
+ sizeof(struct mail_index_record);
+ mail_index_set_error(index, "Corrupted index file %s: "
+ "messages_count too large (%u > %u)",
+ index->filepath, map->hdr->messages_count,
+ records_count);
+ return 0;
+ }
+
+ map->hdr = hdr;
+ if (map->hdr->header_size < sizeof(*map->hdr)) {
+ /* header smaller than ours, make a copy so our newer headers
+ won't have garbage in them */
+ memcpy(&map->hdr_copy, map->hdr, map->hdr->header_size);
+ map->hdr = &map->hdr_copy;
+ }
+
+ map->records = PTR_OFFSET(map->mmap_base, map->hdr->header_size);
+ map->records_count = map->hdr->messages_count;
+ return 1;
+}
+
+static int mail_index_read_map(struct mail_index *index,
+ struct mail_index_map *map)
+{
+ struct mail_index_header hdr;
+ void *data;
+ ssize_t ret;
+ size_t pos, records_size;
+
+ do {
+ memset(&hdr, 0, sizeof(hdr));
+
+ ret = 1;
+ for (pos = 0; ret > 0 && pos < sizeof(hdr); ) {
+ ret = pread(index->fd, PTR_OFFSET(&hdr, pos),
+ sizeof(hdr) - pos, pos);
+ if (ret > 0)
+ pos += ret;
+ }
+ if (ret < 0 || pos < MAIL_INDEX_HEADER_MIN_SIZE)
+ break;
+
+ records_size = hdr.messages_count *
+ sizeof(struct mail_index_record);
+
+ if (map->buffer == NULL) {
+ map->buffer = buffer_create_dynamic(default_pool,
+ records_size,
+ (size_t)-1);
+ }
+
+ /* @UNSAFE */
+ buffer_set_used_size(map->buffer, 0);
+ data = buffer_append_space_unsafe(map->buffer, records_size);
+
+ ret = pread_full(index->fd, data, records_size,
+ hdr.header_size);
+ } while (0);
+
if (ret < 0) {
if (errno == ESTALE)
return 0;
@@ -185,7 +223,11 @@
return -1;
}
- map->file_size = file_size;
+ map->records = data;
+ map->records_count = hdr.messages_count;
+
+ map->hdr_copy = hdr;
+ map->hdr = &map->hdr_copy;
return 1;
}
@@ -224,17 +266,19 @@
{
struct mail_index_map *map;
size_t used_size;
- void *base;
int ret;
- if (index->map != NULL) {
+ if (index->map != NULL && MAIL_INDEX_MAP_IS_IN_MEMORY(index->map)) {
+ /* FIXME: can we avoid reading it? */
+ map = index->map;
+ } else if (index->map != NULL) {
map = index->map;
/* see if re-mmaping is needed (file has grown) */
used_size = map->hdr->header_size +
map->hdr->messages_count *
sizeof(struct mail_index_record);
- if (map->file_size >= used_size && !force) {
+ if (map->mmap_size >= used_size && !force) {
/* update log file position in case it has changed */
map->log_file_seq = map->hdr->log_file_seq;
map->log_file_offset = map->hdr->log_file_offset;
@@ -242,7 +286,7 @@
}
if (map->mmap_base != NULL) {
- if (munmap(map->mmap_base, map->file_size) < 0)
+ if (munmap(map->mmap_base, map->mmap_size) < 0)
mail_index_set_syscall_error(index, "munmap()");
map->mmap_base = NULL;
}
@@ -254,20 +298,10 @@
index->hdr = NULL;
index->map = NULL;
- /* make sure if we fail we don't try to access anything outside the
- buffer */
- map->file_size = 0;
- map->file_used_size = 0;
-
if (!index->mmap_disable) {
- map->mmap_base = index->lock_type != F_WRLCK ?
- mmap_ro_file(index->fd, &map->file_size) :
- mmap_rw_file(index->fd, &map->file_size);
- if (map->mmap_base == MAP_FAILED) {
- map->mmap_base = NULL;
- mail_index_set_syscall_error(index, "mmap()");
+ if ((ret = mail_index_mmap(index, map)) <= 0) {
mail_index_unmap_forced(index, map);
- return -1;
+ return ret;
}
} else {
if (mail_index_read_map_with_retry(index, map) < 0) {
@@ -276,30 +310,6 @@
}
}
- if (map->file_size < MAIL_INDEX_HEADER_MIN_SIZE) {
- mail_index_set_error(index, "Corrupted index file %s: "
- "File too small (%"PRIuSIZE_T")",
- index->filepath, map->file_size);
- mail_index_unmap_forced(index, map);
- return 0;
- }
-
- base = !MAIL_INDEX_MAP_IS_IN_MEMORY(map) ? map->mmap_base :
- buffer_get_modifyable_data(map->buffer, NULL);
- map->hdr = base;
-
- if (map->hdr->header_size < sizeof(*map->hdr)) {
- /* header smaller than ours, make a copy so our newer headers
- won't have garbage in them */
- memcpy(&map->hdr_copy, map->hdr, map->hdr->header_size);
- map->hdr = &map->hdr_copy;
- }
-
- map->records = PTR_OFFSET(base, map->hdr->header_size);
- map->records_count = map->hdr->messages_count;
- map->file_used_size = map->hdr->header_size +
- map->records_count * sizeof(struct mail_index_record);
-
ret = mail_index_check_header(index, map);
if (ret < 0) {
mail_index_unmap_forced(index, map);
@@ -613,8 +623,10 @@
index->log = NULL;
}
- mail_index_unmap(index, index->map);
- index->map = NULL;
+ if (index->map != NULL) {
+ mail_index_unmap(index, index->map);
+ index->map = NULL;
+ }
if (index->fd != -1) {
if (close(index->fd) < 0)
@@ -623,6 +635,7 @@
}
i_free(index->copy_lock_path);
+ index->copy_lock_path = NULL;
i_free(index->filepath);
index->filepath = NULL;
More information about the dovecot-cvs
mailing list