Mercurial > dovecot > original-hg > dovecot-1.2
changeset 6802:ba58eaf06763 HEAD
Keep better track of when we need to flush NFS attribute caches.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 15 Nov 2007 03:15:18 +0200 |
parents | 6a5540e5a464 |
children | 9f40c3f83773 |
files | src/lib-index/mail-transaction-log-file.c src/lib-index/mail-transaction-log-private.h src/lib-index/mail-transaction-log-view.c src/lib-index/mail-transaction-log.c |
diffstat | 4 files changed, 49 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ 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 @@ 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); }
--- 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(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,
--- 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 @@ 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 @@ 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++;
--- 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 @@ 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 @@ 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 @@ } 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 @@ return 0; } - if (mail_transaction_log_refresh(log) < 0) + if (mail_transaction_log_refresh(log, FALSE) < 0) return -1; - if (file_seq > log->head->hdr.file_seq) - return 0; + 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 @@ 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;