[dovecot-cvs] dovecot/src/lib-index/mbox mbox-index.c,1.42,1.43 mbox-index.h,1.19,1.20 mbox-lock.c,1.10,1.11 mbox-rewrite.c,1.34,1.35 mbox-sync-full.c,1.2,1.3 mbox-sync.c,1.16,1.17
cras at procontrol.fi
cras at procontrol.fi
Sat Nov 2 22:10:23 EET 2002
- Previous message: [dovecot-cvs] dovecot/src/lib-index mail-index-open.c,1.12,1.13 mail-index-update-cache.c,1.9,1.10 mail-index.c,1.66,1.67 mail-index.h,1.48,1.49 mail-tree.c,1.8,1.9
- Next message: [dovecot-cvs] dovecot/src/lib-storage mail-storage.h,1.17,1.18
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/dovecot/src/lib-index/mbox
In directory danu:/tmp/cvs-serv8907/lib-index/mbox
Modified Files:
mbox-index.c mbox-index.h mbox-lock.c mbox-rewrite.c
mbox-sync-full.c mbox-sync.c
Log Message:
Mostly mbox locking/syncing fixes. Still some problems though.
Index: mbox-index.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-index.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- mbox-index.c 27 Oct 2002 06:37:18 -0000 1.42
+++ mbox-index.c 2 Nov 2002 20:10:20 -0000 1.43
@@ -701,6 +701,20 @@
i_free(index);
}
+static int mbox_index_set_lock(MailIndex *index, MailLockType lock_type)
+{
+ if (lock_type == MAIL_LOCK_UNLOCK)
+ (void)mbox_unlock(index);
+ return mail_index_set_lock(index, lock_type);
+}
+
+static int mbox_index_try_lock(MailIndex *index, MailLockType lock_type)
+{
+ if (lock_type == MAIL_LOCK_UNLOCK)
+ (void)mbox_unlock(index);
+ return mail_index_try_lock(index, lock_type);
+}
+
static int mbox_index_update_flags(MailIndex *index, MailIndexRecord *rec,
unsigned int seq, MailFlags flags,
int external_change)
@@ -719,8 +733,8 @@
mail_index_open,
mail_index_open_or_create,
mbox_index_free,
- mail_index_set_lock,
- mail_index_try_lock,
+ mbox_index_set_lock,
+ mbox_index_try_lock,
mbox_index_rebuild,
mail_index_fsck,
mbox_index_sync,
Index: mbox-index.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-index.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- mbox-index.h 27 Oct 2002 06:37:18 -0000 1.19
+++ mbox-index.h 2 Nov 2002 20:10:20 -0000 1.20
@@ -48,7 +48,7 @@
MailIndex *mbox_index_alloc(const char *dir, const char *mbox_path);
int mbox_index_rebuild(MailIndex *index);
-int mbox_index_sync(MailIndex *index);
+int mbox_index_sync(MailIndex *index, MailLockType lock_type, int *changes);
int mbox_sync_full(MailIndex *index);
IBuffer *mbox_open_mail(MailIndex *index, MailIndexRecord *rec,
time_t *internal_date, int *deleted);
Index: mbox-lock.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-lock.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- mbox-lock.c 29 Oct 2002 06:46:47 -0000 1.10
+++ mbox-lock.c 2 Nov 2002 20:10:20 -0000 1.11
@@ -151,6 +151,10 @@
{
struct stat st;
+ /* index must be locked before mbox file, to avoid deadlocks */
+ i_assert(index->lock_type != MAIL_LOCK_UNLOCK);
+
+ /* allow only unlock -> shared/exclusive or exclusive -> shared */
i_assert(lock_type == MAIL_LOCK_SHARED ||
lock_type == MAIL_LOCK_EXCLUSIVE);
i_assert(lock_type != MAIL_LOCK_EXCLUSIVE ||
@@ -200,7 +204,6 @@
int failed;
index->mbox_lock_counter++;
- index->mbox_lock_next_sync = MAIL_LOCK_UNLOCK;
if (index->mbox_lock_type == MAIL_LOCK_UNLOCK)
return TRUE;
Index: mbox-rewrite.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-rewrite.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -d -r1.34 -r1.35
--- mbox-rewrite.c 29 Oct 2002 18:01:10 -0000 1.34
+++ mbox-rewrite.c 2 Nov 2002 20:10:20 -0000 1.35
@@ -406,9 +406,17 @@
unsigned int seq;
int tmp_fd, failed, dirty_found, rewrite;
- i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE);
+ i_assert(index->lock_type == MAIL_LOCK_UNLOCK);
- if ((index->header->flags & MAIL_INDEX_FLAG_DIRTY_MESSAGES) == 0) {
+ if (!index->set_lock(index, MAIL_LOCK_SHARED))
+ return FALSE;
+
+ rewrite = (index->header->flags & MAIL_INDEX_FLAG_DIRTY_MESSAGES);
+
+ if (!index->set_lock(index, MAIL_LOCK_UNLOCK))
+ return FALSE;
+
+ if (!rewrite) {
/* no need to rewrite */
return TRUE;
}
@@ -417,8 +425,7 @@
failed = TRUE; rewrite = FALSE;
do {
/* make sync() lock the file to prevent race conditions */
- index->mbox_lock_next_sync = MAIL_LOCK_EXCLUSIVE;
- if (!index->sync(index))
+ if (!index->sync_and_lock(index, MAIL_LOCK_EXCLUSIVE, NULL))
break;
inbuf = mbox_get_inbuf(index, 0, MAIL_LOCK_EXCLUSIVE);
@@ -442,6 +449,8 @@
if (!rewrite) {
(void)mbox_unlock(index);
+ if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
+ failed = TRUE;
if (inbuf != NULL)
i_buffer_unref(inbuf);
return !failed;
@@ -455,10 +464,9 @@
}
dirty_offset = 0;
- //offset = hdr_size = body_size = 0; /* just to keep compiler happy */
-
- t_push();
- outbuf = o_buffer_create_file(tmp_fd, data_stack_pool, 8192, 0, FALSE);
+ /* note: we can't use data_stack_pool with outbuf because it's
+ being written to inside t_push() .. t_pop() calls */
+ outbuf = o_buffer_create_file(tmp_fd, system_pool, 8192, 0, FALSE);
failed = FALSE; seq = 1;
rec = index->lookup(index, 1);
@@ -535,7 +543,6 @@
i_buffer_unref(inbuf);
o_buffer_unref(outbuf);
- t_pop();
if (!failed) {
/* POSSIBLE DATA LOSS HERE. We're writing to the mbox file,
@@ -565,10 +572,13 @@
}
}
+ if (!index->set_lock(index, MAIL_LOCK_UNLOCK))
+ failed = TRUE;
+
(void)mbox_unlock(index);
(void)unlink(path);
if (close(tmp_fd) < 0)
index_file_set_syscall_error(index, path, "close()");
- return failed;
+ return !failed;
}
Index: mbox-sync-full.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-sync-full.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- mbox-sync-full.c 27 Oct 2002 06:37:18 -0000 1.2
+++ mbox-sync-full.c 2 Nov 2002 20:10:21 -0000 1.3
@@ -47,6 +47,7 @@
{
const void *part_data;
void *part_data_copy;
+ uoff_t virtual_size;
size_t size;
/* update FIELD_HDR_HEADER_SIZE */
@@ -54,10 +55,15 @@
&hdr_size->physical_size,
sizeof(hdr_size->physical_size));
+ /* reset FIELD_HDR_VIRTUAL_SIZE - we don't know it anymore */
+ virtual_size = (uoff_t)-1;
+ index->update_field_raw(update, DATA_HDR_VIRTUAL_SIZE,
+ &virtual_size, sizeof(virtual_size));
+
+ /* update DATA_FIELD_MESSAGEPART */
if ((rec->data_fields & DATA_FIELD_MESSAGEPART) == 0)
return TRUE;
- /* update DATA_FIELD_MESSAGEPART */
part_data = index->lookup_field_raw(index, rec, DATA_FIELD_MESSAGEPART,
&size);
if (part_data == NULL) {
@@ -77,10 +83,9 @@
return FALSE;
}
- t_pop();
-
index->update_field_raw(update, DATA_FIELD_MESSAGEPART,
part_data_copy, size);
+ t_pop();
return TRUE;
}
@@ -183,9 +188,6 @@
unsigned int seq;
int dirty;
- if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
- return FALSE;
-
mbox_skip_empty_lines(inbuf);
/* first make sure we start with a "From " line. If file is too
@@ -217,6 +219,10 @@
if (!mbox_skip_crlf(inbuf)) {
/* they just went and broke it, even while
we had it locked. */
+ index_set_error(index,
+ "Error syncing mbox file %s: "
+ "LF not found where expected",
+ index->mbox_path);
return FALSE;
}
}
@@ -258,18 +264,20 @@
int mbox_sync_full(MailIndex *index)
{
IBuffer *inbuf;
- int failed, unlock;
+ int failed;
+
+ if (index->lock_type == MAIL_LOCK_SHARED)
+ (void)mail_index_set_lock(index, MAIL_LOCK_UNLOCK);
+
+ if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
+ return FALSE;
- unlock = index->mbox_lock_type == MAIL_LOCK_UNLOCK;
inbuf = mbox_get_inbuf(index, 0, MAIL_LOCK_SHARED);
if (inbuf == NULL)
return FALSE;
failed = !mbox_sync_buf(index, inbuf);
i_buffer_unref(inbuf);
-
- if (unlock)
- (void)mbox_unlock(index);
return !failed;
}
Index: mbox-sync.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-index/mbox/mbox-sync.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- mbox-sync.c 27 Oct 2002 06:37:18 -0000 1.16
+++ mbox-sync.c 2 Nov 2002 20:10:21 -0000 1.17
@@ -33,9 +33,6 @@
offset += hdr_size + body_size;
}
- if (index->lock_type == MAIL_LOCK_SHARED)
- (void)mail_index_set_lock(index, MAIL_LOCK_UNLOCK);
-
if (offset > OFF_T_MAX) {
/* too large to fit in off_t */
return 0;
@@ -44,17 +41,16 @@
return offset;
}
-int mbox_index_sync(MailIndex *index)
+int mbox_index_sync(MailIndex *index, MailLockType lock_type, int *changes)
{
struct stat st;
- MailLockType lock_type;
time_t index_mtime;
uoff_t filesize;
i_assert(index->lock_type != MAIL_LOCK_SHARED);
- lock_type = index->mbox_lock_next_sync;
- index->mbox_lock_next_sync = MAIL_LOCK_UNLOCK;
+ if (changes != NULL)
+ *changes = FALSE;
index->mbox_sync_counter = index->mbox_lock_counter;
if (index->fd == -1) {
@@ -79,34 +75,60 @@
mbox_file_close_fd(index);
}
- if (lock_type != MAIL_LOCK_UNLOCK) {
- if (!mbox_lock(index, lock_type))
+ if (lock_type == MAIL_LOCK_EXCLUSIVE) {
+ /* if we know that we want exclusive lock, we might get
+ it immediately to save extra lock changes */
+ if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
return FALSE;
}
- if (index_mtime == st.st_mtime && index->mbox_size == filesize)
- return TRUE;
+ if (index_mtime != st.st_mtime || index->mbox_size != filesize) {
+ mbox_file_close_inbuf(index);
- mbox_file_close_inbuf(index);
+ /* problem .. index->mbox_size points to data after the last
+ message. that should be \n or end of file. modify filesize
+ accordingly to allow the extra byte. Don't actually bother
+ to open the file and verify it, it'd just slow things.. */
+ index->mbox_size = get_indexed_mbox_size(index);
+ if (filesize == index->mbox_size+1)
+ index->mbox_size = filesize;
- /* problem .. index->mbox_size points to data after the last message.
- that should be \n, \r\n, or end of file. modify filesize
- accordingly to allow any of the extra 0-2 bytes. Don't actually
- bother to open the file and verify it, it'd just slow things.. */
- index->mbox_size = get_indexed_mbox_size(index);
- if (filesize == index->mbox_size+1 ||
- filesize == index->mbox_size+2)
- index->mbox_size = filesize;
+ if (index->file_sync_stamp == 0 &&
+ index->mbox_size == filesize) {
+ /* just opened the mailbox, and the file size is same
+ as we expected. don't bother checking it any
+ further. */
+ } else {
+ if (changes != NULL)
+ *changes = TRUE;
+
+ /* file has changed, scan through the whole mbox */
+ if (!mbox_sync_full(index)) {
+ (void)index->set_lock(index, MAIL_LOCK_UNLOCK);
+ return FALSE;
+ }
+
+ if (lock_type == MAIL_LOCK_EXCLUSIVE &&
+ index->mbox_lock_type == MAIL_LOCK_SHARED) {
+ /* mbox_sync_full() left it */
+ if (!mbox_unlock(index))
+ return FALSE;
+ }
+ }
- if (index->file_sync_stamp == 0 && index->mbox_size == filesize) {
- /* just opened the mailbox, and the file size is same as
- we expected. don't bother checking it any further. */
index->file_sync_stamp = st.st_mtime;
- return TRUE;
}
- index->file_sync_stamp = st.st_mtime;
+ if (!index->set_lock(index, lock_type))
+ return FALSE;
- /* file has changed, scan through the whole mbox */
- return mbox_sync_full(index);
+ if (lock_type != MAIL_LOCK_UNLOCK) {
+ if (!mbox_lock(index, lock_type))
+ return FALSE;
+ } else {
+ if (!mbox_unlock(index))
+ return FALSE;
+ }
+
+ return TRUE;
}
- Previous message: [dovecot-cvs] dovecot/src/lib-index mail-index-open.c,1.12,1.13 mail-index-update-cache.c,1.9,1.10 mail-index.c,1.66,1.67 mail-index.h,1.48,1.49 mail-tree.c,1.8,1.9
- Next message: [dovecot-cvs] dovecot/src/lib-storage mail-storage.h,1.17,1.18
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list