Mercurial > dovecot > core-2.2
changeset 22302:55d796ab90d8
dbox: Check mailbox existence from index directory with ITERINDEX
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Mon, 26 Jun 2017 19:06:26 +0300 |
parents | d86a691543b4 |
children | 15823e373013 |
files | src/lib-storage/index/dbox-common/dbox-storage.c |
diffstat | 1 files changed, 47 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/dbox-common/dbox-storage.c Wed Jun 28 19:46:01 2017 +0300 +++ b/src/lib-storage/index/dbox-common/dbox-storage.c Mon Jun 26 19:06:26 2017 +0300 @@ -15,6 +15,7 @@ #include <stdio.h> #include <dirent.h> #include <unistd.h> +#include <utime.h> void dbox_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED, struct mailbox_list_settings *set) @@ -178,10 +179,25 @@ /* not the time to scan it yet */ return FALSE; } else { + bool stated = FALSE; + if (last_change_time == (time_t)-1) { + /* Don't know the ctime yet - look it up. */ + struct stat st; + + if (stat(path, &st) < 0) { + if (errno == ENOENT) + i_error("stat(%s) failed: %m", path); + return FALSE; + } + last_change_time = st.st_ctime; + stated = TRUE; + } if (last_scan_time > last_change_time + DBOX_TMP_DELETE_SECS) { /* there haven't been any changes to this directory - since we last checked it. */ - return FALSE; + since we last checked it. If we did an extra stat(), + we need to update the last_scan_time to avoid + stat()ing the next time. */ + return stated; } const char *prefix = mailbox_list_get_global_temp_prefix(list); @@ -189,15 +205,41 @@ ioloop_time - DBOX_TMP_DELETE_SECS); return TRUE; } + return FALSE; } int dbox_mailbox_check_existence(struct mailbox *box, time_t *path_ctime_r) { - const char *box_path = mailbox_get_path(box); + const char *index_path, *box_path = mailbox_get_path(box); struct stat st; + int ret = -1; + + *path_ctime_r = (time_t)-1; - if (stat(box_path, &st) == 0) { - *path_ctime_r = st.st_ctime; + if (box->list->set.iter_from_index_dir) { + /* Just because the index directory exists, it doesn't mean + that the mailbox is selectable. Check that by seeing if + dovecot.index.log exists. If it doesn't, fallback to + checking for the dbox-Mails in the mail root directory. + So this also means that if a mailbox is \NoSelect, listing + it will always do a stat() for dbox-Mails in the mail root + directory. That's not ideal, but this makes the behavior + safer and \NoSelect mailboxes are somewhat rare. */ + if (mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_INDEX, + &index_path) < 0) + return -1; + i_assert(index_path != NULL); + index_path = t_strconcat(index_path, "/", box->index_prefix, + ".log", NULL); + ret = stat(index_path, &st); + } + if (ret < 0) { + ret = stat(box_path, &st); + if (ret == 0) + *path_ctime_r = st.st_ctime; + } + + if (ret == 0) { return 0; } else if (errno == ENOENT || errno == ENAMETOOLONG) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,