Mercurial > dovecot > original-hg > dovecot-1.2
changeset 3435:6f7ce690358e HEAD
If we have rename()d more than 5 files from new/ to cur/, rescan the
directory again to make sure we didn't skip any files.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 16 Jun 2005 22:46:18 +0300 |
parents | 3a98900070ee |
children | 3c51658d6846 |
files | src/lib-storage/index/maildir/maildir-sync.c |
diffstat | 1 files changed, 20 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/maildir/maildir-sync.c Thu Jun 16 22:26:46 2005 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync.c Thu Jun 16 22:46:18 2005 +0300 @@ -188,6 +188,14 @@ #define MAILDIR_FILENAME_FLAG_FOUND 128 +/* When rename()ing many files from new/ to cur/, it's possible that next + readdir() skips some files. we don't of course wish to lose them, so we + go and rescan the new/ directory again from beginning until no files are + left. This value is just an optimization to avoid checking the directory + twice unneededly. usually only NFS is the problem case. 1 is the safest + bet here, but I guess 5 will do just fine too. */ +#define MAILDIR_RENAME_RESCAN_COUNT 5 + struct maildir_sync_context { struct maildir_mailbox *mbox; const char *new_dir, *cur_dir; @@ -420,7 +428,8 @@ DIR *dirp; string_t *src, *dest; struct dirent *dp; - enum maildir_uidlist_rec_flag flags; + enum maildir_uidlist_rec_flag flags; + unsigned int moves = 0; int move_new, ret = 1; dir = new_dir ? ctx->new_dir : ctx->cur_dir; @@ -466,11 +475,13 @@ } if (rename(str_c(src), str_c(dest)) == 0) { /* we moved it - it's \Recent for us */ - ctx->mbox->dirty_cur_time = ioloop_time; + moves++; + ctx->mbox->dirty_cur_time = ioloop_time; flags |= MAILDIR_UIDLIST_REC_FLAG_MOVED | MAILDIR_UIDLIST_REC_FLAG_RECENT; } else if (ENOTFOUND(errno)) { /* someone else moved it already */ + moves++; flags |= MAILDIR_UIDLIST_REC_FLAG_MOVED; } else if (ENOSPACE(errno)) { /* not enough disk space, leave here */ @@ -510,7 +521,7 @@ } t_pop(); - return ret < 0 ? -1 : 0; + return ret < 0 ? -1 : (moves <= MAILDIR_RENAME_RESCAN_COUNT ? 0 : 1); } static int maildir_sync_quick_check(struct maildir_sync_context *ctx, @@ -937,7 +948,12 @@ ctx->uidlist_sync_ctx = maildir_uidlist_sync_init(ctx->mbox->uidlist, ctx->partial); - if (maildir_scan_dir(ctx, TRUE) < 0) + while ((ret = maildir_scan_dir(ctx, TRUE)) > 0) { + /* rename()d at least some files, which might have caused some + other files to be missed. check again (see + MAILDIR_RENAME_RESCAN_COUNT). */ + } + if (ret < 0) return -1; if (cur_changed) { if (maildir_scan_dir(ctx, FALSE) < 0)