comparison src/lib-storage/index/maildir/maildir-sync.c @ 5214:4e9d345df846 HEAD

When syncing huge maildirs check once in a while if we need to update dovecot-uidlist.lock so that another process won't decide that it's stale and overwrite it. Check more often when moving mails from new/ to cur/.
author Timo Sirainen <tss@iki.fi>
date Tue, 06 Mar 2007 17:39:04 +0200
parents e0b83da1e12f
children 1f737b6e911b
comparison
equal deleted inserted replaced
5213:2969edccb9b0 5214:4e9d345df846
194 go and rescan the new/ directory again from beginning until no files are 194 go and rescan the new/ directory again from beginning until no files are
195 left. This value is just an optimization to avoid checking the directory 195 left. This value is just an optimization to avoid checking the directory
196 twice unneededly. usually only NFS is the problem case. 1 is the safest 196 twice unneededly. usually only NFS is the problem case. 1 is the safest
197 bet here, but I guess 5 will do just fine too. */ 197 bet here, but I guess 5 will do just fine too. */
198 #define MAILDIR_RENAME_RESCAN_COUNT 5 198 #define MAILDIR_RENAME_RESCAN_COUNT 5
199
200 /* After moving 100 mails from new/ to cur/, check if we need to touch the
201 uidlist lock. */
202 #define MAILDIR_SLOW_MOVE_COUNT 100
203 /* readdir() should be pretty fast to do, but check anyway every 10000 mails
204 to see if we need to touch the uidlist lock. */
205 #define MAILDIR_SLOW_CHECK_COUNT 10000
199 206
200 struct maildir_sync_context { 207 struct maildir_sync_context {
201 struct maildir_mailbox *mbox; 208 struct maildir_mailbox *mbox;
202 const char *new_dir, *cur_dir; 209 const char *new_dir, *cur_dir;
203 bool partial; 210 bool partial;
683 const char *dir; 690 const char *dir;
684 DIR *dirp; 691 DIR *dirp;
685 string_t *src, *dest; 692 string_t *src, *dest;
686 struct dirent *dp; 693 struct dirent *dp;
687 enum maildir_uidlist_rec_flag flags; 694 enum maildir_uidlist_rec_flag flags;
688 unsigned int moves = 0; 695 time_t last_touch;
696 unsigned int moves = 0, count = 0;
689 int ret = 1; 697 int ret = 1;
690 bool move_new; 698 bool move_new, check_touch;
699
700 last_touch = ioloop_time;
691 701
692 dir = new_dir ? ctx->new_dir : ctx->cur_dir; 702 dir = new_dir ? ctx->new_dir : ctx->cur_dir;
693 dirp = opendir(dir); 703 dirp = opendir(dir);
694 if (dirp == NULL) { 704 if (dirp == NULL) {
695 mail_storage_set_critical(storage, 705 mail_storage_set_critical(storage,
719 continue; 729 continue;
720 } 730 }
721 if (ret < 0) 731 if (ret < 0)
722 break; 732 break;
723 733
734 check_touch = FALSE;
724 flags = 0; 735 flags = 0;
725 if (move_new) { 736 if (move_new) {
726 str_truncate(src, 0); 737 str_truncate(src, 0);
727 str_truncate(dest, 0); 738 str_truncate(dest, 0);
728 str_printfa(src, "%s/%s", ctx->new_dir, dp->d_name); 739 str_printfa(src, "%s/%s", ctx->new_dir, dp->d_name);
751 MAILDIR_UIDLIST_REC_FLAG_RECENT; 762 MAILDIR_UIDLIST_REC_FLAG_RECENT;
752 mail_storage_set_critical(storage, 763 mail_storage_set_critical(storage,
753 "rename(%s, %s) failed: %m", 764 "rename(%s, %s) failed: %m",
754 str_c(src), str_c(dest)); 765 str_c(src), str_c(dest));
755 } 766 }
767 if ((moves % MAILDIR_SLOW_MOVE_COUNT) == 0)
768 check_touch = TRUE;
756 } else if (new_dir) { 769 } else if (new_dir) {
757 flags |= MAILDIR_UIDLIST_REC_FLAG_NEW_DIR | 770 flags |= MAILDIR_UIDLIST_REC_FLAG_NEW_DIR |
758 MAILDIR_UIDLIST_REC_FLAG_RECENT; 771 MAILDIR_UIDLIST_REC_FLAG_RECENT;
772 }
773
774 count++;
775 if (check_touch || (count % MAILDIR_SLOW_CHECK_COUNT) == 0) {
776 time_t now = time(NULL);
777
778 if (now - last_touch > MAILDIR_LOCK_TOUCH_SECS) {
779 (void)maildir_uidlist_lock_touch(
780 ctx->mbox->uidlist);
781 last_touch = now;
782 }
759 } 783 }
760 784
761 ret = maildir_uidlist_sync_next(ctx->uidlist_sync_ctx, 785 ret = maildir_uidlist_sync_next(ctx->uidlist_sync_ctx,
762 dp->d_name, flags); 786 dp->d_name, flags);
763 if (ret <= 0) { 787 if (ret <= 0) {