]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Several fixes and cleanups to cache file code, still badly broken
authorTimo Sirainen <tss@iki.fi>
Sun, 20 Jun 2004 09:13:14 +0000 (12:13 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 20 Jun 2004 09:13:14 +0000 (12:13 +0300)
--HG--
branch : HEAD

15 files changed:
src/lib-index/mail-cache-lookup.c
src/lib-index/mail-cache-private.h
src/lib-index/mail-cache-transaction.c
src/lib-index/mail-cache.c
src/lib-index/mail-cache.h
src/lib-index/mail-index-private.h
src/lib-index/mail-index-sync-update.c
src/lib-index/mail-index-sync.c
src/lib-index/mail-index-transaction-private.h
src/lib-index/mail-index-transaction.c
src/lib-index/mail-index-view.c
src/lib-index/mail-transaction-log.c
src/lib-index/mail-transaction-log.h
src/lib-index/mail-transaction-util.c
src/lib-index/mail-transaction-util.h

index a66f281a635b5242c7a5ac811170ac1172af9510..628f98b44dca0b3bb40acd19fc6b08a2a1b0a498 100644 (file)
@@ -5,6 +5,8 @@
 #include "byteorder.h"
 #include "mail-cache-private.h"
 
+#define CACHE_PREFETCH 1024
+
 const char *
 mail_cache_get_header_fields_str(struct mail_cache *cache, unsigned int idx)
 {
@@ -16,7 +18,7 @@ mail_cache_get_header_fields_str(struct mail_cache *cache, unsigned int idx)
        if (offset == 0)
                return NULL;
 
-       if (mail_cache_mmap_update(cache, offset, 1024) < 0)
+       if (mail_cache_mmap_update(cache, offset, CACHE_PREFETCH) < 0)
                return NULL;
 
        if (offset + sizeof(data_size) > cache->mmap_length) {
@@ -36,8 +38,10 @@ mail_cache_get_header_fields_str(struct mail_cache *cache, unsigned int idx)
                return NULL;
        }
 
-       if (mail_cache_mmap_update(cache, offset, data_size) < 0)
-               return NULL;
+       if (data_size + sizeof(data_size) > CACHE_PREFETCH) {
+               if (mail_cache_mmap_update(cache, offset, data_size) < 0)
+                       return NULL;
+       }
 
        if (offset + data_size > cache->mmap_length) {
                mail_cache_set_corrupted(cache, "Header %u points outside file",
@@ -109,7 +113,6 @@ struct mail_cache_record *
 mail_cache_get_record(struct mail_cache *cache, uint32_t offset,
                      int index_offset)
 {
-#define CACHE_PREFETCH 1024
        struct mail_cache_record *cache_rec;
        size_t size;
 
@@ -164,15 +167,23 @@ mail_cache_lookup(struct mail_cache_view *view, uint32_t seq,
                  enum mail_cache_field fields)
 {
        const struct mail_index_record *rec;
+       struct mail_index_map *map;
 
        if (mail_cache_transaction_autocommit(view, seq, fields) < 0)
                return NULL;
-       /* FIXME: check cache_offset in transaction
-          FIXME: if rec doesn't point to header record, the file seq may
-          be different and the offset wrong */
-       if (mail_index_lookup(view->view, seq, &rec) < 0)
+
+       if (view->cache->disabled)
+               return NULL;
+
+       /* FIXME: check cache_offset in transaction */
+       if (mail_index_lookup_full(view->view, seq, &map, &rec) < 0)
                return NULL;
 
+       if (map->hdr->cache_file_seq != view->cache->hdr->file_seq) {
+               /* FIXME: we should check if newer file is available? */
+               return NULL;
+       }
+
        return mail_cache_get_record(view->cache, rec->cache_offset, TRUE);
 }
 
index 50e93bbf217403f2d4456b490f2ba2ee91e7d0fc..5cdc4e3e23c280aa73d055a3182d85156265ec04 100644 (file)
@@ -58,7 +58,6 @@ struct mail_cache {
 
        void *mmap_base;
        size_t mmap_length;
-       uint32_t used_file_size;
 
        struct mail_cache_header *hdr;
 
@@ -74,6 +73,7 @@ struct mail_cache {
 
        unsigned int mmap_refresh:1;
        unsigned int silent:1;
+       unsigned int disabled:1;
 };
 
 struct mail_cache_view {
index 99fd8a7068d75a1ec784890c3c457644b617173f..badc7321707ab1518939cb4a11138b6a980b278d 100644 (file)
@@ -22,6 +22,7 @@ struct mail_cache_transaction_ctx {
        uint32_t first_seq, last_seq, prev_seq;
        enum mail_cache_field prev_fields;
        buffer_t *cache_marks;
+       uint32_t used_file_size;
 };
 
 static const unsigned char *null4[] = { 0, 0, 0, 0 };
@@ -44,6 +45,7 @@ int mail_cache_transaction_begin(struct mail_cache_view *view, int nonblock,
        ctx->view = view;
        ctx->trans = t;
        ctx->cache_data = buffer_create_dynamic(system_pool, 8192, (size_t)-1);
+       ctx->used_file_size = nbo_to_uint32(ctx->cache->hdr->used_file_size);
 
        view->cache->trans_ctx = ctx;
        *ctx_r = ctx;
@@ -141,7 +143,7 @@ static int commit_all_changes(struct mail_cache_transaction_ctx *ctx)
 
        if (cont * 100 / cache->index->hdr->messages_count >=
            COMPRESS_CONTINUED_PERCENTAGE &&
-           cache->used_file_size >= COMPRESS_MIN_SIZE) {
+           ctx->used_file_size >= COMPRESS_MIN_SIZE) {
                /* too many continued rows, compress */
                //FIXME:cache->index->set_flags |= MAIL_INDEX_HDR_FLAG_COMPRESS_CACHE;
        }
@@ -150,12 +152,14 @@ static int commit_all_changes(struct mail_cache_transaction_ctx *ctx)
        return 0;
 }
 
-static int mail_cache_grow(struct mail_cache *cache, uint32_t size)
+static int
+mail_cache_grow(struct mail_cache_transaction_ctx *ctx, uint32_t size)
 {
+        struct mail_cache *cache = ctx->cache;
        struct stat st;
        uoff_t grow_size, new_fsize;
 
-       new_fsize = cache->used_file_size + size;
+       new_fsize = ctx->used_file_size + size;
        grow_size = new_fsize / 100 * MAIL_CACHE_GROW_PERCENTAGE;
        if (grow_size < 16384)
                grow_size = 16384;
@@ -168,7 +172,7 @@ static int mail_cache_grow(struct mail_cache *cache, uint32_t size)
                return -1;
        }
 
-       if (cache->used_file_size + size <= (uoff_t)st.st_size) {
+       if (ctx->used_file_size + size <= (uoff_t)st.st_size) {
                /* no need to grow, just update mmap */
                if (mail_cache_mmap_update(cache, 0, 0) < 0)
                        return -1;
@@ -193,7 +197,7 @@ static uint32_t mail_cache_append_space(struct mail_cache_transaction_ctx *ctx,
 
        i_assert((size & 3) == 0);
 
-       offset = ctx->cache->used_file_size;
+       offset = ctx->used_file_size;
        if (offset >= 0x40000000) {
                mail_index_set_error(ctx->cache->index,
                                     "Cache file too large: %s",
@@ -202,11 +206,11 @@ static uint32_t mail_cache_append_space(struct mail_cache_transaction_ctx *ctx,
        }
 
        if (offset + size > ctx->cache->mmap_length) {
-               if (mail_cache_grow(ctx->cache, size) < 0)
+               if (mail_cache_grow(ctx, size) < 0)
                        return 0;
        }
 
-       ctx->cache->used_file_size += size;
+       ctx->used_file_size += size;
        return offset;
 }
 
@@ -215,6 +219,7 @@ static int mail_cache_write(struct mail_cache_transaction_ctx *ctx)
        struct mail_cache *cache = ctx->cache;
        struct mail_cache_record *cache_rec, *next;
        const struct mail_index_record *rec;
+       struct mail_index_map *map;
        uint32_t write_offset, update_offset;
        const void *buf;
        size_t size, buf_size;
@@ -226,10 +231,16 @@ static int mail_cache_write(struct mail_cache_transaction_ctx *ctx)
        ctx->cache_rec.size = uint32_to_nbo(size);
 
        // FIXME: check cache_offset in transaction
-       ret = mail_index_lookup(ctx->view->view, ctx->prev_seq, &rec);
+       ret = mail_index_lookup_full(ctx->view->view, ctx->prev_seq,
+                                    &map, &rec);
        if (ret < 0)
                return -1;
 
+       if (map->hdr->cache_file_seq != cache->hdr->file_seq) {
+               /* FIXME: we should check if newer file is available? */
+               ret = 0;
+       }
+
        if (ret == 0) {
                /* it's been expunged already, do nothing */
        } else {
@@ -275,13 +286,17 @@ int mail_cache_transaction_commit(struct mail_cache_transaction_ctx *ctx)
 {
        int ret = 0;
 
+       if (ctx->cache->disabled) {
+               mail_cache_transaction_flush(ctx);
+               return 0;
+       }
+
        if (ctx->prev_seq != 0) {
                if (mail_cache_write(ctx) < 0)
                        return -1;
        }
 
-       ctx->cache->hdr->used_file_size =
-               uint32_to_nbo(ctx->cache->used_file_size);
+       ctx->cache->hdr->used_file_size = uint32_to_nbo(ctx->used_file_size);
 
        if (commit_all_changes(ctx) < 0)
                ret = -1;
@@ -303,7 +318,7 @@ void mail_cache_transaction_rollback(struct mail_cache_transaction_ctx *ctx)
 
        /* no need to actually modify the file - we just didn't update
           used_file_size */
-       cache->used_file_size = nbo_to_uint32(cache->hdr->used_file_size);
+       ctx->used_file_size = nbo_to_uint32(cache->hdr->used_file_size);
 
        /* make sure we don't cache the headers */
        for (i = 0; i < ctx->next_unused_header_lowwater; i++) {
@@ -532,9 +547,9 @@ int mail_cache_delete(struct mail_cache_transaction_ctx *ctx, uint32_t seq)
        } while (cache_rec != NULL);
 
        /* see if we've reached the max. deleted space in file */
-       max_del_space = cache->used_file_size / 100 * COMPRESS_PERCENTAGE;
+       max_del_space = ctx->used_file_size / 100 * COMPRESS_PERCENTAGE;
        if (deleted_space >= max_del_space &&
-           cache->used_file_size >= COMPRESS_MIN_SIZE) {
+           ctx->used_file_size >= COMPRESS_MIN_SIZE) {
                //FIXME:cache->index->set_flags |= MAIL_INDEX_HDR_FLAG_COMPRESS_CACHE;
        }
 
index 58a631ad48e3b0f30494c9a7748c1317ff8e9cf6..9c05007dd446a0b064889dd2a5514e3a312787ba 100644 (file)
@@ -136,6 +136,7 @@ static int mail_cache_file_reopen(struct mail_cache *cache)
 static int mmap_verify_header(struct mail_cache *cache)
 {
        struct mail_cache_header *hdr;
+       uint32_t used_file_size;
 
        /* check that the header is still ok */
        if (cache->mmap_length < sizeof(struct mail_cache_header)) {
@@ -156,28 +157,23 @@ static int mmap_verify_header(struct mail_cache *cache)
                return 1;
        }
 
-       cache->used_file_size = nbo_to_uint32(hdr->used_file_size);
-
        /* only check the header if we're locked */
        if (cache->locks == 0)
                return 1;
 
-       if (cache->used_file_size < sizeof(struct mail_cache_header)) {
+       used_file_size = nbo_to_uint32(hdr->used_file_size);
+       if (used_file_size < sizeof(struct mail_cache_header)) {
                mail_cache_set_corrupted(cache, "used_file_size too small");
                return 0;
        }
-       if ((cache->used_file_size % sizeof(uint32_t)) != 0) {
+       if ((used_file_size % sizeof(uint32_t)) != 0) {
                mail_cache_set_corrupted(cache, "used_file_size not aligned");
                return 0;
        }
 
-       if (cache->used_file_size > cache->mmap_length) {
-               /* maybe a crash truncated the file - just fix it */
-               hdr->used_file_size = uint32_to_nbo(cache->mmap_length & ~3);
-               if (msync(cache->mmap_base, sizeof(*hdr), MS_SYNC) < 0) {
-                       mail_cache_set_syscall_error(cache, "msync()");
-                       return -1;
-               }
+       if (used_file_size > cache->mmap_length) {
+               mail_cache_set_corrupted(cache, "used_file_size too large");
+               return 0;
        }
        return 1;
 }
@@ -354,10 +350,6 @@ static int mail_cache_open_or_create_file(struct mail_cache *cache,
                return -1;
        }
 
-       if (cache->index->hdr->cache_file_seq != 0) {
-               // FIXME: clear cache_offsets in index file
-       }
-
        mail_cache_file_close(cache);
        cache->fd = dup(fd);
 
@@ -388,12 +380,15 @@ struct mail_cache *mail_cache_open_or_create(struct mail_index *index)
        cache->fd = -1;
         cache->split_header_pool = pool_alloconly_create("Headers", 512);
 
-       /* we'll do anon-mmaping only if initially requested. if we fail
-          because of out of disk space, we'll just let the main index code
-          know it and fail. */
        if (mail_cache_open_or_create_file(cache, &hdr) < 0) {
-               mail_cache_free(cache);
-               return NULL;
+               /* failed for some reason - doesn't really matter,
+                  just disable caching. */
+               mail_cache_file_close(cache);
+
+               i_free(cache->filepath);
+               cache->filepath = i_strdup_printf("(disabled cache for %s)",
+                                                 index->filepath);
+               cache->disabled = TRUE;
        }
 
        return cache;
@@ -423,15 +418,10 @@ int mail_cache_reset(struct mail_cache *cache)
        struct mail_cache_header hdr;
        int fd;
 
-       i_assert(cache->index->lock_type == F_WRLCK);
-
        memset(&hdr, 0, sizeof(hdr));
        hdr.indexid = cache->index->indexid;
        hdr.file_seq = cache->index->hdr->cache_file_seq + 1;
        hdr.used_file_size = uint32_to_nbo(sizeof(hdr));
-       cache->used_file_size = sizeof(hdr);
-
-       // FIXME: update cache_offsets in index
 
        fd = file_dotlock_open(cache->filepath, NULL, NULL,
                               MAIL_CACHE_LOCK_TIMEOUT,
@@ -491,18 +481,11 @@ int mail_cache_lock(struct mail_cache *cache, int nonblock)
                        (void)mail_cache_unlock(cache);
                        return -1;
                }
-#if 0 // FIXME
+
                if (cache->hdr->file_seq != cache->index->hdr->cache_file_seq) {
-                       /* we have the cache file locked and sync_id still
-                          doesn't match. it means we crashed between updating
-                          cache file and updating sync_id in index header.
-                          just update the sync_ids so they match. */
-                       i_warning("Updating broken sync_id in cache file %s",
-                                 cache->filepath);
-                       cache->hdr->file_seq =
-                               cache->index->hdr->cache_file_seq;
+                       mail_cache_unlock(cache);
+                       return 0;
                }
-#endif
        }
        return ret;
 }
@@ -525,6 +508,18 @@ int mail_cache_is_locked(struct mail_cache *cache)
        return cache->locks > 0;
 }
 
+int mail_cache_need_reset(struct mail_cache *cache, uint32_t *new_file_seq_r)
+{
+       if (cache->hdr->file_seq != cache->index->hdr->cache_file_seq) {
+               if (mail_cache_lock(cache, TRUE) == 0) {
+                       *new_file_seq_r = cache->index->hdr->cache_file_seq;
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
 struct mail_cache_view *
 mail_cache_view_open(struct mail_cache *cache, struct mail_index_view *iview)
 {
index aa4823db722dc3d9da1fe672632e3a69d45bec57..5317883b0d9d7ae3722702e3b7abee38eae2d586 100644 (file)
@@ -81,14 +81,17 @@ int mail_cache_compress(struct mail_cache *cache);
 /* Reset the cache file, clearing all data. */
 int mail_cache_reset(struct mail_cache *cache);
 
-/* Explicitly lock the cache file. Returns 1 if ok, 0 if nonblock is TRUE and
-   we couldn't immediately get a lock, or -1 if error. */
+/* Explicitly lock the cache file. Returns -1 if error, 1 if ok,
+   0 if we couldn't lock (nonblock = TRUE or index file needs a cache reset) */
 int mail_cache_lock(struct mail_cache *cache, int nonblock);
 int mail_cache_unlock(struct mail_cache *cache);
 
 /* Returns TRUE if cache file is locked. */
 int mail_cache_is_locked(struct mail_cache *cache);
 
+/* Returns TRUE if index's cache_file_seq doesn't match the latest cache file */
+int mail_cache_need_reset(struct mail_cache *cache, uint32_t *new_file_seq_r);
+
 struct mail_cache_view *
 mail_cache_view_open(struct mail_cache *cache, struct mail_index_view *iview);
 void mail_cache_view_close(struct mail_cache_view *view);
index 23d410ca6136ee6e97427c0cb3480b75e12209d0..ffd5a0b415165bc487f02938799190a6265043d1 100644 (file)
@@ -124,6 +124,12 @@ void mail_index_unmap(struct mail_index *index, struct mail_index_map *map);
 struct mail_index_map *
 mail_index_map_to_memory(struct mail_index *index, struct mail_index_map *map);
 
+int mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
+                          struct mail_index_map **map_r,
+                          const struct mail_index_record **rec_r);
+
+void mail_index_reset_cache(struct mail_index_transaction *t,
+                           uint32_t new_file_seq);
 void mail_index_update_cache(struct mail_index_transaction *t,
                             uint32_t seq, uint32_t offset);
 
index fc65434937af09612c9b9e6709893a98ba4cb026..48fabe351a067dde6b1060c854b761f98b628c03 100644 (file)
@@ -178,6 +178,19 @@ static int sync_flag_update(const struct mail_transaction_flag_update *u,
        return 1;
 }
 
+static int sync_cache_reset(const struct mail_transaction_cache_reset *u,
+                           void *context)
+{
+       struct mail_index_view *view = context;
+       uint32_t i;
+
+       view->map->hdr_copy.cache_file_seq = u->new_file_seq;
+
+       for (i = 0; i < view->messages_count; i++)
+               MAIL_INDEX_MAP_IDX(view->index, view->map, i)->cache_offset = 0;
+       return 1;
+}
+
 static int sync_cache_update(const struct mail_transaction_cache_update *u,
                             void *context)
 {
@@ -374,5 +387,6 @@ int mail_index_sync_update_index(struct mail_index_sync_ctx *sync_ctx)
 
 struct mail_transaction_map_functions mail_index_map_sync_funcs = {
        sync_expunge, sync_append, sync_flag_update,
-       sync_cache_update, sync_header_update, sync_extra_rec_update
+       sync_cache_reset, sync_cache_update, sync_header_update,
+       sync_extra_rec_update
 };
index 4848a12db2c2c915eaf2145e9d472104000c8189..b21ba2a7907c9bfa446570b8f9249455561ef709 100644 (file)
@@ -125,7 +125,7 @@ int mail_index_sync_begin(struct mail_index *index,
                          uint32_t log_file_seq, uoff_t log_file_offset)
 {
        struct mail_index_sync_ctx *ctx;
-       uint32_t seq;
+       uint32_t seq, new_file_seq;
        uoff_t offset;
        unsigned int lock_id;
 
@@ -178,6 +178,17 @@ int mail_index_sync_begin(struct mail_index *index,
                return -1;
        }
 
+       /* check here if cache file's sequence has changed unexpectedly */
+       if (mail_cache_need_reset(index->cache, &new_file_seq)) {
+               uint32_t seq;
+               uoff_t offset;
+               struct mail_index_transaction *t;
+
+               t = mail_index_transaction_begin(ctx->view, FALSE);
+               mail_index_reset_cache(t, new_file_seq);
+                mail_index_transaction_commit(t, &seq, &offset);
+       }
+
        *ctx_r = ctx;
        *view_r = ctx->view;
        return 1;
index f6be129e190adc103ca0596d3f57d9adeea58209..d0efb4e31c837357a32eab8497de12eb682d79a5 100644 (file)
@@ -15,6 +15,7 @@ struct mail_index_transaction {
 
        unsigned char hdr_change[sizeof(struct mail_index_header)];
        unsigned char hdr_mask[sizeof(struct mail_index_header)];
+       uint32_t new_cache_file_seq;
 
        buffer_t *extra_rec_updates[MAIL_INDEX_MAX_EXTRA_RECORDS];
 
index 0c627cf9fd22e2dc656a5d33565fa3feb4a48335..b4da4bd4780a545388c4b9ca87d7a4df320546bc 100644 (file)
@@ -474,6 +474,12 @@ static void mail_index_update_seq_buffer(buffer_t **buffer, uint32_t seq,
        memcpy(seq_p+1, record, record_size);
 }
 
+void mail_index_reset_cache(struct mail_index_transaction *t,
+                           uint32_t new_file_seq)
+{
+       t->new_cache_file_seq = new_file_seq;
+}
+
 void mail_index_update_cache(struct mail_index_transaction *t,
                             uint32_t seq, uint32_t offset)
 {
index 3f6fa93b5baacacc376cbd9890074910f9139159..9d1fdd441dce3bad038b61872d764cb0dcc22b4e 100644 (file)
@@ -160,9 +160,9 @@ int mail_index_get_header(struct mail_index_view *view,
        return 0;
 }
 
-static int mail_index_lookup_int(struct mail_index_view *view, uint32_t seq,
-                                struct mail_index_map **map_r,
-                                const struct mail_index_record **rec_r)
+int mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
+                          struct mail_index_map **map_r,
+                          const struct mail_index_record **rec_r)
 {
        struct mail_index_map *map;
        const struct mail_index_record *rec, *n_rec;
@@ -218,7 +218,7 @@ int mail_index_lookup(struct mail_index_view *view, uint32_t seq,
 {
        struct mail_index_map *map;
 
-       return mail_index_lookup_int(view, seq, &map, rec_r);
+       return mail_index_lookup_full(view, seq, &map, rec_r);
 }
 
 int mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
@@ -242,7 +242,7 @@ int mail_index_lookup_extra(struct mail_index_view *view, uint32_t seq,
        uint32_t offset;
        int ret;
 
-       if ((ret = mail_index_lookup_int(view, seq, &map, &rec)) < 0)
+       if ((ret = mail_index_lookup_full(view, seq, &map, &rec)) < 0)
                return -1;
 
        if (rec == NULL) {
index aafe37eda0fa3e14053e51744866eea2a8b09bbe..564c98daa3d73ca4c35a02fb35905cb6c4bce99e 100644 (file)
@@ -982,6 +982,19 @@ static int log_append_buffer(struct mail_transaction_log_file *file,
        return 0;
 }
 
+static const buffer_t *get_cache_reset_buf(struct mail_index_transaction *t)
+{
+       struct mail_transaction_cache_reset u;
+       buffer_t *buf;
+
+       memset(&u, 0, sizeof(u));
+       u.new_file_seq = t->new_cache_file_seq;
+
+       buf = buffer_create_static(pool_datastack_create(), sizeof(u));
+       buffer_append(buf, &u, sizeof(u));
+       return buf;
+}
+
 static const buffer_t *
 log_get_hdr_update_buffer(struct mail_index_transaction *t)
 {
@@ -1089,6 +1102,11 @@ int mail_transaction_log_append(struct mail_index_transaction *t,
                                        MAIL_TRANSACTION_FLAG_UPDATE,
                                        view->external);
        }
+       if (t->new_cache_file_seq != 0) {
+               ret = log_append_buffer(file, get_cache_reset_buf(t), NULL,
+                                       MAIL_TRANSACTION_CACHE_RESET,
+                                       view->external);
+       }
        if (t->cache_updates != NULL && ret == 0) {
                ret = log_append_buffer(file, t->cache_updates, NULL,
                                        MAIL_TRANSACTION_CACHE_UPDATE,
index cb6745bde97c3337069fbdb16b5e61cd58fd8a47..572f7a7ee5977a8a7eb255e7111f3da9950ebc24 100644 (file)
@@ -17,9 +17,10 @@ enum mail_transaction_type {
        MAIL_TRANSACTION_EXPUNGE                = 0x00000001,
        MAIL_TRANSACTION_APPEND                 = 0x00000002,
        MAIL_TRANSACTION_FLAG_UPDATE            = 0x00000004,
-       MAIL_TRANSACTION_CACHE_UPDATE           = 0x00000008,
-       MAIL_TRANSACTION_HEADER_UPDATE          = 0x00000010,
-       MAIL_TRANSACTION_EXTRA_REC_UPDATE       = 0x00000020,
+       MAIL_TRANSACTION_CACHE_RESET            = 0x00000008,
+       MAIL_TRANSACTION_CACHE_UPDATE           = 0x00000010,
+       MAIL_TRANSACTION_HEADER_UPDATE          = 0x00000020,
+       MAIL_TRANSACTION_EXTRA_REC_UPDATE       = 0x00000040,
 
        MAIL_TRANSACTION_TYPE_MASK              = 0x0000ffff,
 
@@ -50,6 +51,10 @@ struct mail_transaction_flag_update {
        keywords_mask_t remove_keywords;
 };
 
+struct mail_transaction_cache_reset {
+       uint32_t new_file_seq;
+};
+
 struct mail_transaction_cache_update {
        uint32_t uid;
        uint32_t cache_offset;
index 276507c51f1348f2d23769d581fa29007696ccfe..cb102b29c23b4b107957db55788662ee5cd05892 100644 (file)
@@ -20,6 +20,8 @@ const struct mail_transaction_type_map mail_transaction_type_map[] = {
          sizeof(struct mail_transaction_expunge) },
        { MAIL_TRANSACTION_FLAG_UPDATE, MAIL_INDEX_SYNC_TYPE_FLAGS,
          sizeof(struct mail_transaction_flag_update) },
+       { MAIL_TRANSACTION_CACHE_RESET, 0,
+         sizeof(struct mail_transaction_cache_reset) },
        { MAIL_TRANSACTION_CACHE_UPDATE, 0,
          sizeof(struct mail_transaction_cache_update) },
        { MAIL_TRANSACTION_HEADER_UPDATE, 0, 1 }, /* variable size, use 1 */
@@ -107,6 +109,13 @@ int mail_transaction_map(struct mail_index *index,
                }
                break;
        }
+       case MAIL_TRANSACTION_CACHE_RESET: {
+               const struct mail_transaction_cache_reset *u = data;
+
+               if (map->cache_reset != NULL)
+                       ret = map->cache_reset(u, context);
+               break;
+       }
        case MAIL_TRANSACTION_CACHE_UPDATE: {
                const struct mail_transaction_cache_update *rec, *end;
 
index 8bf6dd83bec87d31df16bf21fcb862313bb9a303..45303fbd1dfcf5236fb79c37515e7204750c7de9 100644 (file)
@@ -13,6 +13,8 @@ struct mail_transaction_map_functions {
        int (*append)(const struct mail_index_record *rec, void *context);
        int (*flag_update)(const struct mail_transaction_flag_update *u,
                           void *context);
+       int (*cache_reset)(const struct mail_transaction_cache_reset *u,
+                           void *context);
        int (*cache_update)(const struct mail_transaction_cache_update *u,
                            void *context);
        int (*header_update)(const struct mail_transaction_header_update *u,