Mercurial > dovecot > core-2.2
changeset 1370:5f521a721671 HEAD
Use mtime to check changes in dovecot-uidlist file rather than inode changes
which aren't reliable.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 21 Apr 2003 16:42:00 +0300 |
parents | 945f857cb514 |
children | b73c2bdd12d0 |
files | src/lib-index/mail-index.h src/lib-index/maildir/maildir-sync.c src/lib-index/maildir/maildir-uidlist.c src/lib-index/maildir/maildir-uidlist.h |
diffstat | 4 files changed, 67 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index.h Thu Apr 17 17:20:47 2003 +0300 +++ b/src/lib-index/mail-index.h Mon Apr 21 16:42:00 2003 +0300 @@ -394,9 +394,7 @@ ino_t mbox_ino; /* last maildir sync: */ - dev_t uidlist_dev; - ino_t uidlist_ino; - + time_t uidlist_mtime; int maildir_lock_fd; int fd; /* opened index file */ @@ -445,7 +443,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, 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-sync.c Thu Apr 17 17:20:47 2003 +0300 +++ b/src/lib-index/maildir/maildir-sync.c Mon Apr 21 16:42:00 2003 +0300 @@ -197,6 +197,16 @@ return FALSE; } + if (uid_rec.uid > uid && + (hash_rec->action == MAILDIR_FILE_ACTION_UPDATE_FLAGS || + hash_rec->action == MAILDIR_FILE_ACTION_NONE)) { + /* it's UID has changed */ + hash_rec->action = MAILDIR_FILE_ACTION_UPDATE_CONTENT; + + /* make sure filename is not invalidated by expunge */ + hash_insert(files, p_strdup(pool, fname), hash_rec); + } + switch (hash_rec->action) { case MAILDIR_FILE_ACTION_EXPUNGE: if (!index->expunge(index, rec, seq, TRUE)) @@ -247,7 +257,14 @@ i_assert(hash_rec->action == MAILDIR_FILE_ACTION_NEW); /* make sure we set the same UID for it. */ - i_assert(index->header->next_uid <= uid_rec.uid); + if (index->header->next_uid > uid_rec.uid) { + index_set_corrupted(index, + "index.next_uid (%u) > " + "uid_rec.uid (%u)", + index->header->next_uid, + uid_rec.uid); + return FALSE; + } index->header->next_uid = uid_rec.uid; hash_rec->action = MAILDIR_FILE_ACTION_NONE; @@ -428,7 +445,7 @@ struct utimbuf ut; struct maildir_uidlist *uidlist; const char *uidlist_path, *cur_dir, *new_dir; - time_t index_mtime; + time_t index_mtime, uidlist_mtime; int cur_changed; *uidlist_r = uidlist = NULL; @@ -456,12 +473,13 @@ memset(&st, 0, sizeof(st)); cur_changed = TRUE; + uidlist_mtime = 0; } else { - /* FIXME: save device and inode into index header, so we don't + /* FIXME: save mtime into index header, so we don't have to read it every time mailbox is opened */ + uidlist_mtime = st.st_mtime; cur_changed = index_mtime != std.st_mtime || - st.st_ino != index->uidlist_ino || - !CMP_DEV_T(st.st_dev, index->uidlist_dev); + index->uidlist_mtime != uidlist_mtime; } if (new_dirp != NULL || cur_changed) { @@ -556,18 +574,12 @@ return TRUE; } - if (fstat(index->maildir_lock_fd, &st) < 0) { - return index_file_set_syscall_error(index, uidlist_path, - "fstat()"); - } - - if (!maildir_uidlist_rewrite(index)) + if (!maildir_uidlist_rewrite(index, &uidlist_mtime)) return FALSE; } /* uidlist file synced */ - index->uidlist_ino = st.st_ino; - index->uidlist_dev = st.st_dev; + index->uidlist_mtime = uidlist_mtime; /* update sync stamp */ index->file_sync_stamp = std.st_mtime;
--- a/src/lib-index/maildir/maildir-uidlist.c Thu Apr 17 17:20:47 2003 +0300 +++ b/src/lib-index/maildir/maildir-uidlist.c Mon Apr 21 16:42:00 2003 +0300 @@ -12,6 +12,7 @@ #include <stdio.h> #include <sys/stat.h> +#include <utime.h> /* how many seconds to wait before overriding uidlist.lock */ #define UIDLIST_LOCK_STALE_TIMEOUT (60*5) @@ -168,23 +169,14 @@ i_free(uidlist); } -int maildir_uidlist_rewrite(struct mail_index *index) +static int maildir_uidlist_rewrite_fd(struct mail_index *index, + const char *temp_path, time_t *mtime) { struct mail_index_record *rec; - const char *temp_path, *db_path, *p, *fname; + struct utimbuf ut; + const char *p, *fname; string_t *str; size_t len; - int failed = FALSE; - - i_assert(INDEX_IS_UIDLIST_LOCKED(index)); - - if (index->lock_type == MAIL_LOCK_UNLOCK) { - if (!index->set_lock(index, MAIL_LOCK_SHARED)) - return FALSE; - } - - temp_path = t_strconcat(index->mailbox_path, - "/" MAILDIR_UIDLIST_NAME ".lock", NULL); str = t_str_new(4096); str_printfa(str, "1 %u %u\n", @@ -194,7 +186,7 @@ while (rec != NULL) { fname = maildir_get_location(index, rec); if (fname == NULL) - break; + return FALSE; p = strchr(fname, ':'); len = p == NULL ? strlen(fname) : (size_t)(p-fname); @@ -205,7 +197,7 @@ str_data(str), str_len(str)) < 0) { index_file_set_syscall_error(index, temp_path, "write_full()"); - break; + return FALSE; } str_truncate(str, 0); } @@ -220,20 +212,47 @@ if (write_full(index->maildir_lock_fd, str_data(str), str_len(str)) < 0) { index_file_set_syscall_error(index, temp_path, "write_full()"); - failed = TRUE; + return FALSE; + } + + /* uidlist's mtime must grow every time */ + *mtime = ioloop_time > *mtime ? ioloop_time : *mtime + 1; + ut.actime = ioloop_time; + ut.modtime = *mtime; + if (utime(temp_path, &ut) < 0) + index_set_syscall_error(index, "utime()"); + + if (fsync(index->maildir_lock_fd) < 0) { + index_file_set_syscall_error(index, temp_path, "fsync()"); + return FALSE; } - if (fdatasync(index->maildir_lock_fd) < 0) { - index_file_set_syscall_error(index, temp_path, "fdatasync()"); - failed = TRUE; + return TRUE; +} + +int maildir_uidlist_rewrite(struct mail_index *index, time_t *mtime) +{ + const char *temp_path, *db_path; + int failed = FALSE; + + i_assert(INDEX_IS_UIDLIST_LOCKED(index)); + + if (index->lock_type == MAIL_LOCK_UNLOCK) { + if (!index->set_lock(index, MAIL_LOCK_SHARED)) + return FALSE; } + + temp_path = t_strconcat(index->mailbox_path, + "/" MAILDIR_UIDLIST_NAME ".lock", NULL); + + failed = !maildir_uidlist_rewrite_fd(index, temp_path, mtime); if (close(index->maildir_lock_fd) < 0) { index_file_set_syscall_error(index, temp_path, "close()"); failed = TRUE; } index->maildir_lock_fd = -1; - if (rec == NULL) { + if (!failed) { db_path = t_strconcat(index->mailbox_path, "/" MAILDIR_UIDLIST_NAME, NULL);
--- a/src/lib-index/maildir/maildir-uidlist.h Thu Apr 17 17:20:47 2003 +0300 +++ b/src/lib-index/maildir/maildir-uidlist.h Mon Apr 21 16:42:00 2003 +0300 @@ -22,7 +22,7 @@ int maildir_uidlist_try_lock(struct mail_index *index); void maildir_uidlist_unlock(struct mail_index *index); -int maildir_uidlist_rewrite(struct mail_index *index); +int maildir_uidlist_rewrite(struct mail_index *index, time_t *mtime); struct maildir_uidlist *maildir_uidlist_open(struct mail_index *index); void maildir_uidlist_close(struct maildir_uidlist *uidlist);