dovecot: Code cleanups and some minor fixes.
dovecot at dovecot.org
dovecot at dovecot.org
Sat Sep 22 11:43:02 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/53313d1e7e4f
changeset: 6443:53313d1e7e4f
user: Timo Sirainen <tss at iki.fi>
date: Sat Sep 22 11:42:58 2007 +0300
description:
Code cleanups and some minor fixes.
diffstat:
2 files changed, 111 insertions(+), 77 deletions(-)
src/lib-index/mail-cache-fields.c | 89 ++++++++++++++++------------
src/lib-index/mail-cache-transaction.c | 99 +++++++++++++++++++-------------
diffs (truncated from 307 to 300 lines):
diff -r 6f12401a149e -r 53313d1e7e4f src/lib-index/mail-cache-fields.c
--- a/src/lib-index/mail-cache-fields.c Sat Sep 22 11:11:58 2007 +0300
+++ b/src/lib-index/mail-cache-fields.c Sat Sep 22 11:42:58 2007 +0300
@@ -10,6 +10,10 @@
#include <stddef.h>
#define CACHE_HDR_PREFETCH 1024
+
+#define CACHE_FIELD_IS_NEWLY_WANTED(cache, field_idx) \
+ ((cache)->field_file_map[field_idx] == (uint32_t)-1 && \
+ (cache)->fields[field_idx].used)
static bool field_has_fixed_size(enum mail_cache_field_type type)
{
@@ -340,53 +344,61 @@ int mail_cache_header_fields_read(struct
return 0;
}
-static void copy_to_buf(struct mail_cache *cache, buffer_t *dest,
+static void copy_to_buf(struct mail_cache *cache, buffer_t *dest, bool add_new,
size_t offset, size_t size)
{
const void *data;
unsigned int i, field;
+ /* copy the existing fields */
for (i = 0; i < cache->file_fields_count; i++) {
field = cache->file_field_map[i];
data = CONST_PTR_OFFSET(&cache->fields[field], offset);
buffer_append(dest, data, size);
}
+ if (!add_new)
+ return;
+
+ /* copy newly wanted fields */
for (i = 0; i < cache->fields_count; i++) {
- if (cache->field_file_map[i] != (uint32_t)-1 ||
- !cache->fields[i].used)
- continue;
- data = CONST_PTR_OFFSET(&cache->fields[i], offset);
- buffer_append(dest, data, size);
+ if (CACHE_FIELD_IS_NEWLY_WANTED(cache, i)) {
+ data = CONST_PTR_OFFSET(&cache->fields[i], offset);
+ buffer_append(dest, data, size);
+ }
}
}
static void copy_to_buf_byte(struct mail_cache *cache, buffer_t *dest,
- size_t offset)
+ bool add_new, size_t offset)
{
const int *data;
unsigned int i, field;
uint8_t byte;
+ /* copy the existing fields */
for (i = 0; i < cache->file_fields_count; i++) {
field = cache->file_field_map[i];
data = CONST_PTR_OFFSET(&cache->fields[field], offset);
byte = (uint8_t)*data;
buffer_append(dest, &byte, 1);
}
+ if (!add_new)
+ return;
+
+ /* copy newly wanted fields */
for (i = 0; i < cache->fields_count; i++) {
- if (cache->field_file_map[i] != (uint32_t)-1 ||
- !cache->fields[i].used)
- continue;
- data = CONST_PTR_OFFSET(&cache->fields[i], offset);
- byte = (uint8_t)*data;
- buffer_append(dest, &byte, 1);
+ if (CACHE_FIELD_IS_NEWLY_WANTED(cache, i)) {
+ data = CONST_PTR_OFFSET(&cache->fields[i], offset);
+ byte = (uint8_t)*data;
+ buffer_append(dest, &byte, 1);
+ }
}
}
static int mail_cache_header_fields_update_locked(struct mail_cache *cache)
{
buffer_t *buffer;
- uint32_t i, offset;
+ uint32_t i, offset, dec_offset;
int ret = 0;
if (mail_cache_header_fields_read(cache) < 0 ||
@@ -396,21 +408,20 @@ static int mail_cache_header_fields_upda
t_push();
buffer = buffer_create_dynamic(pool_datastack_create(), 256);
- copy_to_buf(cache, buffer,
+ copy_to_buf(cache, buffer, FALSE,
offsetof(struct mail_cache_field_private, last_used),
sizeof(uint32_t));
- ret = mail_cache_write(cache, buffer->data,
- sizeof(uint32_t) * cache->file_fields_count,
+ ret = mail_cache_write(cache, buffer->data, buffer->used,
offset + MAIL_CACHE_FIELD_LAST_USED());
if (ret == 0) {
buffer_set_used_size(buffer, 0);
- copy_to_buf_byte(cache, buffer,
+ copy_to_buf_byte(cache, buffer, FALSE,
offsetof(struct mail_cache_field, decision));
- ret = mail_cache_write(cache, buffer->data,
- sizeof(uint8_t) * cache->file_fields_count, offset +
- MAIL_CACHE_FIELD_DECISION(cache->file_fields_count));
-
+ dec_offset = offset +
+ MAIL_CACHE_FIELD_DECISION(cache->file_fields_count);
+ ret = mail_cache_write(cache, buffer->data, buffer->used,
+ dec_offset);
if (ret == 0) {
for (i = 0; i < cache->file_fields_count; i++)
cache->fields[i].decision_dirty = FALSE;
@@ -450,41 +461,41 @@ void mail_cache_header_fields_get(struct
memset(&hdr, 0, sizeof(hdr));
hdr.fields_count = cache->file_fields_count;
for (i = 0; i < cache->fields_count; i++) {
- if (cache->field_file_map[i] == (uint32_t)-1 &&
- cache->fields[i].used)
+ if (CACHE_FIELD_IS_NEWLY_WANTED(cache, i))
hdr.fields_count++;
}
buffer_append(dest, &hdr, sizeof(hdr));
/* we have to keep the field order for the existing fields. */
- copy_to_buf(cache, dest,
+ copy_to_buf(cache, dest, TRUE,
offsetof(struct mail_cache_field_private, last_used),
sizeof(uint32_t));
- copy_to_buf(cache, dest, offsetof(struct mail_cache_field, field_size),
+ copy_to_buf(cache, dest, TRUE,
+ offsetof(struct mail_cache_field, field_size),
sizeof(uint32_t));
- copy_to_buf_byte(cache, dest, offsetof(struct mail_cache_field, type));
- copy_to_buf_byte(cache, dest,
+ copy_to_buf_byte(cache, dest, TRUE,
+ offsetof(struct mail_cache_field, type));
+ copy_to_buf_byte(cache, dest, TRUE,
offsetof(struct mail_cache_field, decision));
- i_assert(buffer_get_used_size(dest) == sizeof(hdr) +
+ i_assert(dest->used == sizeof(hdr) +
(sizeof(uint32_t)*2 + 2) * hdr.fields_count);
- /* add fields' names */
+ /* add existing fields' names */
for (i = 0; i < cache->file_fields_count; i++) {
field = cache->file_field_map[i];
name = cache->fields[field].field.name;
buffer_append(dest, name, strlen(name)+1);
}
+ /* add newly wanted fields' names */
for (i = 0; i < cache->fields_count; i++) {
- if (cache->field_file_map[i] != (uint32_t)-1 ||
- !cache->fields[i].used)
- continue;
-
- name = cache->fields[i].field.name;
- buffer_append(dest, name, strlen(name)+1);
- }
-
- hdr.size = buffer_get_used_size(dest);
+ if (CACHE_FIELD_IS_NEWLY_WANTED(cache, i)) {
+ name = cache->fields[i].field.name;
+ buffer_append(dest, name, strlen(name)+1);
+ }
+ }
+
+ hdr.size = dest->used;
buffer_write(dest, 0, &hdr, sizeof(hdr));
if ((hdr.size & 3) != 0)
diff -r 6f12401a149e -r 53313d1e7e4f src/lib-index/mail-cache-transaction.c
--- a/src/lib-index/mail-cache-transaction.c Sat Sep 22 11:11:58 2007 +0300
+++ b/src/lib-index/mail-cache-transaction.c Sat Sep 22 11:42:58 2007 +0300
@@ -663,18 +663,58 @@ void mail_cache_transaction_rollback(str
mail_cache_transaction_free(ctx);
}
+static int
+mail_cache_header_fields_write(struct mail_cache_transaction_ctx *ctx,
+ const buffer_t *buffer)
+{
+ struct mail_cache *cache = ctx->cache;
+ size_t size = buffer->used;
+ uint32_t offset, hdr_offset;
+
+ if (mail_cache_transaction_get_space(ctx, size, size,
+ &offset, NULL, TRUE) <= 0)
+ return -1;
+
+ if (mail_cache_write(cache, buffer->data, size, offset) < 0)
+ return -1;
+
+ if (!cache->index->fsync_disable) {
+ if (fdatasync(cache->fd) < 0) {
+ mail_cache_set_syscall_error(cache, "fdatasync()");
+ return -1;
+ }
+ }
+ if (mail_cache_header_fields_get_next_offset(cache, &hdr_offset) < 0)
+ return -1;
+
+ /* if we rollback the transaction, we must not overwrite this
+ area because it's already committed after updating the
+ header offset */
+ mail_cache_transaction_partial_commit(ctx, offset, size);
+
+ /* after it's guaranteed to be in disk, update header offset */
+ offset = mail_index_uint32_to_offset(offset);
+ if (mail_cache_write(cache, &offset, sizeof(offset), hdr_offset) < 0)
+ return -1;
+
+ if (hdr_offset == offsetof(struct mail_cache_header,
+ field_header_offset)) {
+ /* we're adding the first field. hdr_copy needs to be kept
+ in sync so unlocking won't overwrite it. */
+ cache->hdr_copy.field_header_offset = hdr_offset;
+ }
+ return 0;
+}
+
static int mail_cache_header_add_field(struct mail_cache_transaction_ctx *ctx,
unsigned int field_idx)
{
struct mail_cache *cache = ctx->cache;
buffer_t *buffer;
- const void *data;
- size_t size;
- uint32_t offset, hdr_offset;
- int ret = 0;
-
- ctx->cache->fields[field_idx].last_used = ioloop_time;
- ctx->cache->fields[field_idx].used = TRUE;
+ int ret;
+
+ cache->fields[field_idx].last_used = ioloop_time;
+ cache->fields[field_idx].used = TRUE;
if ((ret = mail_cache_transaction_lock(ctx)) <= 0) {
/* create the cache file if it doesn't exist yet */
@@ -694,7 +734,7 @@ static int mail_cache_header_add_field(s
return -1;
}
- if (ctx->cache->field_file_map[field_idx] != (uint32_t)-1) {
+ if (cache->field_file_map[field_idx] != (uint32_t)-1) {
/* it was already added */
if (mail_cache_unlock(cache) < 0)
return -1;
@@ -704,37 +744,20 @@ static int mail_cache_header_add_field(s
t_push();
buffer = buffer_create_dynamic(pool_datastack_create(), 256);
mail_cache_header_fields_get(cache, buffer);
- data = buffer_get_data(buffer, &size);
-
- if (mail_cache_transaction_get_space(ctx, size, size,
- &offset, NULL, TRUE) <= 0)
+ ret = mail_cache_header_fields_write(ctx, buffer);
+ t_pop();
+
+ if (ret == 0) {
+ /* we wrote all the headers, so there are no pending changes */
+ cache->field_header_write_pending = FALSE;
+ ret = mail_cache_header_fields_read(cache);
+ }
+ if (ret == 0 && cache->field_file_map[field_idx] == (uint32_t)-1) {
+ mail_index_set_error(cache->index,
+ "Cache file %s: Newly added field got "
+ "lost unexpectedly", cache->filepath);
ret = -1;
- else if (mail_cache_write(cache, data, size, offset) < 0)
- ret = -1;
- else if (!cache->index->fsync_disable && fdatasync(cache->fd) < 0) {
- mail_cache_set_syscall_error(cache, "fdatasync()");
- ret = -1;
- } else if (mail_cache_header_fields_get_next_offset(cache,
- &hdr_offset) < 0)
- ret = -1;
- else {
- /* if we rollback the transaction, we must not overwrite this
- area because it's already committed after updating the
- header offset */
- mail_cache_transaction_partial_commit(ctx, offset, size);
-
- /* after it's guaranteed to be in disk, update header offset */
- offset = mail_index_uint32_to_offset(offset);
- if (mail_cache_write(cache, &offset, sizeof(offset),
- hdr_offset) < 0)
- ret = -1;
- else {
- /* we'll need to fix mappings. */
- if (mail_cache_header_fields_read(cache) < 0)
- ret = -1;
More information about the dovecot-cvs
mailing list