[dovecot-cvs] dovecot/src/lib-index mail-cache-compress.c, 1.41,
1.42 mail-cache-private.h, 1.28, 1.29 mail-cache.c, 1.79, 1.80
cras at dovecot.org
cras at dovecot.org
Wed May 3 23:07:16 EEST 2006
Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv6636
Modified Files:
mail-cache-compress.c mail-cache-private.h mail-cache.c
Log Message:
Don't compress cache file if it was just compressed by another process.
Index: mail-cache-compress.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-compress.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- mail-cache-compress.c 26 Feb 2006 10:05:13 -0000 1.41
+++ mail-cache-compress.c 3 May 2006 20:07:13 -0000 1.42
@@ -3,6 +3,9 @@
#include "lib.h"
#include "buffer.h"
#include "ostream.h"
+#include "nfs-workarounds.h"
+#include "read-full.h"
+#include "close-keep-errno.h"
#include "file-dotlock.h"
#include "file-cache.h"
#include "file-set-size.h"
@@ -236,21 +239,52 @@
return mail_index_transaction_commit(&t, &seq, &offset);
}
+static int mail_cache_compress_has_file_changed(struct mail_cache *cache)
+{
+ struct mail_cache_header hdr;
+ unsigned int i;
+ int fd, ret;
+
+ for (i = 0;; i++) {
+ fd = nfs_safe_open(cache->filepath, O_RDONLY);
+ if (fd == -1) {
+ if (errno == ENOENT)
+ return 0;
+
+ mail_cache_set_syscall_error(cache, "open()");
+ return -1;
+ }
+
+ ret = read_full(fd, &hdr, sizeof(hdr));
+ close_keep_errno(fd);
+
+ if (ret >= 0) {
+ if (ret == 0)
+ return 0;
+ if (cache->need_compress_file_seq == (uint32_t)-1) {
+ /* previously it didn't exist */
+ return 1;
+ }
+ return hdr.file_seq != cache->need_compress_file_seq;
+ } else if (errno != ESTALE || i >= NFS_ESTALE_RETRY_COUNT) {
+ mail_cache_set_syscall_error(cache, "read()");
+ return -1;
+ }
+ }
+ return -1;
+}
+
static int mail_cache_compress_locked(struct mail_cache *cache,
struct mail_index_view *view)
{
struct dotlock *dotlock;
mode_t old_mask;
- int fd;
+ int fd, ret;
/* get the latest info on fields */
if (mail_cache_header_fields_read(cache) < 0)
return -1;
-#ifdef DEBUG
- i_warning("Compressing cache file %s", cache->filepath);
-#endif
-
old_mask = umask(cache->index->mode ^ 0666);
fd = file_dotlock_open(&cache->dotlock_settings, cache->filepath,
0, &dotlock);
@@ -261,6 +295,21 @@
return -1;
}
+ if ((ret = mail_cache_compress_has_file_changed(cache)) != 0) {
+ if (ret < 0)
+ return -1;
+
+ /* was just compressed, forget this */
+ cache->need_compress_file_seq = 0;
+ file_dotlock_delete(&dotlock);
+ return mail_cache_reopen(cache);
+ }
+
+#ifdef DEBUG
+ i_warning("Compressing cache file %s (%u)",
+ cache->filepath, cache->need_compress_file_seq);
+#endif
+
if (cache->index->gid != (gid_t)-1 &&
fchown(fd, (uid_t)-1, cache->index->gid) < 0) {
mail_cache_set_syscall_error(cache, "fchown()");
@@ -268,8 +317,6 @@
return -1;
}
- // FIXME: check that cache file wasn't just recreated
-
if (mail_cache_copy(cache, view, fd) < 0) {
(void)file_dotlock_delete(&dotlock);
return -1;
@@ -294,7 +341,7 @@
if (mail_cache_header_fields_read(cache) < 0)
return -1;
- cache->need_compress = FALSE;
+ cache->need_compress_file_seq = 0;
return 0;
}
@@ -329,5 +376,5 @@
bool mail_cache_need_compress(struct mail_cache *cache)
{
- return cache->need_compress;
+ return cache->need_compress_file_seq != 0;
}
Index: mail-cache-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache-private.h,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- mail-cache-private.h 5 Feb 2006 12:46:08 -0000 1.28
+++ mail-cache-private.h 3 May 2006 20:07:13 -0000 1.29
@@ -140,11 +140,14 @@
unsigned int fields_count;
struct hash_table *field_name_hash; /* name -> idx */
+ /* 0 is no need for compression, otherwise the file sequence number
+ which we want compressed. */
+ uint32_t need_compress_file_seq;
+
unsigned int *file_field_map;
unsigned int file_fields_count;
unsigned int locked:1;
- unsigned int need_compress:1;
unsigned int hdr_modified:1;
unsigned int field_header_write_pending:1;
};
Index: mail-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache.c,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -d -r1.79 -r1.80
--- mail-cache.c 16 Feb 2006 15:23:03 -0000 1.79
+++ mail-cache.c 3 May 2006 20:07:13 -0000 1.80
@@ -4,6 +4,7 @@
#include "array.h"
#include "buffer.h"
#include "hash.h"
+#include "nfs-workarounds.h"
#include "file-cache.h"
#include "mmap-util.h"
#include "write-full.h"
@@ -71,17 +72,18 @@
const struct mail_index_ext *ext;
if (MAIL_CACHE_IS_UNUSABLE(cache) &&
- (cache->need_compress || MAIL_INDEX_IS_IN_MEMORY(cache->index))) {
+ (cache->need_compress_file_seq != 0 ||
+ MAIL_INDEX_IS_IN_MEMORY(cache->index))) {
/* reopening does no good */
return 0;
}
mail_cache_file_close(cache);
- cache->fd = open(cache->filepath, O_RDWR);
+ cache->fd = nfs_safe_open(cache->filepath, O_RDWR);
if (cache->fd == -1) {
if (errno == ENOENT)
- cache->need_compress = TRUE;
+ cache->need_compress_file_seq = (uint32_t)-1;
else
mail_cache_set_syscall_error(cache, "open()");
return -1;
@@ -103,7 +105,7 @@
file_seq really is corrupted. either way, this shouldn't
happen often so we'll just mark cache to be compressed
later which fixes this. */
- cache->need_compress = TRUE;
+ cache->need_compress_file_seq = cache->hdr->file_seq;
mail_index_view_close(&view);
return 0;
}
@@ -197,7 +199,9 @@
cache->hdr = cache->data;
if (offset == 0 && !mail_cache_verify_header(cache)) {
- cache->need_compress = TRUE;
+ cache->need_compress_file_seq =
+ cache->hdr->file_seq != 0 ?
+ cache->hdr->file_seq : (uint32_t)-1;
return -1;
}
return 0;
@@ -216,7 +220,7 @@
if (cache->fd == -1) {
/* unusable, waiting for compression or
index is in memory */
- i_assert(cache->need_compress ||
+ i_assert(cache->need_compress_file_seq != 0 ||
MAIL_INDEX_IS_IN_MEMORY(cache->index));
return -1;
}
@@ -237,7 +241,9 @@
cache->hdr = cache->mmap_base;
if (!mail_cache_verify_header(cache)) {
- cache->need_compress = TRUE;
+ cache->need_compress_file_seq =
+ cache->hdr->file_seq != 0 ?
+ cache->hdr->file_seq : (uint32_t)-1;
return -1;
}
@@ -249,10 +255,10 @@
if (MAIL_INDEX_IS_IN_MEMORY(cache->index))
return 0;
- cache->fd = open(cache->filepath, O_RDWR);
+ cache->fd = nfs_safe_open(cache->filepath, O_RDWR);
if (cache->fd == -1) {
if (errno == ENOENT) {
- cache->need_compress = TRUE;
+ cache->need_compress_file_seq = (uint32_t)-1;
return 0;
}
@@ -327,7 +333,7 @@
struct mail_cache *cache;
cache = mail_cache_alloc(index);
- cache->need_compress = TRUE;
+ cache->need_compress_file_seq = (uint32_t)-1;
return cache;
}
@@ -449,14 +455,14 @@
if (cont_percentage >= COMPRESS_CONTINUED_PERCENTAGE &&
hdr->used_file_size >= COMPRESS_MIN_SIZE) {
/* too many continued rows, compress */
- cache->need_compress = TRUE;
+ cache->need_compress_file_seq = hdr->file_seq;
}
/* see if we've reached the max. deleted space in file */
max_del_space = hdr->used_file_size / 100 * COMPRESS_PERCENTAGE;
if (hdr->deleted_space >= max_del_space &&
hdr->used_file_size >= COMPRESS_MIN_SIZE)
- cache->need_compress = TRUE;
+ cache->need_compress_file_seq = hdr->file_seq;
}
int mail_cache_unlock(struct mail_cache *cache)
More information about the dovecot-cvs
mailing list