[dovecot-cvs] dovecot/src/lib-index mail-cache.c, 1.48,
1.49 mail-index-lock.c, 1.32, 1.33 mail-index-private.h, 1.30,
1.31 mail-index-view.c, 1.23, 1.24 mail-index.c, 1.152,
1.153 mail-index.h, 1.131, 1.132 mail-transaction-log.c, 1.62, 1.63
cras at dovecot.org
cras at dovecot.org
Sun Oct 10 20:25:47 EEST 2004
Update of /var/lib/cvs/dovecot/src/lib-index
In directory talvi:/tmp/cvs-serv11749/src/lib-index
Modified Files:
mail-cache.c mail-index-lock.c mail-index-private.h
mail-index-view.c mail-index.c mail-index.h
mail-transaction-log.c
Log Message:
Replaced fcntl_locks_disable with lock_method, so it's now possible to use
flock() to lock indexes.
Index: mail-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-cache.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -d -r1.48 -r1.49
--- mail-cache.c 8 Oct 2004 17:51:48 -0000 1.48
+++ mail-cache.c 10 Oct 2004 17:25:44 -0000 1.49
@@ -3,7 +3,6 @@
#include "lib.h"
#include "buffer.h"
#include "hash.h"
-#include "file-lock.h"
#include "mmap-util.h"
#include "write-full.h"
#include "mail-cache-private.h"
@@ -257,8 +256,11 @@
}
for (i = 0; i < 3; i++) {
- if ((ret = file_wait_lock(cache->fd, F_WRLCK)) <= 0) {
- mail_cache_set_syscall_error(cache, "file_wait_lock()");
+ ret = mail_index_lock_fd(cache->index, cache->fd, F_WRLCK,
+ MAIL_INDEX_LOCK_SECS);
+ if (ret <= 0) {
+ mail_cache_set_syscall_error(cache,
+ "mail_index_wait_lock_fd()");
break;
}
cache->locked = TRUE;
@@ -321,8 +323,10 @@
mail_cache_update_need_compress(cache);
}
- if (file_wait_lock(cache->fd, F_UNLCK) <= 0)
- mail_cache_set_syscall_error(cache, "file_wait_lock(F_UNLCK)");
+ if (mail_index_lock_fd(cache->index, cache->fd, F_UNLCK, 0) <= 0) {
+ mail_cache_set_syscall_error(cache,
+ "mail_index_wait_lock_fd(F_UNLCK)");
+ }
}
struct mail_cache_view *
Index: mail-index-lock.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-lock.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- mail-index-lock.c 5 Sep 2004 17:53:45 -0000 1.32
+++ mail-index-lock.c 10 Oct 2004 17:25:44 -0000 1.33
@@ -21,13 +21,92 @@
#include "lib.h"
#include "buffer.h"
#include "mmap-util.h"
-#include "file-lock.h"
#include "write-full.h"
#include "mail-index-private.h"
#include <stdio.h>
#include <sys/stat.h>
+#ifdef HAVE_FLOCK
+# include <sys/file.h>
+#endif
+
+#define MAIL_INDEX_LOCK_WAIT_TIME 120
+
+int mail_index_lock_fd(struct mail_index *index, int fd, int lock_type,
+ unsigned int timeout_secs)
+{
+ if (timeout_secs != 0) alarm(MAIL_INDEX_LOCK_WAIT_TIME);
+
+ switch (index->lock_method) {
+ case MAIL_INDEX_LOCK_FCNTL: {
+#ifndef HAVE_FCNTL
+ i_fatal("fcntl() locks not supported");
+#else
+ struct flock fl;
+
+ fl.l_type = lock_type;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+
+ if (fcntl(fd, timeout_secs ? F_SETLKW : F_SETLK, &fl) < 0) {
+ if (timeout_secs == 0 &&
+ (errno == EACCES || errno == EAGAIN)) {
+ /* locked by another process */
+ return 0;
+ }
+
+ if (errno == EINTR) {
+ /* most likely alarm hit, meaning we timeouted.
+ even if not, we probably want to be killed
+ so stop blocking. */
+ errno = EAGAIN;
+ if (timeout_secs != 0) alarm(0);
+ return 0;
+ }
+ }
+ if (timeout_secs != 0) alarm(0);
+ return 1;
+#endif
+ }
+ case MAIL_INDEX_LOCK_FLOCK: {
+#ifndef HAVE_FLOCK
+ i_fatal("flock() locks not supported");
+#else
+ int operation = timeout_secs != 0 ? 0 : LOCK_NB;
+
+ switch (lock_type) {
+ case F_RDLCK:
+ operation |= LOCK_SH;
+ break;
+ case F_WRLCK:
+ operation |= LOCK_EX;
+ break;
+ case F_UNLCK:
+ operation |= LOCK_UN;
+ break;
+ }
+
+ if (flock(fd, operation) < 0) {
+ if (errno == EWOULDBLOCK || errno == EINTR) {
+ /* a) locked by another process,
+ b) timeouted */
+ if (timeout_secs != 0) alarm(0);
+ return 0;
+ }
+ }
+ if (timeout_secs != 0) alarm(0);
+ return 1;
+#endif
+ }
+ case MAIL_INDEX_LOCK_DOTLOCK:
+ /* we shouldn't get here */
+ break;
+ }
+ i_unreached();
+}
+
int mail_index_map_lock_mprotect(struct mail_index *index,
struct mail_index_map *map, int lock_type)
{
@@ -91,7 +170,7 @@
if (ret > 0)
return 1;
- if (index->fcntl_locks_disable) {
+ if (index->lock_type == MAIL_INDEX_LOCK_DOTLOCK) {
/* FIXME: exclusive locking will rewrite the index file every
time. shouldn't really be needed.. reading doesn't require
locks then, though */
@@ -111,12 +190,8 @@
}
if (lock_type == F_RDLCK || !index->log_locked) {
- ret = file_wait_lock_full(index->fd, lock_type, timeout_secs,
- NULL, NULL);
- if (ret < 0) {
- mail_index_set_syscall_error(index, "file_wait_lock()");
- return -1;
- }
+ ret = mail_index_lock_fd(index, index->fd, lock_type,
+ timeout_secs);
} else {
/* this is kind of kludgy. we wish to avoid deadlocks while
trying to lock transaction log, but it can happen if our
@@ -132,14 +207,14 @@
so, the workaround for this problem is that we simply try
locking once. if it doesn't work, just rewrite the file.
hopefully there won't be any other deadlocking issues. :) */
- ret = file_try_lock(index->fd, lock_type);
- if (ret < 0) {
- mail_index_set_syscall_error(index, "file_try_lock()");
- return -1;
- }
+ ret = mail_index_lock_fd(index, index->fd, lock_type, 0);
+ }
+ if (ret <= 0) {
+ if (ret == 0)
+ return 0;
+ mail_index_set_syscall_error(index, "mail_index_lock_fd()");
+ return -1;
}
- if (ret == 0)
- return 0;
if (index->lock_type == F_UNLCK)
index->lock_id += 2;
@@ -163,7 +238,7 @@
{
int ret;
- ret = mail_index_lock(index, F_RDLCK, DEFAULT_LOCK_TIMEOUT,
+ ret = mail_index_lock(index, F_RDLCK, MAIL_INDEX_LOCK_SECS,
update_index, lock_id_r);
if (ret > 0)
return 0;
@@ -340,12 +415,12 @@
(void)close(fd);
}
- if (index->shared_lock_count > 0 && !index->fcntl_locks_disable) {
+ if (index->shared_lock_count > 0 &&
+ index->lock_method != MAIL_INDEX_LOCK_DOTLOCK) {
/* leave ourself shared locked. */
- if (file_try_lock(index->fd, F_RDLCK) <= 0) {
+ if (mail_index_lock_fd(index, index->fd, F_RDLCK, 0) <= 0) {
mail_index_file_set_syscall_error(index,
- index->copy_lock_path,
- "file_try_lock()");
+ index->copy_lock_path, "mail_index_lock_fd()");
}
i_assert(index->lock_type == F_WRLCK);
index->lock_type = F_RDLCK;
@@ -384,10 +459,11 @@
index->lock_id += 2;
index->lock_type = F_UNLCK;
(void)mail_index_lock_mprotect(index, F_UNLCK);
- if (!index->fcntl_locks_disable) {
- if (file_wait_lock(index->fd, F_UNLCK) < 0) {
+ if (index->lock_method != MAIL_INDEX_LOCK_DOTLOCK) {
+ if (mail_index_lock_fd(index, index->fd,
+ F_UNLCK, 0) < 0) {
mail_index_set_syscall_error(index,
- "file_wait_lock()");
+ "mail_index_lock_fd()");
}
}
}
Index: mail-index-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-private.h,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- mail-index-private.h 3 Oct 2004 16:32:59 -0000 1.30
+++ mail-index-private.h 10 Oct 2004 17:25:44 -0000 1.31
@@ -1,11 +1,17 @@
#ifndef __MAIL_INDEX_PRIVATE_H
#define __MAIL_INDEX_PRIVATE_H
+/* Make sure F_RDLCK, F_WRLCK and F_UNLCK get defined */
+#include <unistd.h>
+#include <fcntl.h>
+
#include "file-dotlock.h"
#include "mail-index.h"
struct mail_transaction_header;
+/* How many seconds to wait a lock for index file. */
+#define MAIL_INDEX_LOCK_SECS 120
/* Index file is grown exponentially when we're adding less than this many
records. */
#define MAIL_INDEX_MAX_POWER_GROW (1024*1024 / sizeof(struct mail_index_record))
@@ -91,6 +97,7 @@
unsigned int lock_id;
char *copy_lock_path;
struct dotlock dotlock;
+ enum mail_index_lock_method lock_method;
unsigned int last_grow_count;
@@ -102,7 +109,6 @@
unsigned int log_locked:1;
unsigned int mmap_disable:1;
unsigned int mmap_no_write:1;
- unsigned int fcntl_locks_disable:1;
unsigned int readonly:1;
unsigned int fsck:1;
};
@@ -127,6 +133,9 @@
int mail_index_map_lock_mprotect(struct mail_index *index,
struct mail_index_map *map, int lock_type);
+int mail_index_lock_fd(struct mail_index *index, int fd, int lock_type,
+ unsigned int timeout_secs);
+
/* Map index file to memory, replacing the previous mapping for index.
Returns 1 = ok, 0 = corrupted, -1 = error. If index needs fscking, it
returns 1 but sets index->fsck = TRUE. */
Index: mail-index-view.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index-view.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- mail-index-view.c 10 Oct 2004 13:55:12 -0000 1.23
+++ mail-index-view.c 10 Oct 2004 17:25:44 -0000 1.24
@@ -2,7 +2,6 @@
#include "lib.h"
#include "buffer.h"
-#include "file-lock.h"
#include "mail-index-view-private.h"
#include "mail-transaction-log.h"
Index: mail-index.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index.c,v
retrieving revision 1.152
retrieving revision 1.153
diff -u -d -r1.152 -r1.153
--- mail-index.c 9 Oct 2004 14:20:21 -0000 1.152
+++ mail-index.c 10 Oct 2004 17:25:44 -0000 1.153
@@ -2,7 +2,6 @@
#include "lib.h"
#include "buffer.h"
-#include "file-lock.h"
#include "mmap-util.h"
#include "read-full.h"
#include "write-full.h"
@@ -948,7 +947,8 @@
return 1;
}
-int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags)
+int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags,
+ enum mail_index_lock_method lock_method)
{
int i = 0, ret;
@@ -963,6 +963,7 @@
index->lock_type = F_UNLCK;
index->lock_id = 2;
+ index->readonly = FALSE;
index->nodiskspace = FALSE;
index->index_lock_timeout = FALSE;
index->log_locked = FALSE;
@@ -970,9 +971,7 @@
(flags & MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE) != 0;
index->mmap_no_write =
(flags & MAIL_INDEX_OPEN_FLAG_MMAP_NO_WRITE) != 0;
- index->fcntl_locks_disable =
- (flags & MAIL_INDEX_OPEN_FLAG_FCNTL_LOCKS_DISABLE) != 0;
- index->readonly = FALSE;
+ index->lock_method = lock_method;
ret = mail_index_open_files(index, flags);
if (ret <= 0)
Index: mail-index.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-index.h,v
retrieving revision 1.131
retrieving revision 1.132
diff -u -d -r1.131 -r1.132
--- mail-index.h 4 Oct 2004 16:31:51 -0000 1.131
+++ mail-index.h 10 Oct 2004 17:25:44 -0000 1.132
@@ -23,9 +23,13 @@
/* Don't try to write() to mmap()ed index files. Required for the few
OSes that don't have unified buffer cache
(currently OpenBSD <= 3.5) */
- MAIL_INDEX_OPEN_FLAG_MMAP_NO_WRITE = 0x08,
- /* Don't use fcntl() locking */
- MAIL_INDEX_OPEN_FLAG_FCNTL_LOCKS_DISABLE= 0x10
+ MAIL_INDEX_OPEN_FLAG_MMAP_NO_WRITE = 0x08
+};
+
+enum mail_index_lock_method {
+ MAIL_INDEX_LOCK_FCNTL,
+ MAIL_INDEX_LOCK_FLOCK,
+ MAIL_INDEX_LOCK_DOTLOCK
};
enum mail_index_header_compat_flags {
@@ -140,7 +144,8 @@
void mail_index_set_permissions(struct mail_index *index,
mode_t mode, gid_t gid);
-int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags);
+int mail_index_open(struct mail_index *index, enum mail_index_open_flags flags,
+ enum mail_index_lock_method lock_method);
void mail_index_close(struct mail_index *index);
/* Force checking if index can be refreshed. */
Index: mail-transaction-log.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-index/mail-transaction-log.c,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -d -r1.62 -r1.63
--- mail-transaction-log.c 8 Oct 2004 17:51:48 -0000 1.62
+++ mail-transaction-log.c 10 Oct 2004 17:25:44 -0000 1.63
@@ -3,7 +3,6 @@
#include "lib.h"
#include "ioloop.h"
#include "buffer.h"
-#include "file-lock.h"
#include "file-dotlock.h"
#include "read-full.h"
#include "write-full.h"
@@ -129,11 +128,11 @@
if (file->locked)
return 0;
- if (file->log->index->fcntl_locks_disable)
+ if (file->log->index->lock_type == MAIL_INDEX_LOCK_DOTLOCK)
return mail_transaction_log_file_dotlock(file);
- ret = file_wait_lock_full(file->fd, F_WRLCK, DEFAULT_LOCK_TIMEOUT,
- NULL, NULL);
+ ret = mail_index_lock_fd(file->log->index, file->fd, F_WRLCK,
+ MAIL_INDEX_LOCK_SECS);
if (ret > 0) {
file->locked = TRUE;
return 0;
@@ -141,7 +140,7 @@
if (ret < 0) {
mail_index_file_set_syscall_error(file->log->index,
file->filepath,
- "file_wait_lock()");
+ "mail_index_wait_lock_fd()");
return -1;
}
@@ -163,16 +162,16 @@
file->locked = FALSE;
- if (file->log->index->fcntl_locks_disable) {
+ if (file->log->index->lock_method == MAIL_INDEX_LOCK_DOTLOCK) {
mail_transaction_log_file_undotlock(file);
return;
}
- ret = file_wait_lock(file->fd, F_UNLCK);
+ ret = mail_index_lock_fd(file->log->index, file->fd, F_UNLCK, 0);
if (ret <= 0) {
mail_index_file_set_syscall_error(file->log->index,
file->filepath,
- "file_wait_lock()");
+ "mail_index_wait_lock_fd()");
}
}
More information about the dovecot-cvs
mailing list