[dovecot-cvs] dovecot/src/lib-index/mbox mbox-lock.c,1.26,1.27
cras at procontrol.fi
cras at procontrol.fi
Fri Feb 14 14:56:34 EET 2003
Update of /home/cvs/dovecot/src/lib-index/mbox
In directory danu:/tmp/cvs-serv22162/lib-index/mbox
Modified Files:
mbox-lock.c
Log Message:
Don't even try to override mbox dotlock if we can't get fcntl/flock.
Index: mbox-lock.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-lock.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- mbox-lock.c 12 Feb 2003 12:07:51 -0000 1.26
+++ mbox-lock.c 14 Feb 2003 12:56:32 -0000 1.27
@@ -25,6 +25,12 @@
/* assume stale dotlock if mbox file hasn't changed for n seconds */
#define DEFAULT_DOTLOCK_CHANGE_TIMEOUT 30
+struct dotlock_context {
+ struct mail_index *index;
+ enum mail_lock_type lock_type;
+ int last_stale;
+};
+
static int lock_settings_initialized = FALSE;
static int use_dotlock, use_fcntl_lock, use_flock, fcntl_before_flock;
static int use_read_dotlock, lock_timeout, dotlock_change_timeout;
@@ -82,8 +88,11 @@
return FALSE;
}
+ if (max_wait_time == 0)
+ return FALSE;
+
now = time(NULL);
- if (max_wait_time != 0 && now >= max_wait_time) {
+ if (now >= max_wait_time) {
index->mailbox_lock_timeout = TRUE;
index_set_error(index, "Timeout while waiting for "
"release of flock() lock for mbox file "
@@ -110,15 +119,18 @@
{
struct flock fl;
time_t now;
+ int wait_type;
fl.l_type = MAIL_LOCK_TO_FLOCK(lock_type);
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
- while (fcntl(index->mbox_fd, F_SETLKW, &fl) == -1) {
+ wait_type = max_wait_time == 0 ? F_SETLK : F_SETLKW;
+ while (fcntl(index->mbox_fd, wait_type, &fl) < 0) {
if (errno != EINTR) {
- mbox_set_syscall_error(index, "fcntl()");
+ if (errno != EAGAIN && errno != EACCES)
+ mbox_set_syscall_error(index, "fcntl()");
return FALSE;
}
@@ -137,44 +149,82 @@
index->lock_notify_context);
}
}
-
return TRUE;
}
-static int mbox_file_locks(struct mail_index *index, time_t max_wait_time)
+static int mbox_file_locks(struct mail_index *index,
+ enum mail_lock_type lock_type, time_t max_wait_time)
{
+ struct stat st;
+
+ /* now we need to have the file itself locked. open it if needed. */
+ if (stat(index->mailbox_path, &st) < 0)
+ return mbox_set_syscall_error(index, "stat()");
+
+ if (st.st_dev != index->mbox_dev || st.st_ino != index->mbox_ino)
+ mbox_file_close_fd(index);
+
+ if (index->mbox_fd == -1) {
+ if (!mbox_file_open(index)) {
+ (void)mbox_unlock(index);
+ return FALSE;
+ }
+ }
+
if (use_fcntl_lock && fcntl_before_flock) {
- if (!mbox_lock_fcntl(index, index->mbox_lock_type,
- max_wait_time))
+ if (!mbox_lock_fcntl(index, lock_type, max_wait_time))
return FALSE;
}
#ifdef HAVE_FLOCK
if (use_flock) {
- if (!mbox_lock_flock(index, index->mbox_lock_type,
- max_wait_time))
+ if (!mbox_lock_flock(index, lock_type, max_wait_time))
return FALSE;
}
#endif
if (use_fcntl_lock && !fcntl_before_flock) {
- if (!mbox_lock_fcntl(index, index->mbox_lock_type,
- max_wait_time))
+ if (!mbox_lock_fcntl(index, lock_type, max_wait_time))
return FALSE;
}
return TRUE;
}
-static void dotlock_callback(unsigned int secs_left, int stale, void *context)
+static int mbox_file_unlock(struct mail_index *index)
{
- struct mail_index *index = context;
+ int failed = FALSE;
- index->lock_notify_cb(stale ? MAIL_LOCK_NOTIFY_MAILBOX_OVERRIDE :
- MAIL_LOCK_NOTIFY_MAILBOX_ABORT,
- secs_left, index->lock_notify_context);
+#ifdef HAVE_FLOCK
+ if (use_flock && !mbox_lock_flock(index, MAIL_LOCK_UNLOCK, 0))
+ failed = TRUE;
+#endif
+ if (use_fcntl_lock &&
+ !mbox_lock_fcntl(index, MAIL_LOCK_UNLOCK, 0))
+ failed = TRUE;
+
+ return !failed;
+}
+
+static int dotlock_callback(unsigned int secs_left, int stale, void *context)
+{
+ struct dotlock_context *ctx = context;
+
+ if (stale && !ctx->last_stale) {
+ if (!mbox_file_locks(ctx->index, ctx->lock_type, 0)) {
+ /* we couldn't get fcntl/flock - it's really locked */
+ ctx->last_stale = TRUE;
+ return FALSE;
+ }
+ (void)mbox_file_unlock(ctx->index);
+ }
+ ctx->last_stale = stale;
+
+ ctx->index->lock_notify_cb(stale ? MAIL_LOCK_NOTIFY_MAILBOX_OVERRIDE :
+ MAIL_LOCK_NOTIFY_MAILBOX_ABORT,
+ secs_left, ctx->index->lock_notify_context);
+ return TRUE;
}
int mbox_lock(struct mail_index *index, enum mail_lock_type lock_type)
{
- struct stat st;
time_t max_wait_time;
int ret;
@@ -197,11 +247,17 @@
/* make .lock file first to protect overwriting the file */
if (use_dotlock && index->mbox_dotlock.ino == 0) {
+ struct dotlock_context ctx;
+
+ ctx.index = index;
+ ctx.lock_type = lock_type;
+ ctx.last_stale = -1;
+
ret = file_lock_dotlock(index->mailbox_path,
lock_type == MAIL_LOCK_SHARED &&
!use_read_dotlock, lock_timeout,
dotlock_change_timeout,
- dotlock_callback, index,
+ dotlock_callback, &ctx,
&index->mbox_dotlock);
if (ret < 0) {
@@ -217,22 +273,8 @@
}
}
- /* now we need to have the file itself locked. open it if needed. */
- if (stat(index->mailbox_path, &st) < 0)
- return mbox_set_syscall_error(index, "stat()");
-
- if (st.st_dev != index->mbox_dev || st.st_ino != index->mbox_ino)
- mbox_file_close_fd(index);
-
- if (index->mbox_fd == -1) {
- if (!mbox_file_open(index)) {
- (void)mbox_unlock(index);
- return FALSE;
- }
- }
-
index->mbox_lock_type = lock_type;
- if (!mbox_file_locks(index, max_wait_time)) {
+ if (!mbox_file_locks(index, index->mbox_lock_type, max_wait_time)) {
(void)mbox_unlock(index);
return FALSE;
}
@@ -251,12 +293,7 @@
failed = FALSE;
if (index->mbox_fd != -1) {
-#ifdef HAVE_FLOCK
- if (use_flock && !mbox_lock_flock(index, MAIL_LOCK_UNLOCK, 0))
- failed = TRUE;
-#endif
- if (use_fcntl_lock &&
- !mbox_lock_fcntl(index, MAIL_LOCK_UNLOCK, 0))
+ if (!mbox_file_unlock(index))
failed = TRUE;
}
More information about the dovecot-cvs
mailing list