# HG changeset patch # User Timo Sirainen # Date 1224350795 -10800 # Node ID 9ed4ecd4a866181fe9cc554e6dfd7cc68947c5fd # Parent 4296aa3fbb75ed1a03b698a1e98e9e7c7ecc4cea Fixes to handling "out of disk space/quota" write failures. diff -r 4296aa3fbb75 -r 9ed4ecd4a866 src/lib-index/mail-cache-compress.c --- a/src/lib-index/mail-cache-compress.c Sat Oct 18 17:07:42 2008 +0300 +++ b/src/lib-index/mail-cache-compress.c Sat Oct 18 20:26:35 2008 +0300 @@ -394,6 +394,10 @@ } if (mail_cache_copy(cache, trans, fd, &file_seq, &ext_offsets) < 0) { + /* the fields may have been updated in memory already. + reverse those changes by re-reading them from file. */ + if (mail_cache_header_fields_read(cache) < 0) + return -1; (void)file_dotlock_delete(&dotlock); return -1; } diff -r 4296aa3fbb75 -r 9ed4ecd4a866 src/lib-index/mail-cache.c --- a/src/lib-index/mail-cache.c Sat Oct 18 17:07:42 2008 +0300 +++ b/src/lib-index/mail-cache.c Sat Oct 18 20:26:35 2008 +0300 @@ -188,6 +188,29 @@ return 1; } +static void mail_cache_update_need_compress(struct mail_cache *cache) +{ + const struct mail_cache_header *hdr = cache->hdr; + unsigned int cont_percentage; + uoff_t max_del_space; + + cont_percentage = hdr->continued_record_count * 100 / + (cache->index->map->rec_map->records_count == 0 ? 1 : + cache->index->map->rec_map->records_count); + if (cont_percentage >= MAIL_CACHE_COMPRESS_CONTINUED_PERCENTAGE && + hdr->used_file_size >= MAIL_CACHE_COMPRESS_MIN_SIZE) { + /* too many continued rows, compress */ + cache->need_compress_file_seq = hdr->file_seq; + } + + /* see if we've reached the max. deleted space in file */ + max_del_space = hdr->used_file_size / 100 * + MAIL_CACHE_COMPRESS_PERCENTAGE; + if (hdr->deleted_space >= max_del_space && + hdr->used_file_size >= MAIL_CACHE_COMPRESS_MIN_SIZE) + cache->need_compress_file_seq = hdr->file_seq; +} + static bool mail_cache_verify_header(struct mail_cache *cache) { const struct mail_cache_header *hdr = cache->data; @@ -282,6 +305,8 @@ sizeof(cache->hdr_ro_copy)); } cache->hdr = &cache->hdr_ro_copy; + if (offset == 0) + mail_cache_update_need_compress(cache); return 0; } @@ -326,6 +351,8 @@ } cache->hdr = cache->data; + if (offset == 0) + mail_cache_update_need_compress(cache); return 0; } @@ -599,29 +626,6 @@ return mail_cache_lock_full(cache, FALSE, TRUE); } -static void mail_cache_update_need_compress(struct mail_cache *cache) -{ - const struct mail_cache_header *hdr = cache->hdr; - unsigned int cont_percentage; - uoff_t max_del_space; - - cont_percentage = hdr->continued_record_count * 100 / - (cache->index->map->rec_map->records_count == 0 ? 1 : - cache->index->map->rec_map->records_count); - if (cont_percentage >= MAIL_CACHE_COMPRESS_CONTINUED_PERCENTAGE && - hdr->used_file_size >= MAIL_CACHE_COMPRESS_MIN_SIZE) { - /* too many continued rows, compress */ - cache->need_compress_file_seq = hdr->file_seq; - } - - /* see if we've reached the max. deleted space in file */ - max_del_space = hdr->used_file_size / 100 * - MAIL_CACHE_COMPRESS_PERCENTAGE; - if (hdr->deleted_space >= max_del_space && - hdr->used_file_size >= MAIL_CACHE_COMPRESS_MIN_SIZE) - cache->need_compress_file_seq = hdr->file_seq; -} - int mail_cache_unlock(struct mail_cache *cache) { int ret = 0; diff -r 4296aa3fbb75 -r 9ed4ecd4a866 src/lib-index/mail-transaction-log-append.c --- a/src/lib-index/mail-transaction-log-append.c Sat Oct 18 17:07:42 2008 +0300 +++ b/src/lib-index/mail-transaction-log-append.c Sat Oct 18 20:26:35 2008 +0300 @@ -87,6 +87,8 @@ i_assert(file->buffer_offset + file->buffer->used == file->sync_offset); buffer_append_buf(file->buffer, ctx->output, 0, (size_t)-1); + buffer_write(file->buffer, file->sync_offset - file->buffer_offset, + &ctx->first_append_size, sizeof(uint32_t)); file->sync_offset = file->buffer_offset + file->buffer->used; return 0; } diff -r 4296aa3fbb75 -r 9ed4ecd4a866 src/lib-index/mail-transaction-log-file.c --- a/src/lib-index/mail-transaction-log-file.c Sat Oct 18 17:07:42 2008 +0300 +++ b/src/lib-index/mail-transaction-log-file.c Sat Oct 18 20:26:35 2008 +0300 @@ -1555,4 +1555,8 @@ file->filepath, "close()"); } file->fd = -1; + + i_free(file->filepath); + file->filepath = i_strconcat(file->log->index->filepath, + MAIL_TRANSACTION_LOG_SUFFIX, NULL); } diff -r 4296aa3fbb75 -r 9ed4ecd4a866 src/lib-index/mail-transaction-log-private.h --- a/src/lib-index/mail-transaction-log-private.h Sat Oct 18 17:07:42 2008 +0300 +++ b/src/lib-index/mail-transaction-log-private.h Sat Oct 18 20:26:35 2008 +0300 @@ -4,6 +4,8 @@ #include "file-dotlock.h" #include "mail-transaction-log.h" +#define MAIL_TRANSACTION_LOG_SUFFIX ".log" + /* Synchronization can take a while sometimes, especially when copying lots of mails. */ #define MAIL_TRANSCATION_LOG_LOCK_TIMEOUT (3*60) diff -r 4296aa3fbb75 -r 9ed4ecd4a866 src/lib-index/mail-transaction-log.c --- a/src/lib-index/mail-transaction-log.c Sat Oct 18 17:07:42 2008 +0300 +++ b/src/lib-index/mail-transaction-log.c Sat Oct 18 20:26:35 2008 +0300 @@ -14,7 +14,6 @@ #include #include -#define MAIL_TRANSACTION_LOG_SUFFIX ".log" #define LOG_NEW_DOTLOCK_SUFFIX ".newlock" static void diff -r 4296aa3fbb75 -r 9ed4ecd4a866 src/lib-storage/index/maildir/maildir-save.c --- a/src/lib-storage/index/maildir/maildir-save.c Sat Oct 18 17:07:42 2008 +0300 +++ b/src/lib-storage/index/maildir/maildir-save.c Sat Oct 18 20:26:35 2008 +0300 @@ -441,8 +441,10 @@ path = t_strconcat(ctx->tmpdir, "/", ctx->file_last->basename, NULL); if (o_stream_flush(ctx->output) < 0) { - mail_storage_set_critical(storage, - "o_stream_flush(%s) failed: %m", path); + if (!mail_storage_set_error_from_errno(storage)) { + mail_storage_set_critical(storage, + "o_stream_flush(%s) failed: %m", path); + } ctx->failed = TRUE; }