changeset 6753:de67ceff3199 HEAD

Flush cache file's NFS attribute cache only once per sync. Don't invalidate areas that have already been invalidated within this sync.
author Timo Sirainen <tss@iki.fi>
date Thu, 08 Nov 2007 21:55:06 +0200
parents 75f7163d4379
children 4b92160ac256
files src/lib-index/mail-cache-sync-update.c
diffstat 1 files changed, 36 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-cache-sync-update.c	Thu Nov 08 21:37:43 2007 +0200
+++ b/src/lib-index/mail-cache-sync-update.c	Thu Nov 08 21:55:06 2007 +0200
@@ -7,8 +7,11 @@
 #include "mail-index-sync-private.h"
 
 struct mail_cache_sync_context {
+	uoff_t invalidate_highwater;
+
 	unsigned int locked:1;
 	unsigned int lock_failed:1;
+	unsigned int nfs_attr_cache_flushed:1;
 };
 
 static void mail_cache_handler_deinit(struct mail_index_sync_map_ctx *sync_ctx,
@@ -22,15 +25,25 @@
 	i_free(ctx);
 }
 
-static int mail_cache_handler_init(struct mail_cache_sync_context **ctx_r,
+static struct mail_cache_sync_context *mail_cache_handler_init(void **context)
+{
+	struct mail_cache_sync_context *ctx;
+
+	if (*context != NULL)
+		ctx = *context;
+	else {
+		*context = i_new(struct mail_cache_sync_context, 1);
+		ctx = *context;
+		ctx->invalidate_highwater = (uoff_t)-1;
+	}
+	return ctx;
+}
+
+static int mail_cache_handler_lock(struct mail_cache_sync_context *ctx,
 				   struct mail_cache *cache)
 {
-	struct mail_cache_sync_context *ctx = *ctx_r;
 	int ret;
 
-	if (ctx == NULL)
-		ctx = *ctx_r = i_new(struct mail_cache_sync_context, 1);
-
 	if (ctx->locked)
 		return 1;
 	if (ctx->lock_failed)
@@ -81,8 +94,8 @@
 	if (MAIL_CACHE_IS_UNUSABLE(cache))
 		return 0;
 
-	ret = mail_cache_handler_init(&ctx, cache);
-	*sync_context = ctx;
+	ctx = mail_cache_handler_init(context);
+	ret = mail_cache_handler_lock(ctx, cache);
 	if (ret <= 0)
 		return ret;
 
@@ -118,10 +131,22 @@
 	if (MAIL_CACHE_IS_UNUSABLE(cache))
 		return 1;
 
+	ctx = mail_cache_handler_init(context);
 	if (cache->file_cache != NULL) {
-		mail_cache_flush_read_cache(cache, FALSE);
-		file_cache_invalidate(cache->file_cache, *new_cache_offset,
-				      (uoff_t)-1);
+		/* flush attribute cache only once per sync */
+		if (!ctx->nfs_attr_cache_flushed && cache->index->nfs_flush) {
+			ctx->nfs_attr_cache_flushed = TRUE;
+			mail_cache_flush_read_cache(cache, FALSE);
+		}
+		/* don't invalidate anything that's already been invalidated
+		   within this sync. */
+		if (*new_cache_offset < ctx->invalidate_highwater) {
+			file_cache_invalidate(cache->file_cache,
+					      *new_cache_offset,
+					      ctx->invalidate_highwater -
+					      *new_cache_offset);
+			ctx->invalidate_highwater = *new_cache_offset;
+		}
 	}
 
 	if (*old_cache_offset == 0 || *old_cache_offset == *new_cache_offset ||
@@ -138,8 +163,7 @@
 	}
 
 	/* we'll need to link the old and new cache records */
-	ret = mail_cache_handler_init(&ctx, cache);
-	*context = ctx;
+	ret = mail_cache_handler_lock(ctx, cache);
 	if (ret <= 0)
 		return ret < 0 ? -1 : 1;