dovecot-2.0: mdbox: If flock() isn't available, use dotlock files.
dovecot at dovecot.org
dovecot at dovecot.org
Tue Apr 20 18:08:00 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/0eff8ef104e6
changeset: 11180:0eff8ef104e6
user: Timo Sirainen <tss at iki.fi>
date: Tue Apr 20 18:07:56 2010 +0300
description:
mdbox: If flock() isn't available, use dotlock files.
This allows again using client_limit > 1 without corrupting dbox files.
diffstat:
src/lib-storage/index/dbox-common/dbox-file.c | 28 +++++++++++++++++++++-------
src/lib-storage/index/dbox-common/dbox-file.h | 13 +++++++++++++
2 files changed, 34 insertions(+), 7 deletions(-)
diffs (97 lines):
diff -r 944f4335845f -r 0eff8ef104e6 src/lib-storage/index/dbox-common/dbox-file.c
--- a/src/lib-storage/index/dbox-common/dbox-file.c Tue Apr 20 18:05:08 2010 +0300
+++ b/src/lib-storage/index/dbox-common/dbox-file.c Tue Apr 20 18:07:56 2010 +0300
@@ -9,6 +9,7 @@
#include "istream.h"
#include "ostream.h"
#include "file-lock.h"
+#include "file-dotlock.h"
#include "mkdir-parents.h"
#include "fdatasync-path.h"
#include "eacces-error.h"
@@ -24,12 +25,11 @@
#define DBOX_READ_BLOCK_SIZE 4096
-/* prefer flock(). fcntl() locking currently breaks if trying to access the
- same file from multiple mail_storages within same process. */
-#ifdef HAVE_FLOCK
-# define DBOX_FILE_LOCK_METHOD FILE_LOCK_METHOD_FLOCK
-#else
-# define DBOX_FILE_LOCK_METHOD FILE_LOCK_METHOD_FCNTL
+#if DBOX_FILE_LOCK_METHOD == FILE_LOCK_METHOD_DOTLOCK
+static const struct dotlock_settings dotlock_set = {
+ .stale_timeout = 60*10,
+ .use_excl_lock = TRUE
+};
#endif
const char *dbox_generate_tmp_filename(void)
@@ -298,12 +298,21 @@
i_assert(file->fd != -1);
+#if DBOX_FILE_LOCK_METHOD == FILE_LOCK_METHOD_DOTLOCK
+ ret = file_dotlock_create(&dotlock_set, file->cur_path,
+ DOTLOCK_CREATE_FLAG_NONBLOCK, &file->lock);
+ if (ret < 0) {
+ mail_storage_set_critical(&file->storage->storage,
+ "file_dotlock_create(%s) failed: %m", file->cur_path);
+ }
+#else
ret = file_try_lock(file->fd, file->cur_path, F_WRLCK,
DBOX_FILE_LOCK_METHOD, &file->lock);
if (ret < 0) {
mail_storage_set_critical(&file->storage->storage,
"file_try_lock(%s) failed: %m", file->cur_path);
}
+#endif
return ret;
}
@@ -311,8 +320,13 @@
{
i_assert(!file->appending || file->lock == NULL);
- if (file->lock != NULL)
+ if (file->lock != NULL) {
+#if DBOX_FILE_LOCK_METHOD == FILE_LOCK_METHOD_DOTLOCK
+ (void)file_dotlock_delete(&file->lock);
+#else
file_unlock(&file->lock);
+#endif
+ }
if (file->input != NULL)
i_stream_sync(file->input);
}
diff -r 944f4335845f -r 0eff8ef104e6 src/lib-storage/index/dbox-common/dbox-file.h
--- a/src/lib-storage/index/dbox-common/dbox-file.h Tue Apr 20 18:05:08 2010 +0300
+++ b/src/lib-storage/index/dbox-common/dbox-file.h Tue Apr 20 18:07:56 2010 +0300
@@ -19,6 +19,15 @@
#define DBOX_MAGIC_PRE "\001\002"
#define DBOX_MAGIC_POST "\n\001\003\n"
+/* prefer flock(). fcntl() locking currently breaks if trying to access the
+ same file from multiple mail_storages within same process. that's why we
+ fallback to dotlocks. */
+#ifdef HAVE_FLOCK
+# define DBOX_FILE_LOCK_METHOD FILE_LOCK_METHOD_FLOCK
+#else
+# define DBOX_FILE_LOCK_METHOD FILE_LOCK_METHOD_DOTLOCK
+#endif
+
struct dbox_file;
enum dbox_header_key {
@@ -97,7 +106,11 @@
char *primary_path, *alt_path;
int fd;
struct istream *input;
+#if DBOX_FILE_LOCK_METHOD == FILE_LOCK_METHOD_DOTLOCK
+ struct dotlock *lock;
+#else
struct file_lock *lock;
+#endif
uoff_t cur_offset;
uoff_t cur_physical_size;
More information about the dovecot-cvs
mailing list