dovecot: Keep better track of when we need to flush NFS attribut...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Nov 15 03:15:24 EET 2007
details: http://hg.dovecot.org/dovecot/rev/ba58eaf06763
changeset: 6802:ba58eaf06763
user: Timo Sirainen <tss at iki.fi>
date: Thu Nov 15 03:15:18 2007 +0200
description:
Keep better track of when we need to flush NFS attribute caches.
diffstat:
4 files changed, 50 insertions(+), 14 deletions(-)
src/lib-index/mail-transaction-log-file.c | 26 +++++++++++++++++++++++++-
src/lib-index/mail-transaction-log-private.h | 2 +-
src/lib-index/mail-transaction-log-view.c | 12 ++++++++----
src/lib-index/mail-transaction-log.c | 24 ++++++++++++++++--------
diffs (146 lines):
diff -r 6a5540e5a464 -r ba58eaf06763 src/lib-index/mail-transaction-log-file.c
--- a/src/lib-index/mail-transaction-log-file.c Thu Nov 15 02:04:21 2007 +0200
+++ b/src/lib-index/mail-transaction-log-file.c Thu Nov 15 03:15:18 2007 +0200
@@ -885,6 +885,29 @@ mail_transaction_log_file_read_more(stru
return 1;
}
+static bool
+mail_transaction_log_file_need_nfs_flush(struct mail_transaction_log_file *file)
+{
+ const struct mail_index_header *hdr = &file->log->index->map->hdr;
+
+ if (file->locked)
+ return TRUE;
+
+ if (file->next != NULL &&
+ file->hdr.file_seq == file->next->hdr.prev_file_seq &&
+ file->next->hdr.prev_file_offset != file->sync_offset) {
+ /* we already have a newer log file which says that we haven't
+ synced the entire file. */
+ return TRUE;
+ }
+
+ if (file->hdr.file_seq == hdr->log_file_seq &&
+ file->sync_offset < hdr->log_file_head_offset)
+ return TRUE;
+
+ return FALSE;
+}
+
static int
mail_transaction_log_file_read(struct mail_transaction_log_file *file,
uoff_t start_offset)
@@ -893,7 +916,8 @@ mail_transaction_log_file_read(struct ma
i_assert(file->mmap_base == NULL);
- if (file->log->index->nfs_flush && file->locked) {
+ if (file->log->index->nfs_flush &&
+ mail_transaction_log_file_need_nfs_flush(file)) {
/* Make sure we know the latest file size */
nfs_flush_attr_cache_fd(file->filepath, file->fd);
}
diff -r 6a5540e5a464 -r ba58eaf06763 src/lib-index/mail-transaction-log-private.h
--- a/src/lib-index/mail-transaction-log-private.h Thu Nov 15 02:04:21 2007 +0200
+++ b/src/lib-index/mail-transaction-log-private.h Thu Nov 15 03:15:18 2007 +0200
@@ -93,7 +93,7 @@ int mail_transaction_log_file_lock(struc
int mail_transaction_log_file_lock(struct mail_transaction_log_file *file);
int mail_transaction_log_find_file(struct mail_transaction_log *log,
- uint32_t file_seq,
+ uint32_t file_seq, bool nfs_flush,
struct mail_transaction_log_file **file_r);
/* Returns 1 if ok, 0 if file is corrupted or offset range is invalid,
diff -r 6a5540e5a464 -r ba58eaf06763 src/lib-index/mail-transaction-log-view.c
--- a/src/lib-index/mail-transaction-log-view.c Thu Nov 15 02:04:21 2007 +0200
+++ b/src/lib-index/mail-transaction-log-view.c Thu Nov 15 03:15:18 2007 +0200
@@ -152,9 +152,13 @@ int mail_transaction_log_view_set(struct
view->tail = view->head = file = NULL;
for (seq = min_file_seq; seq <= max_file_seq; seq++) {
if (file == NULL || file->hdr.file_seq != seq) {
- /* see if we could find the missing file */
- ret = mail_transaction_log_find_file(view->log,
- seq, &file);
+ /* see if we could find the missing file. if we know
+ the max. file sequence, make sure NFS attribute
+ cache gets flushed if necessary. */
+ bool nfs_flush = max_file_seq != (uint32_t)-1;
+
+ ret = mail_transaction_log_find_file(view->log, seq,
+ nfs_flush, &file);
if (ret <= 0) {
if (ret < 0)
return -1;
@@ -284,7 +288,7 @@ void mail_transaction_log_view_clear(str
struct mail_transaction_log_file *file;
mail_transaction_log_view_unref_all(view);
- if (mail_transaction_log_find_file(view->log, oldest_file_seq,
+ if (mail_transaction_log_find_file(view->log, oldest_file_seq, FALSE,
&file) > 0) {
array_append(&view->file_refs, &file, 1);
file->refcount++;
diff -r 6a5540e5a464 -r ba58eaf06763 src/lib-index/mail-transaction-log.c
--- a/src/lib-index/mail-transaction-log.c Thu Nov 15 02:04:21 2007 +0200
+++ b/src/lib-index/mail-transaction-log.c Thu Nov 15 03:15:18 2007 +0200
@@ -265,7 +265,8 @@ int mail_transaction_log_rotate(struct m
return 0;
}
-static int mail_transaction_log_refresh(struct mail_transaction_log *log)
+static int
+mail_transaction_log_refresh(struct mail_transaction_log *log, bool nfs_flush)
{
struct mail_transaction_log_file *file;
struct stat st;
@@ -278,7 +279,7 @@ static int mail_transaction_log_refresh(
path = t_strconcat(log->index->filepath,
MAIL_TRANSACTION_LOG_SUFFIX, NULL);
- if (log->index->nfs_flush && log->head->locked)
+ if (log->index->nfs_flush && nfs_flush)
nfs_flush_attr_cache(path, TRUE);
if (nfs_safe_stat(path, &st) < 0) {
if (errno != ENOENT) {
@@ -345,7 +346,7 @@ void mail_transaction_log_set_mailbox_sy
}
int mail_transaction_log_find_file(struct mail_transaction_log *log,
- uint32_t file_seq,
+ uint32_t file_seq, bool nfs_flush,
struct mail_transaction_log_file **file_r)
{
struct mail_transaction_log_file *file;
@@ -360,10 +361,17 @@ int mail_transaction_log_find_file(struc
return 0;
}
- if (mail_transaction_log_refresh(log) < 0)
- return -1;
- if (file_seq > log->head->hdr.file_seq)
- return 0;
+ if (mail_transaction_log_refresh(log, FALSE) < 0)
+ return -1;
+ if (file_seq > log->head->hdr.file_seq) {
+ if (!nfs_flush || !log->index->nfs_flush)
+ return 0;
+ /* try again, this time flush attribute cache */
+ if (mail_transaction_log_refresh(log, TRUE) < 0)
+ return -1;
+ if (file_seq > log->head->hdr.file_seq)
+ return 0;
+ }
}
for (file = log->files; file != NULL; file = file->next) {
@@ -410,7 +418,7 @@ int mail_transaction_log_lock_head(struc
return -1;
file->refcount++;
- ret = mail_transaction_log_refresh(log);
+ ret = mail_transaction_log_refresh(log, TRUE);
if (--file->refcount == 0) {
mail_transaction_logs_clean(log);
file = NULL;
More information about the dovecot-cvs
mailing list