dovecot: Flush NFS caches when needed if MAIL_INDEX_OPEN_FLAG_NF...
dovecot at dovecot.org
dovecot at dovecot.org
Fri Jul 13 00:18:32 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/9fb9dc4d8df8
changeset: 5972:9fb9dc4d8df8
user: Timo Sirainen <tss at iki.fi>
date: Thu Jul 12 23:55:08 2007 +0300
description:
Flush NFS caches when needed if MAIL_INDEX_OPEN_FLAG_NFS_FLUSH is enabled.
diffstat:
15 files changed, 181 insertions(+), 19 deletions(-)
src/lib-index/mail-cache-compress.c | 4 ++
src/lib-index/mail-cache-private.h | 1
src/lib-index/mail-cache-sync-update.c | 2 +
src/lib-index/mail-cache.c | 53 +++++++++++++++++++++++------
src/lib-index/mail-hash.c | 12 ++++++
src/lib-index/mail-index-lock.c | 27 +++++++++++++-
src/lib-index/mail-index-map.c | 3 +
src/lib-index/mail-index-private.h | 1
src/lib-index/mail-index-write.c | 16 +++++++-
src/lib-index/mail-index.c | 16 ++++++++
src/lib-index/mail-index.h | 4 +-
src/lib-index/mail-transaction-log-file.c | 25 +++++++++++++
src/lib-index/mail-transaction-log.c | 2 +
src/lib-index/mailbox-list-index-sync.c | 17 +++++++++
src/lib-index/mailbox-list-index.c | 17 ++++++++-
diffs (truncated from 498 to 300 lines):
diff -r 2bc25f61431f -r 9fb9dc4d8df8 src/lib-index/mail-cache-compress.c
--- a/src/lib-index/mail-cache-compress.c Thu Jul 12 23:54:34 2007 +0300
+++ b/src/lib-index/mail-cache-compress.c Thu Jul 12 23:55:08 2007 +0300
@@ -257,6 +257,7 @@ static int mail_cache_compress_has_file_
return -1;
}
+ mail_cache_flush_read_cache(cache, FALSE);
ret = read_full(fd, &hdr, sizeof(hdr));
close_keep_errno(fd);
@@ -286,6 +287,9 @@ static int mail_cache_compress_locked(st
const uint32_t *offsets;
unsigned int i, count;
int fd, ret;
+
+ if (cache->fd != -1)
+ mail_cache_flush_read_cache(cache, TRUE);
/* get the latest info on fields */
if (mail_cache_header_fields_read(cache) < 0)
diff -r 2bc25f61431f -r 9fb9dc4d8df8 src/lib-index/mail-cache-private.h
--- a/src/lib-index/mail-cache-private.h Thu Jul 12 23:54:34 2007 +0300
+++ b/src/lib-index/mail-cache-private.h Thu Jul 12 23:55:08 2007 +0300
@@ -200,6 +200,7 @@ int mail_cache_lock(struct mail_cache *c
/* Returns -1 if cache is / just got corrupted, 0 if ok. */
int mail_cache_unlock(struct mail_cache *cache);
+void mail_cache_flush_read_cache(struct mail_cache *cache, bool just_locked);
int mail_cache_write(struct mail_cache *cache, const void *data, size_t size,
uoff_t offset);
diff -r 2bc25f61431f -r 9fb9dc4d8df8 src/lib-index/mail-cache-sync-update.c
--- a/src/lib-index/mail-cache-sync-update.c Thu Jul 12 23:54:34 2007 +0300
+++ b/src/lib-index/mail-cache-sync-update.c Thu Jul 12 23:55:08 2007 +0300
@@ -119,6 +119,7 @@ int mail_cache_sync_handler(struct mail_
return 1;
if (cache->file_cache != NULL) {
+ mail_cache_flush_read_cache(cache, FALSE);
file_cache_invalidate(cache->file_cache, *new_cache_offset,
(uoff_t)-1);
}
@@ -158,5 +159,6 @@ int mail_cache_sync_handler(struct mail_
void mail_cache_sync_lost_handler(struct mail_index *index)
{
+ mail_cache_flush_read_cache(index->cache, FALSE);
file_cache_invalidate(index->cache->file_cache, 0, (uoff_t)-1);
}
diff -r 2bc25f61431f -r 9fb9dc4d8df8 src/lib-index/mail-cache.c
--- a/src/lib-index/mail-cache.c Thu Jul 12 23:54:34 2007 +0300
+++ b/src/lib-index/mail-cache.c Thu Jul 12 23:55:08 2007 +0300
@@ -76,6 +76,9 @@ static void mail_cache_init_file_cache(s
if (cache->file_cache == NULL)
return;
+
+ nfs_flush_attr_cache_fd(cache->filepath, cache->fd);
+ nfs_flush_read_cache(cache->filepath, cache->fd, F_UNLCK, FALSE);
file_cache_set_fd(cache->file_cache, cache->fd);
@@ -397,19 +400,44 @@ void mail_cache_free(struct mail_cache *
i_free(cache);
}
-static int mail_cache_lock_file(struct mail_cache *cache, int lock_type)
-{
+void mail_cache_flush_read_cache(struct mail_cache *cache, bool just_locked)
+{
+ if (!cache->index->nfs_flush)
+ return;
+
+ /* Assume flock() is independent of fcntl() locks. This isn't true
+ with Linux 2.6 NFS, but with it there's no point in using flock() */
+ if (cache->locked &&
+ cache->index->lock_method == FILE_LOCK_METHOD_FCNTL) {
+ nfs_flush_read_cache(cache->filepath, cache->fd,
+ F_WRLCK, just_locked);
+ } else {
+ nfs_flush_read_cache(cache->filepath, cache->fd,
+ F_UNLCK, FALSE);
+ }
+}
+
+static int mail_cache_lock_file(struct mail_cache *cache)
+{
+ int ret;
+
if (cache->index->lock_method != FILE_LOCK_METHOD_DOTLOCK) {
i_assert(cache->file_lock == NULL);
- return mail_index_lock_fd(cache->index, cache->filepath,
- cache->fd, lock_type,
- MAIL_INDEX_LOCK_SECS,
- &cache->file_lock);
+ ret = mail_index_lock_fd(cache->index, cache->filepath,
+ cache->fd, F_WRLCK,
+ MAIL_INDEX_LOCK_SECS,
+ &cache->file_lock);
} else {
i_assert(cache->dotlock == NULL);
- return file_dotlock_create(&cache->dotlock_settings,
- cache->filepath, 0, &cache->dotlock);
- }
+ ret = file_dotlock_create(&cache->dotlock_settings,
+ cache->filepath, 0, &cache->dotlock);
+ }
+
+ if (ret <= 0)
+ return ret;
+
+ mail_cache_flush_read_cache(cache, TRUE);
+ return 1;
}
static void mail_cache_unlock_file(struct mail_cache *cache)
@@ -454,7 +482,7 @@ int mail_cache_lock(struct mail_cache *c
}
for (i = 0; i < 3; i++) {
- ret = mail_cache_lock_file(cache, F_WRLCK);
+ ret = mail_cache_lock_file(cache);
if (ret <= 0)
break;
cache->locked = TRUE;
@@ -536,6 +564,11 @@ int mail_cache_unlock(struct mail_cache
sizeof(cache->hdr_copy), 0) < 0)
ret = -1;
mail_cache_update_need_compress(cache);
+ }
+
+ if (cache->index->nfs_flush) {
+ if (fdatasync(cache->fd) < 0)
+ mail_cache_set_syscall_error(cache, "fdatasync()");
}
mail_cache_unlock_file(cache);
diff -r 2bc25f61431f -r 9fb9dc4d8df8 src/lib-index/mail-hash.c
--- a/src/lib-index/mail-hash.c Thu Jul 12 23:54:34 2007 +0300
+++ b/src/lib-index/mail-hash.c Thu Jul 12 23:55:08 2007 +0300
@@ -10,6 +10,7 @@
#include "read-full.h"
#include "write-full.h"
#include "mmap-util.h"
+#include "nfs-workarounds.h"
#include "mail-index-private.h"
#include "mail-hash.h"
@@ -273,6 +274,9 @@ static int mail_hash_file_read(struct ma
hash->mmap_size = size;
}
+ if (hash->index->nfs_flush)
+ nfs_flush_read_cache(hash->filepath, hash->fd, F_UNLCK, FALSE);
+
ret = pread_full(hash->fd, hash->mmap_base, size, 0);
if (ret < 0) {
mail_hash_set_syscall_error(hash, "pread_full()");
@@ -356,6 +360,9 @@ static int mail_hash_file_map(struct mai
{
struct stat st;
size_t size;
+
+ if (hash->index->nfs_flush)
+ nfs_flush_attr_cache_fd(hash->filepath, hash->fd);
if (fstat(hash->fd, &st) < 0) {
mail_hash_set_syscall_error(hash, "fstat()");
@@ -644,7 +651,10 @@ static int mail_hash_reopen_if_needed(st
if (hash->fd == -1)
return mail_hash_reopen(hash);
- if (stat(hash->filepath, &st) < 0) {
+ if (hash->index->nfs_flush)
+ nfs_flush_attr_cache(hash->filepath);
+
+ if (nfs_safe_stat(hash->filepath, &st) < 0) {
if (errno == ENOENT)
return mail_hash_reopen(hash);
diff -r 2bc25f61431f -r 9fb9dc4d8df8 src/lib-index/mail-index-lock.c
--- a/src/lib-index/mail-index-lock.c Thu Jul 12 23:54:34 2007 +0300
+++ b/src/lib-index/mail-index-lock.c Thu Jul 12 23:55:08 2007 +0300
@@ -18,6 +18,7 @@
*/
#include "lib.h"
+#include "nfs-workarounds.h"
#include "mail-index-private.h"
int mail_index_lock_fd(struct mail_index *index, const char *path, int fd,
@@ -117,13 +118,31 @@ static int mail_index_lock(struct mail_i
return 1;
}
+static void mail_index_flush_read_cache(struct mail_index *index)
+{
+ if (!index->nfs_flush)
+ return;
+
+ /* Assume flock() is independent of fcntl() locks. This isn't true
+ with Linux 2.6 NFS, but with it there's no point in using flock() */
+ if (index->lock_method == FILE_LOCK_METHOD_FCNTL) {
+ nfs_flush_read_cache(index->filepath, index->fd,
+ index->lock_type, TRUE);
+ } else {
+ nfs_flush_read_cache(index->filepath, index->fd,
+ F_UNLCK, FALSE);
+ }
+}
+
int mail_index_lock_shared(struct mail_index *index, unsigned int *lock_id_r)
{
int ret;
ret = mail_index_lock(index, F_RDLCK, MAIL_INDEX_LOCK_SECS, lock_id_r);
- if (ret > 0)
+ if (ret > 0) {
+ mail_index_flush_read_cache(index);
return 0;
+ }
if (ret < 0)
return -1;
@@ -137,7 +156,11 @@ int mail_index_try_lock_exclusive(struct
int mail_index_try_lock_exclusive(struct mail_index *index,
unsigned int *lock_id_r)
{
- return mail_index_lock(index, F_WRLCK, 0, lock_id_r);
+ int ret;
+
+ if ((ret = mail_index_lock(index, F_WRLCK, 0, lock_id_r)) > 0)
+ mail_index_flush_read_cache(index);
+ return ret;
}
void mail_index_unlock(struct mail_index *index, unsigned int *_lock_id)
diff -r 2bc25f61431f -r 9fb9dc4d8df8 src/lib-index/mail-index-map.c
--- a/src/lib-index/mail-index-map.c Thu Jul 12 23:54:34 2007 +0300
+++ b/src/lib-index/mail-index-map.c Thu Jul 12 23:55:08 2007 +0300
@@ -678,6 +678,9 @@ static int mail_index_map_latest_file(st
if (mail_index_lock_shared(index, &lock_id) < 0)
return -1;
+ if (index->nfs_flush)
+ nfs_flush_attr_cache_fd(index->filepath, index->fd);
+
if (fstat(index->fd, &st) == 0)
file_size = st.st_size;
else {
diff -r 2bc25f61431f -r 9fb9dc4d8df8 src/lib-index/mail-index-private.h
--- a/src/lib-index/mail-index-private.h Thu Jul 12 23:54:34 2007 +0300
+++ b/src/lib-index/mail-index-private.h Thu Jul 12 23:55:08 2007 +0300
@@ -200,6 +200,7 @@ struct mail_index {
unsigned int mmap_disable:1;
unsigned int fsync_disable:1;
unsigned int use_excl_dotlocks:1;
+ unsigned int nfs_flush:1;
unsigned int readonly:1;
unsigned int fsck:1;
unsigned int mapping:1;
diff -r 2bc25f61431f -r 9fb9dc4d8df8 src/lib-index/mail-index-write.c
--- a/src/lib-index/mail-index-write.c Thu Jul 12 23:54:34 2007 +0300
+++ b/src/lib-index/mail-index-write.c Thu Jul 12 23:55:08 2007 +0300
@@ -138,6 +138,7 @@ void mail_index_write(struct mail_index
const struct mail_index_header *hdr = &map->hdr;
struct stat st;
unsigned int lock_id;
+ int ret;
if (!mail_index_map_has_changed(map))
return;
@@ -192,14 +193,23 @@ void mail_index_write(struct mail_index
}
}
} else {
- if (mail_index_write_map_over(index) < 0) {
+ ret = mail_index_write_map_over(index);
+ if (ret < 0)
mail_index_set_syscall_error(index, "pwrite_full()");
+ else if (index->nfs_flush) {
+ ret = fdatasync(index->fd);
+ if (ret < 0) {
+ mail_index_set_syscall_error(index,
+ "fdatasync()");
+ }
+ }
+ mail_index_unlock(index, &lock_id);
+
+ if (ret < 0) {
/* hopefully didn't break badly */
- mail_index_unlock(index, &lock_id);
mail_index_move_to_memory(index);
return;
}
- mail_index_unlock(index, &lock_id);
}
index->last_read_log_file_seq = hdr->log_file_seq;
More information about the dovecot-cvs
mailing list