[dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-sync.c,
1.55, 1.56
cras at dovecot.org
cras at dovecot.org
Thu Jun 16 22:46:20 EEST 2005
Update of /var/lib/cvs/dovecot/src/lib-storage/index/maildir
In directory talvi:/tmp/cvs-serv14484/lib-storage/index/maildir
Modified Files:
maildir-sync.c
Log Message:
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.
Index: maildir-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-sync.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -d -r1.55 -r1.56
--- maildir-sync.c 9 Jun 2005 14:31:43 -0000 1.55
+++ maildir-sync.c 16 Jun 2005 19:46:18 -0000 1.56
@@ -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)
More information about the dovecot-cvs
mailing list