dovecot-1.1: Added support for dotlocks.
dovecot at dovecot.org
dovecot at dovecot.org
Fri Mar 7 08:15:38 EET 2008
details: http://hg.dovecot.org/dovecot-1.1/rev/55712d36224b
changeset: 7371:55712d36224b
user: Timo Sirainen <tss at iki.fi>
date: Fri Mar 07 08:15:35 2008 +0200
description:
Added support for dotlocks.
diffstat:
4 files changed, 114 insertions(+), 42 deletions(-)
src/plugins/fts-squat/squat-trie-private.h | 5 +
src/plugins/fts-squat/squat-trie.c | 85 ++++++++++++++++++++--------
src/plugins/fts-squat/squat-trie.h | 9 ++
src/plugins/fts-squat/squat-uidlist.c | 57 +++++++++++++-----
diffs (truncated from 384 to 300 lines):
diff -r d51565e31ceb -r 55712d36224b src/plugins/fts-squat/squat-trie-private.h
--- a/src/plugins/fts-squat/squat-trie-private.h Fri Mar 07 07:38:41 2008 +0200
+++ b/src/plugins/fts-squat/squat-trie-private.h Fri Mar 07 08:15:35 2008 +0200
@@ -1,10 +1,12 @@
#ifndef SQUAT_TRIE_PRIVATE_H
#define SQUAT_TRIE_PRIVATE_H
+#include "file-dotlock.h"
#include "squat-trie.h"
#define SQUAT_TRIE_VERSION 2
#define SQUAT_TRIE_LOCK_TIMEOUT 60
+#define SQUAT_TRIE_DOTLOCK_STALE_TIMEOUT (15*60)
struct squat_file_header {
uint8_t version;
@@ -114,12 +116,14 @@ struct squat_trie {
size_t node_alloc_size;
unsigned int unmapped_child_count;
+ enum squat_index_flags flags;
enum file_lock_method lock_method;
uint32_t uidvalidity;
char *path;
int fd;
struct file_cache *file_cache;
+ struct dotlock_settings dotlock_set;
uoff_t locked_file_size;
const void *data;
@@ -130,7 +134,6 @@ struct squat_trie {
unsigned char default_normalize_map[256];
- unsigned int mmap_disable:1;
unsigned int corrupted:1;
};
diff -r d51565e31ceb -r 55712d36224b src/plugins/fts-squat/squat-trie.c
--- a/src/plugins/fts-squat/squat-trie.c Fri Mar 07 07:38:41 2008 +0200
+++ b/src/plugins/fts-squat/squat-trie.c Fri Mar 07 08:15:35 2008 +0200
@@ -36,6 +36,7 @@ struct squat_trie_build_context {
struct squat_uidlist_build_context *uidlist_build_ctx;
struct file_lock *file_lock;
+ struct dotlock *dotlock;
uint32_t first_uid;
unsigned int compress_nodes:1;
@@ -126,7 +127,7 @@ static void node_free(struct squat_trie
struct squat_trie *
squat_trie_init(const char *path, uint32_t uidvalidity,
- enum file_lock_method lock_method, bool mmap_disable)
+ enum file_lock_method lock_method, enum squat_index_flags flags)
{
struct squat_trie *trie;
@@ -136,8 +137,14 @@ squat_trie_init(const char *path, uint32
trie->fd = -1;
trie->lock_method = lock_method;
trie->uidvalidity = uidvalidity;
- trie->mmap_disable = mmap_disable;
+ trie->flags = flags;
squat_trie_normalize_map_build(trie);
+
+ trie->dotlock_set.use_excl_lock =
+ (flags & SQUAT_INDEX_FLAG_DOTLOCK_USE_EXCL) != 0;
+ trie->dotlock_set.nfs_flush = (flags & SQUAT_INDEX_FLAG_NFS_FLUSH) != 0;
+ trie->dotlock_set.timeout = SQUAT_TRIE_LOCK_TIMEOUT;
+ trie->dotlock_set.stale_timeout = SQUAT_TRIE_DOTLOCK_STALE_TIMEOUT;
return trie;
}
@@ -254,16 +261,26 @@ void squat_trie_refresh(struct squat_tri
}
static int squat_trie_lock(struct squat_trie *trie, int lock_type,
- struct file_lock **file_lock_r)
+ struct file_lock **file_lock_r,
+ struct dotlock **dotlock_r)
{
int ret;
+ *file_lock_r = NULL;
+ *dotlock_r = NULL;
+
while (trie->fd != -1) {
- ret = file_wait_lock(trie->fd, trie->path, lock_type,
- trie->lock_method, SQUAT_TRIE_LOCK_TIMEOUT,
- file_lock_r);
+ if (trie->lock_method != FILE_LOCK_METHOD_DOTLOCK) {
+ ret = file_wait_lock(trie->fd, trie->path, lock_type,
+ trie->lock_method,
+ SQUAT_TRIE_LOCK_TIMEOUT,
+ file_lock_r);
+ } else {
+ ret = file_dotlock_create(&trie->dotlock_set,
+ trie->path, 0, dotlock_r);
+ }
if (ret == 0) {
- i_error("file_wait_lock(%s) failed: %m", trie->path);
+ i_error("squat trie %s: Locking timed out", trie->path);
return 0;
}
if (ret < 0)
@@ -275,7 +292,10 @@ static int squat_trie_lock(struct squat_
if (ret == 0)
return 1;
- file_unlock(file_lock_r);
+ if (*file_lock_r != NULL)
+ file_unlock(file_lock_r);
+ else
+ file_dotlock_delete(dotlock_r);
if (ret < 0)
return -1;
@@ -1348,7 +1368,9 @@ squat_trie_renumber_uidlists(struct squa
squat_trie_iterate_deinit(iter);
/* lock the trie before we rename uidlist */
- if (squat_trie_lock(ctx->trie, F_WRLCK, &ctx->file_lock) <= 0)
+ i_assert(ctx->file_lock == NULL && ctx->dotlock == NULL);
+ if (squat_trie_lock(ctx->trie, F_WRLCK,
+ &ctx->file_lock, &ctx->dotlock) <= 0)
ret = -1;
return squat_uidlist_rebuild_finish(rebuild_ctx, ret < 0);
}
@@ -1381,7 +1403,7 @@ static int squat_trie_map_header(struct
}
i_assert(trie->fd != -1);
- if (trie->mmap_disable) {
+ if ((trie->flags & SQUAT_INDEX_FLAG_MMAP_DISABLE) != 0) {
ret = pread_full(trie->fd, &trie->hdr, sizeof(trie->hdr), 0);
if (ret <= 0) {
if (ret < 0) {
@@ -1424,19 +1446,24 @@ static int squat_trie_map(struct squat_t
static int squat_trie_map(struct squat_trie *trie, bool building)
{
struct file_lock *file_lock = NULL;
+ struct dotlock *dotlock = NULL;
bool changed;
int ret;
if (trie->fd != -1) {
- if (squat_trie_lock(trie, F_RDLCK, &file_lock) <= 0)
+ if (squat_trie_lock(trie, F_RDLCK, &file_lock, &dotlock) <= 0)
return -1;
- if (trie->mmap_disable && trie->file_cache == NULL)
+ if ((trie->flags & SQUAT_INDEX_FLAG_MMAP_DISABLE) != 0 &&
+ trie->file_cache == NULL)
trie->file_cache = file_cache_new(trie->fd);
}
ret = squat_trie_map_header(trie);
if (ret == 0) {
- file_lock_free(&file_lock);
+ if (file_lock != NULL)
+ file_unlock(&file_lock);
+ else
+ file_dotlock_delete(&dotlock);
squat_trie_delete(trie);
squat_trie_close(trie);
squat_trie_header_init(trie);
@@ -1468,6 +1495,8 @@ static int squat_trie_map(struct squat_t
if (file_lock != NULL)
file_unlock(&file_lock);
+ if (dotlock != NULL)
+ file_dotlock_delete(&dotlock);
if (ret < 0)
return -1;
@@ -1513,10 +1542,11 @@ int squat_trie_build_init(struct squat_t
static int squat_trie_write_lock(struct squat_trie_build_context *ctx)
{
- if (ctx->file_lock != NULL)
+ if (ctx->file_lock != NULL || ctx->dotlock != NULL)
return 0;
- if (squat_trie_lock(ctx->trie, F_WRLCK, &ctx->file_lock) <= 0)
+ if (squat_trie_lock(ctx->trie, F_WRLCK,
+ &ctx->file_lock, &ctx->dotlock) <= 0)
return -1;
return 0;
}
@@ -1540,13 +1570,19 @@ static int squat_trie_write(struct squat
i_error("creat(%s) failed: %m", path);
return -1;
}
- ret = file_wait_lock(fd, path, F_WRLCK, trie->lock_method,
- SQUAT_TRIE_LOCK_TIMEOUT, &file_lock);
- if (ret <= 0) {
- if (ret == 0)
- i_error("file_wait_lock(%s) failed: %m", path);
- (void)close(fd);
- return -1;
+ if (trie->lock_method != FILE_LOCK_METHOD_DOTLOCK) {
+ ret = file_wait_lock(fd, path, F_WRLCK,
+ trie->lock_method,
+ SQUAT_TRIE_LOCK_TIMEOUT,
+ &file_lock);
+ if (ret <= 0) {
+ if (ret == 0) {
+ i_error("file_wait_lock(%s) failed: %m",
+ path);
+ }
+ (void)close(fd);
+ return -1;
+ }
}
output = o_stream_create_fd(fd, 0, FALSE);
@@ -1614,7 +1650,8 @@ static int squat_trie_write(struct squat
if (ret < 0) {
if (unlink(path) < 0 && errno != ENOENT)
i_error("unlink(%s) failed: %m", path);
- file_lock_free(&file_lock);
+ if (file_lock != NULL)
+ file_lock_free(&file_lock);
} else {
squat_trie_close_fd(trie);
trie->fd = fd;
@@ -1659,6 +1696,8 @@ int squat_trie_build_deinit(struct squat
else
file_lock_free(&ctx->file_lock);
}
+ if (ctx->dotlock != NULL)
+ file_dotlock_delete(&ctx->dotlock);
squat_uidlist_build_deinit(&ctx->uidlist_build_ctx);
i_free(ctx);
diff -r d51565e31ceb -r 55712d36224b src/plugins/fts-squat/squat-trie.h
--- a/src/plugins/fts-squat/squat-trie.h Fri Mar 07 07:38:41 2008 +0200
+++ b/src/plugins/fts-squat/squat-trie.h Fri Mar 07 08:15:35 2008 +0200
@@ -3,6 +3,12 @@
#include "file-lock.h"
#include "seq-range-array.h"
+
+enum squat_index_flags {
+ SQUAT_INDEX_FLAG_MMAP_DISABLE = 0x01,
+ SQUAT_INDEX_FLAG_NFS_FLUSH = 0x02,
+ SQUAT_INDEX_FLAG_DOTLOCK_USE_EXCL = 0x04
+};
enum squat_index_type {
SQUAT_INDEX_TYPE_HEADER = 0x01,
@@ -13,7 +19,8 @@ struct squat_trie_build_context;
struct squat_trie *
squat_trie_init(const char *path, uint32_t uidvalidity,
- enum file_lock_method lock_method, bool mmap_disable);
+ enum file_lock_method lock_method,
+ enum squat_index_flags flags);
void squat_trie_deinit(struct squat_trie **trie);
void squat_trie_refresh(struct squat_trie *trie);
diff -r d51565e31ceb -r 55712d36224b src/plugins/fts-squat/squat-uidlist.c
--- a/src/plugins/fts-squat/squat-uidlist.c Fri Mar 07 07:38:41 2008 +0200
+++ b/src/plugins/fts-squat/squat-uidlist.c Fri Mar 07 08:15:35 2008 +0200
@@ -39,6 +39,7 @@ struct squat_uidlist {
struct file_cache *file_cache;
struct file_lock *file_lock;
+ struct dotlock *dotlock;
uoff_t locked_file_size;
void *mmap_base;
@@ -438,7 +439,7 @@ static int squat_uidlist_map(struct squa
return 1;
}
- if (!uidlist->trie->mmap_disable) {
+ if ((uidlist->trie->flags & SQUAT_INDEX_FLAG_MMAP_DISABLE) == 0) {
if (mmap_hdr == NULL || uidlist->building ||
uidlist->mmap_size < mmap_hdr->used_file_size) {
if (squat_uidlist_mmap(uidlist) < 0)
@@ -466,7 +467,8 @@ static int squat_uidlist_map(struct squa
uidlist->data = NULL;
uidlist->data_size = 0;
}
- if (uidlist->file_cache == NULL && uidlist->trie->mmap_disable)
+ if (uidlist->file_cache == NULL &&
+ (uidlist->trie->flags & SQUAT_INDEX_FLAG_MMAP_DISABLE) != 0)
uidlist->file_cache = file_cache_new(uidlist->fd);
return squat_uidlist_map_header(uidlist);
}
@@ -516,6 +518,8 @@ static void squat_uidlist_close(struct s
file_cache_free(&uidlist->file_cache);
if (uidlist->file_lock != NULL)
file_lock_free(&uidlist->file_lock);
+ if (uidlist->dotlock != NULL)
+ file_dotlock_delete(&uidlist->dotlock);
if (uidlist->fd != -1) {
if (close(uidlist->fd) < 0)
More information about the dovecot-cvs
mailing list