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 }