Mercurial > dovecot > original-hg > dovecot-1.2
changeset 1550:e1b2614c9e16 HEAD
Dirty maildir flags support works now.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 15 Jun 2003 05:20:52 +0300 |
parents | 3620bfe9cb05 |
children | 313779bde3ec |
files | src/lib-index/mail-index-open.c src/lib-index/mail-index.h src/lib-index/maildir/maildir-expunge.c src/lib-index/maildir/maildir-index.h src/lib-index/maildir/maildir-sync.c src/lib-index/maildir/maildir-update-flags.c src/lib-storage/index/maildir/maildir-storage.c |
diffstat | 7 files changed, 112 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index-open.c Sun Jun 15 05:20:12 2003 +0300 +++ b/src/lib-index/mail-index-open.c Sun Jun 15 05:20:52 2003 +0300 @@ -30,6 +30,9 @@ index->maildir_have_new = (hdr->flags & MAIL_INDEX_FLAG_MAILDIR_NEW) != 0; + if ((hdr->flags & MAIL_INDEX_FLAG_DIRTY_MESSAGES) != 0) + index->next_dirty_flush = ioloop_time; + /* update \Recent message counters */ if ((flags & MAIL_INDEX_OPEN_FLAG_UPDATE_RECENT) != 0 && hdr->last_nonrecent_uid != hdr->next_uid-1) {
--- a/src/lib-index/mail-index.h Sun Jun 15 05:20:12 2003 +0300 +++ b/src/lib-index/mail-index.h Sun Jun 15 05:20:52 2003 +0300 @@ -404,7 +404,7 @@ /* last maildir sync: */ time_t last_new_mtime, last_uidlist_mtime; - time_t maildir_cur_dirty; + time_t maildir_cur_dirty, next_dirty_flush; int maildir_lock_fd; pool_t new_filename_pool; struct hash_table *new_filenames; @@ -458,7 +458,7 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ - 0, 0, 0, 0 + 0, 0, 0, 0, 0 #endif /* defaults - same as above but prefixed with mail_index_. */
--- a/src/lib-index/maildir/maildir-expunge.c Sun Jun 15 05:20:12 2003 +0300 +++ b/src/lib-index/maildir/maildir-expunge.c Sun Jun 15 05:20:52 2003 +0300 @@ -17,6 +17,12 @@ if (*fname == NULL) return -1; + /* if we're in out-of-space condition, reset it since we'll probably + have enough space now. */ + index->maildir_keep_new = FALSE; + if (index->next_dirty_flush != 0) + index->next_dirty_flush = ioloop_time; + if ((rec->index_flags & INDEX_MAIL_FLAG_MAILDIR_NEW) != 0) { /* probably in new/ dir */ path = t_strconcat(index->mailbox_path, "/new/", *fname, NULL);
--- a/src/lib-index/maildir/maildir-index.h Sun Jun 15 05:20:12 2003 +0300 +++ b/src/lib-index/maildir/maildir-index.h Sun Jun 15 05:20:52 2003 +0300 @@ -8,6 +8,9 @@ /* ":2,DFRST" - leave the 2 extra for other clients' additions */ #define MAILDIR_LOCATION_EXTRA_SPACE 10 +/* How often to try to flush dirty flags. */ +#define MAILDIR_DIRTY_FLUSH_TIMEOUT (60*5) + struct mail_index * maildir_index_alloc(const char *maildir, const char *index_dir, const char *control_dir); @@ -35,6 +38,7 @@ int maildir_index_update_flags(struct mail_index *index, struct mail_index_record *rec, unsigned int seq, enum mail_flags flags, int external_change); +int maildir_try_flush_dirty_flags(struct mail_index *index, int force); struct istream *maildir_open_mail(struct mail_index *index, struct mail_index_record *rec,
--- a/src/lib-index/maildir/maildir-sync.c Sun Jun 15 05:20:12 2003 +0300 +++ b/src/lib-index/maildir/maildir-sync.c Sun Jun 15 05:20:52 2003 +0300 @@ -1098,6 +1098,9 @@ struct stat st; time_t new_mtime, cur_mtime; + if (!maildir_try_flush_dirty_flags(ctx->index, FALSE)) + return FALSE; + if (index->fd != -1) { /* FIXME: file_sync_stamp should be in index file's headers. it should also contain maildir_cur_dirty. */
--- a/src/lib-index/maildir/maildir-update-flags.c Sun Jun 15 05:20:12 2003 +0300 +++ b/src/lib-index/maildir/maildir-update-flags.c Sun Jun 15 05:20:52 2003 +0300 @@ -7,6 +7,66 @@ #include <stdio.h> +int maildir_try_flush_dirty_flags(struct mail_index *index, int force) +{ + struct mail_index_record *rec; + const char *old_fname, *old_path, *new_fname, *new_path; + int flag, dirty = FALSE; + + if (index->next_dirty_flush == 0 || + (ioloop_time < index->next_dirty_flush && !force)) + return TRUE; + + if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE)) + return FALSE; + + rec = index->lookup(index, 1); + while (rec != NULL) { + if ((rec->index_flags & INDEX_MAIL_FLAG_DIRTY) != 0) { + old_fname = maildir_get_location(index, rec); + if (old_fname == NULL) + return FALSE; + + flag = (rec->index_flags & + INDEX_MAIL_FLAG_MAILDIR_NEW) != 0; + old_path = t_strconcat(index->mailbox_path, + flag ? "/new/" : "/cur/", + old_fname, NULL); + + new_fname = maildir_filename_set_flags(old_fname, + rec->msg_flags); + new_path = t_strconcat(index->mailbox_path, + "/cur/", new_fname, NULL); + + if (strcmp(old_path, new_path) == 0 || + rename(old_path, new_path) == 0) + rec->index_flags &= ~INDEX_MAIL_FLAG_DIRTY; + else { + dirty = TRUE; + if (errno != ENOENT && errno != EACCES && + !ENOSPACE(errno)) { + index_set_error(index, + "rename(%s, %s) failed: %m", + old_path, new_path); + return FALSE; + } + } + } + + rec = index->next(index, rec); + } + + if (!dirty) { + index->header->flags &= ~MAIL_INDEX_FLAG_DIRTY_MESSAGES; + index->next_dirty_flush = 0; + } else { + index->next_dirty_flush = + ioloop_time + MAILDIR_DIRTY_FLUSH_TIMEOUT; + } + + return TRUE; +} + static int handle_error(struct mail_index *index, const char *path, const char *new_path) { @@ -76,6 +136,8 @@ "/cur/", new_fname, NULL); } + ret = 0; break; + if (strcmp(old_fname, new_fname) == 0) ret = 1; else { @@ -117,6 +179,10 @@ /* we couldn't actually rename() the file now. leave it's flags dirty so they get changed later. */ rec->index_flags |= INDEX_MAIL_FLAG_DIRTY; + index->header->flags |= MAIL_INDEX_FLAG_DIRTY_MESSAGES; + index->next_dirty_flush = + ioloop_time + MAILDIR_DIRTY_FLUSH_TIMEOUT; + *new_fname_r = NULL; } return TRUE; } @@ -127,7 +193,7 @@ { struct mail_index_update *update; const char *new_fname; - int ret; + int failed = FALSE; t_push(); if (!maildir_rename_mail(index, rec, flags, &new_fname)) { @@ -135,18 +201,18 @@ return FALSE; } - /* update the filename in index */ - update = index->update_begin(index, rec); - index->update_field(update, DATA_FIELD_LOCATION, new_fname, 0); + if (new_fname != NULL) { + /* update the filename in index */ + update = index->update_begin(index, rec); + index->update_field(update, DATA_FIELD_LOCATION, new_fname, 0); + if (!index->update_end(update)) + failed = TRUE; + } - if (!index->update_end(update)) - ret = FALSE; - else if (!mail_index_update_flags(index, rec, seq, flags, - external_change)) - ret = FALSE; - else - ret = TRUE; + if (!failed && !mail_index_update_flags(index, rec, seq, flags, + external_change)) + failed = TRUE; t_pop(); - return ret; + return !failed; }
--- a/src/lib-storage/index/maildir/maildir-storage.c Sun Jun 15 05:20:12 2003 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.c Sun Jun 15 05:20:52 2003 +0300 @@ -635,6 +635,21 @@ } } +static int maildir_storage_close(struct mailbox *box) +{ + struct index_mailbox *ibox = (struct index_mailbox *) box; + int failed = FALSE; + + index_storage_init_lock_notify(ibox); + if (!maildir_try_flush_dirty_flags(ibox->index, TRUE)) { + mail_storage_set_index_error(ibox); + failed = TRUE; + } + ibox->index->set_lock_notify_callback(ibox->index, NULL, NULL); + + return index_storage_close(box) && !failed; +} + static void maildir_storage_auto_sync(struct mailbox *box, enum mailbox_sync_type sync_type, unsigned int min_newmail_notify_interval) @@ -688,7 +703,7 @@ NULL, /* name */ NULL, /* storage */ - index_storage_close, + maildir_storage_close, index_storage_get_status, index_storage_sync, maildir_storage_auto_sync,