Mercurial > dovecot > original-hg > dovecot-1.2
comparison src/lib-storage/index/maildir/maildir-sync.c @ 3472:db29cc6754d5 HEAD
Store new/ directory's timestamp in sync_size header in index (kludgy..).
Fixed saving message into empty and non-synced mailboxes.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 12 Jul 2005 15:45:06 +0300 |
parents | 346a494c2feb |
children | e2fe8222449d |
comparison
equal
deleted
inserted
replaced
3471:138e242c53c9 | 3472:db29cc6754d5 |
---|---|
730 | 730 |
731 t_pop(); | 731 t_pop(); |
732 return ret < 0 ? -1 : (moves <= MAILDIR_RENAME_RESCAN_COUNT ? 0 : 1); | 732 return ret < 0 ? -1 : (moves <= MAILDIR_RENAME_RESCAN_COUNT ? 0 : 1); |
733 } | 733 } |
734 | 734 |
735 static int maildir_sync_quick_check(struct maildir_sync_context *ctx, | 735 static void |
736 int *new_changed_r, int *cur_changed_r) | 736 maildir_sync_update_from_header(struct maildir_mailbox *mbox) |
737 { | 737 { |
738 struct maildir_mailbox *mbox = ctx->mbox; | 738 uint64_t value; |
739 | |
740 /* FIXME: ugly, replace with extension header */ | |
741 value = mail_index_get_header(mbox->ibox.view)->sync_size; | |
742 mbox->last_new_mtime = value & 0xffffffff; | |
743 mbox->last_new_sync_time = value >> 32; | |
744 | |
745 mbox->last_cur_mtime = | |
746 mail_index_get_header(mbox->ibox.view)->sync_stamp; | |
747 } | |
748 | |
749 static int | |
750 maildir_sync_quick_check(struct maildir_mailbox *mbox, | |
751 const char *new_dir, const char *cur_dir, | |
752 int *new_changed_r, int *cur_changed_r) | |
753 { | |
739 struct stat st; | 754 struct stat st; |
740 time_t new_mtime, cur_mtime; | 755 time_t new_mtime, cur_mtime; |
741 | 756 |
742 *new_changed_r = *cur_changed_r = FALSE; | 757 *new_changed_r = *cur_changed_r = FALSE; |
743 | 758 |
744 if (stat(ctx->new_dir, &st) < 0) { | 759 if (stat(new_dir, &st) < 0) { |
745 mail_storage_set_critical(STORAGE(mbox->storage), | 760 mail_storage_set_critical(STORAGE(mbox->storage), |
746 "stat(%s) failed: %m", ctx->new_dir); | 761 "stat(%s) failed: %m", new_dir); |
747 return -1; | 762 return -1; |
748 } | 763 } |
749 new_mtime = st.st_mtime; | 764 new_mtime = st.st_mtime; |
750 | 765 |
751 if (stat(ctx->cur_dir, &st) < 0) { | 766 if (stat(cur_dir, &st) < 0) { |
752 mail_storage_set_critical(STORAGE(mbox->storage), | 767 mail_storage_set_critical(STORAGE(mbox->storage), |
753 "stat(%s) failed: %m", ctx->cur_dir); | 768 "stat(%s) failed: %m", cur_dir); |
754 return -1; | 769 return -1; |
755 } | 770 } |
756 cur_mtime = st.st_mtime; | 771 cur_mtime = st.st_mtime; |
757 | 772 |
758 /* cur stamp is kept in index, we don't have to sync if | 773 /* cur stamp is kept in index, we don't have to sync if |
759 someone else has done it and updated the index. */ | 774 someone else has done it and updated the index. |
760 mbox->last_cur_mtime = | 775 |
761 mail_index_get_header(mbox->ibox.view)->sync_stamp; | 776 FIXME: For now we're using sync_size field as the new/ dir's stamp. |
762 if (mbox->dirty_cur_time == 0 && cur_mtime != mbox->last_cur_mtime) { | 777 Pretty ugly.. */ |
778 maildir_sync_update_from_header(mbox); | |
779 if ((mbox->dirty_cur_time == 0 && cur_mtime != mbox->last_cur_mtime) || | |
780 (new_mtime != mbox->last_new_mtime)) { | |
763 /* check if the index has been updated.. */ | 781 /* check if the index has been updated.. */ |
764 if (mail_index_refresh(mbox->ibox.index) < 0) { | 782 if (mail_index_refresh(mbox->ibox.index) < 0) { |
765 mail_storage_set_index_error(&mbox->ibox); | 783 mail_storage_set_index_error(&mbox->ibox); |
766 return -1; | 784 return -1; |
767 } | 785 } |
768 | 786 |
769 mbox->last_cur_mtime = | 787 maildir_sync_update_from_header(mbox); |
770 mail_index_get_header(mbox->ibox.view)->sync_stamp; | |
771 } | 788 } |
772 | 789 |
773 if (new_mtime != mbox->last_new_mtime || | 790 if (new_mtime != mbox->last_new_mtime || |
774 new_mtime >= mbox->last_new_sync_time - MAILDIR_SYNC_SECS) { | 791 new_mtime >= mbox->last_new_sync_time - MAILDIR_SYNC_SECS) { |
775 *new_changed_r = TRUE; | 792 *new_changed_r = TRUE; |
834 const char *filename; | 851 const char *filename; |
835 enum mail_flags flags; | 852 enum mail_flags flags; |
836 array_t ARRAY_DEFINE(keywords, unsigned int); | 853 array_t ARRAY_DEFINE(keywords, unsigned int); |
837 array_t ARRAY_DEFINE(idx_keywords, unsigned int); | 854 array_t ARRAY_DEFINE(idx_keywords, unsigned int); |
838 uint32_t uid_validity, next_uid; | 855 uint32_t uid_validity, next_uid; |
856 uint64_t value; | |
857 time_t old_new_sync_time; | |
839 int ret = 0, full_rescan = FALSE; | 858 int ret = 0, full_rescan = FALSE; |
840 | 859 |
841 i_assert(maildir_uidlist_is_locked(sync_ctx->mbox->uidlist)); | 860 i_assert(maildir_uidlist_is_locked(sync_ctx->mbox->uidlist)); |
842 | 861 |
843 trans = mail_index_transaction_begin(view, FALSE, TRUE); | 862 trans = mail_index_transaction_begin(view, FALSE, TRUE); |
1055 mail_index_update_header(trans, | 1074 mail_index_update_header(trans, |
1056 offsetof(struct mail_index_header, sync_stamp), | 1075 offsetof(struct mail_index_header, sync_stamp), |
1057 &sync_stamp, sizeof(sync_stamp), TRUE); | 1076 &sync_stamp, sizeof(sync_stamp), TRUE); |
1058 } | 1077 } |
1059 | 1078 |
1079 /* FIXME: use a header extension instead of sync_size.. */ | |
1080 value = mbox->last_new_mtime; | |
1081 old_new_sync_time = hdr->sync_size >> 32; | |
1082 if (mbox->last_new_mtime >= old_new_sync_time - MAILDIR_SYNC_SECS) { | |
1083 value |= (uint64_t)mbox->last_new_sync_time << 32; | |
1084 } else { | |
1085 value |= (uint64_t)old_new_sync_time << 32; | |
1086 } | |
1087 if (value != hdr->sync_size) { | |
1088 uint64_t sync_stamp = mbox->last_new_mtime | | |
1089 ((uint64_t)mbox->last_new_sync_time << 32); | |
1090 | |
1091 mail_index_update_header(trans, | |
1092 offsetof(struct mail_index_header, sync_size), | |
1093 &sync_stamp, sizeof(sync_stamp), TRUE); | |
1094 } | |
1095 | |
1060 if (hdr->uid_validity == 0) { | 1096 if (hdr->uid_validity == 0) { |
1061 /* get the initial uidvalidity */ | 1097 /* get the initial uidvalidity */ |
1062 if (maildir_uidlist_update(mbox->uidlist) < 0) | 1098 if (maildir_uidlist_update(mbox->uidlist) < 0) |
1063 ret = -1; | 1099 ret = -1; |
1064 uid_validity = maildir_uidlist_get_uid_validity(mbox->uidlist); | 1100 uid_validity = maildir_uidlist_get_uid_validity(mbox->uidlist); |
1122 int full_rescan = FALSE; | 1158 int full_rescan = FALSE; |
1123 | 1159 |
1124 if (sync_last_commit) { | 1160 if (sync_last_commit) { |
1125 new_changed = cur_changed = FALSE; | 1161 new_changed = cur_changed = FALSE; |
1126 } else if (!forced) { | 1162 } else if (!forced) { |
1127 if (maildir_sync_quick_check(ctx, &new_changed, &cur_changed) < 0) | 1163 if (maildir_sync_quick_check(ctx->mbox, |
1164 ctx->new_dir, ctx->cur_dir, | |
1165 &new_changed, &cur_changed) < 0) | |
1128 return -1; | 1166 return -1; |
1129 | 1167 |
1130 if (!new_changed && !cur_changed) | 1168 if (!new_changed && !cur_changed) |
1131 return 0; | 1169 return 0; |
1132 } else { | 1170 } else { |
1284 } | 1322 } |
1285 } | 1323 } |
1286 | 1324 |
1287 return index_mailbox_sync_init(box, flags, ret < 0); | 1325 return index_mailbox_sync_init(box, flags, ret < 0); |
1288 } | 1326 } |
1327 | |
1328 int maildir_sync_is_synced(struct maildir_mailbox *mbox) | |
1329 { | |
1330 const char *new_dir, *cur_dir; | |
1331 int ret, new_changed, cur_changed; | |
1332 | |
1333 t_push(); | |
1334 new_dir = t_strconcat(mbox->path, "/new", NULL); | |
1335 cur_dir = t_strconcat(mbox->path, "/cur", NULL); | |
1336 | |
1337 ret = maildir_sync_quick_check(mbox, new_dir, cur_dir, | |
1338 &new_changed, &cur_changed); | |
1339 t_pop(); | |
1340 return ret < 0 ? -1 : (!new_changed && !cur_changed); | |
1341 } |