[dovecot-cvs] dovecot/src/lib-index/maildir maildir-sync.c,1.36,1.37 maildir-uidlist.c,1.1,1.2 maildir-uidlist.h,1.1,1.2
cras at procontrol.fi
cras at procontrol.fi
Mon Apr 21 17:42:02 EEST 2003
Update of /home/cvs/dovecot/src/lib-index/maildir
In directory danu:/tmp/cvs-serv12707/lib-index/maildir
Modified Files:
maildir-sync.c maildir-uidlist.c maildir-uidlist.h
Log Message:
Use mtime to check changes in dovecot-uidlist file rather than inode changes
which aren't reliable.
Index: maildir-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-sync.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- maildir-sync.c 16 Apr 2003 15:13:24 -0000 1.36
+++ maildir-sync.c 21 Apr 2003 13:42:00 -0000 1.37
@@ -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;
Index: maildir-uidlist.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-uidlist.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- maildir-uidlist.c 9 Apr 2003 20:10:01 -0000 1.1
+++ maildir-uidlist.c 21 Apr 2003 13:42:00 -0000 1.2
@@ -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;
}
- if (fdatasync(index->maildir_lock_fd) < 0) {
- index_file_set_syscall_error(index, temp_path, "fdatasync()");
- failed = TRUE;
+ /* 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;
}
+
+ 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);
Index: maildir-uidlist.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/maildir/maildir-uidlist.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- maildir-uidlist.h 9 Apr 2003 20:10:01 -0000 1.1
+++ maildir-uidlist.h 21 Apr 2003 13:42:00 -0000 1.2
@@ -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);
More information about the dovecot-cvs
mailing list