changeset 6815:c991d1b132d8 HEAD

Fixed cache file's NFS attribute cache flushing.
author Timo Sirainen <tss@iki.fi>
date Fri, 16 Nov 2007 04:45:53 +0200
parents 020838158024
children 8573124a89b3
files src/lib-index/mail-cache-private.h src/lib-index/mail-cache.c
diffstat 2 files changed, 25 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mail-cache-private.h	Fri Nov 16 04:25:12 2007 +0200
+++ b/src/lib-index/mail-cache-private.h	Fri Nov 16 04:45:53 2007 +0200
@@ -131,6 +131,9 @@
 	char *filepath;
 	int fd;
 
+	ino_t st_ino;
+	dev_t st_dev;
+
 	void *mmap_base;
 	const void *data;
 	size_t mmap_length;
--- a/src/lib-index/mail-cache.c	Fri Nov 16 04:25:12 2007 +0200
+++ b/src/lib-index/mail-cache.c	Fri Nov 16 04:45:53 2007 +0200
@@ -86,15 +86,18 @@
 
 	file_cache_set_fd(cache->file_cache, cache->fd);
 
-	if (fstat(cache->fd, &st) < 0)
+	if (fstat(cache->fd, &st) == 0)
+		file_cache_set_size(cache->file_cache, st.st_size);
+	else if (errno != ESTALE)
 		mail_cache_set_syscall_error(cache, "fstat()");
-	else
-		file_cache_set_size(cache->file_cache, st.st_size);
+
+	cache->st_ino = st.st_ino;
+	cache->st_dev = st.st_dev;
 }
 
 static bool mail_cache_need_reopen(struct mail_cache *cache)
 {
-	struct stat st1, st2;
+	struct stat st;
 
 	if (MAIL_CACHE_IS_UNUSABLE(cache)) {
 		if (cache->need_compress_file_seq != 0) {
@@ -111,16 +114,22 @@
 		return TRUE;
 
 	/* see if the file has changed */
-	if (fstat(cache->fd, &st1) < 0) {
-		mail_cache_set_syscall_error(cache, "fstat()");
-		return TRUE;
-	}
-	if (stat(cache->filepath, &st2) < 0) {
+	if (cache->index->nfs_flush)
+		nfs_flush_attr_cache(cache->filepath, TRUE);
+	if (nfs_safe_stat(cache->filepath, &st) < 0) {
 		mail_cache_set_syscall_error(cache, "stat()");
 		return TRUE;
 	}
-	return st1.st_ino != st2.st_ino ||
-		!CMP_DEV_T(st1.st_dev, st2.st_dev);
+	if (cache->index->nfs_flush) {
+		/* if the old file has been deleted, the new file may have
+		   the same inode as the old one, but we'll catch this by
+		   flushing attribute cache and seeing if it fails with
+		   ESTALE */
+		if (!nfs_flush_attr_cache_fd(cache->filepath, cache->fd))
+			return TRUE;
+	}
+	return st.st_ino != cache->st_ino ||
+		!CMP_DEV_T(st.st_dev, cache->st_dev);
 }
 
 int mail_cache_reopen(struct mail_cache *cache)
@@ -481,6 +490,8 @@
 	if (ret <= 0)
 		return ret;
 
+	if (cache->index->nfs_flush)
+		nfs_flush_attr_cache_fd(cache->filepath, cache->fd);
 	mail_cache_flush_read_cache(cache, TRUE);
 	return 1;
 }