]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Fixes to handling "out of disk space/quota" write failures.
authorTimo Sirainen <tss@iki.fi>
Sat, 18 Oct 2008 17:26:35 +0000 (20:26 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 18 Oct 2008 17:26:35 +0000 (20:26 +0300)
--HG--
branch : HEAD

src/lib-index/mail-cache-compress.c
src/lib-index/mail-cache.c
src/lib-index/mail-transaction-log-append.c
src/lib-index/mail-transaction-log-file.c
src/lib-index/mail-transaction-log-private.h
src/lib-index/mail-transaction-log.c
src/lib-storage/index/maildir/maildir-save.c

index 3ed982b226c85549762a13c2a5052880cbc80a29..03f4f5ebb43447205c5a7c22a3a5337bb7055fbf 100644 (file)
@@ -394,6 +394,10 @@ static int mail_cache_compress_locked(struct mail_cache *cache,
        }
 
        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;
        }
index 6eb9ff1ff7f3d8bfcf950dc2fe43f81f25606685..24663fbe38b6e482ae386d3b3b53eeb4116ef41d 100644 (file)
@@ -188,6 +188,29 @@ int mail_cache_reopen(struct mail_cache *cache)
        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 @@ int mail_cache_map(struct mail_cache *cache, size_t offset, size_t size)
                               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 @@ int mail_cache_map(struct mail_cache *cache, size_t offset, size_t size)
        }
 
        cache->hdr = cache->data;
+       if (offset == 0)
+               mail_cache_update_need_compress(cache);
        return 0;
 }
 
@@ -599,29 +626,6 @@ int mail_cache_try_lock(struct mail_cache *cache)
        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;
index a10499edac7867bf637f43eb320272bc899cfa92..2758e2072b4fbd3fd4491603a40cec0d60d2a316 100644 (file)
@@ -87,6 +87,8 @@ static int log_buffer_move_to_memory(struct log_append_context *ctx)
        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;
 }
index d9f85def2db23ba320d01ad2622e4de201e85c93..1b93a37cfbb5dcc7b910f3e6e78b5140b270dfcb 100644 (file)
@@ -1555,4 +1555,8 @@ void mail_transaction_log_file_move_to_memory(struct mail_transaction_log_file
                                                  file->filepath, "close()");
        }
        file->fd = -1;
+
+       i_free(file->filepath);
+       file->filepath = i_strconcat(file->log->index->filepath,
+                                    MAIL_TRANSACTION_LOG_SUFFIX, NULL);
 }
index 46c1fc5b8c35ddfa200bc6bded533bca99af4b47..a50f7c92bee03a616879d71c88eae88887b8607b 100644 (file)
@@ -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)
index 2032d0124ffa5b50faa3e972b7d4ee6a5530f179..d75a4485776af4349cce946046f7f874ea8f574a 100644 (file)
@@ -14,7 +14,6 @@
 #include <stdio.h>
 #include <sys/stat.h>
 
-#define MAIL_TRANSACTION_LOG_SUFFIX ".log"
 #define LOG_NEW_DOTLOCK_SUFFIX ".newlock"
 
 static void
index 04d7adf891226bfa2a55ff11b851db070f851540..3418cf5455f4bc779263c57a9f3ba3d7d3470a03 100644 (file)
@@ -441,8 +441,10 @@ static int maildir_save_finish_real(struct mail_save_context *_ctx)
 
        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;
        }