]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lock the mbox before reading it.
authorTimo Sirainen <tss@iki.fi>
Tue, 15 Jun 2004 01:15:44 +0000 (04:15 +0300)
committerTimo Sirainen <tss@iki.fi>
Tue, 15 Jun 2004 01:15:44 +0000 (04:15 +0300)
--HG--
branch : HEAD

src/lib-storage/index/mbox/mbox-lock.c
src/lib-storage/index/mbox/mbox-mail.c
src/lib-storage/index/mbox/mbox-storage.c
src/lib-storage/index/mbox/mbox-sync-private.h
src/lib-storage/index/mbox/mbox-sync.c
src/lib-storage/index/mbox/mbox-transaction.c

index 45e2df1c2fa6f32e6a49e80ad8dc6eaf0423439a..5c99827ea43c78326d777e650d03baed4787216d 100644 (file)
@@ -409,6 +409,7 @@ static int mbox_unlock_files(struct index_mailbox *ibox)
 
 int mbox_unlock(struct index_mailbox *ibox, unsigned int lock_id)
 {
+       i_assert(ibox->mbox_locks > 0);
        i_assert(ibox->mbox_lock_id == lock_id);
 
        if (--ibox->mbox_locks > 0)
index 2eb85f8acd6fd568867f2cde7f2a7b643b045c60..84de015e12358e2441d0469ecb8700e3243ce54b 100644 (file)
@@ -5,6 +5,7 @@
 #include "index-mail.h"
 #include "mbox-storage.h"
 #include "mbox-file.h"
+#include "mbox-sync-private.h"
 #include "istream-raw-mbox.h"
 
 #include <fcntl.h>
@@ -16,17 +17,23 @@ static int mbox_mail_seek(struct index_mail *mail)
        struct index_mailbox *ibox = mail->ibox;
        const void *data;
 
+       if (ibox->mbox_lock_type == F_UNLCK) {
+               if (mbox_sync(ibox, FALSE, TRUE) < 0)
+                       return -1;
+
+               i_assert(ibox->mbox_lock_type != F_UNLCK);
+                mail->ibox->mbox_mail_lock_id = ibox->mbox_lock_id;
+       }
+
+       if (mbox_file_open_stream(ibox) < 0)
+               return -1;
+
        if (mail_index_lookup_extra(ibox->view, mail->mail.seq,
                                    ibox->mbox_extra_idx, &data) < 0) {
                mail_storage_set_index_error(ibox);
                return -1;
        }
 
-       // FIXME: lock the file. sync if needed.
-
-       if (mbox_file_open_stream(ibox) < 0)
-               return -1;
-
        istream_raw_mbox_seek(ibox->mbox_stream, *((const uint64_t *)data));
        return 0;
 }
index ea96b814de77b9c5768440f89d978e4d46b37b4e..21a11de2e633191c8c60aca8493e3db4d6ca6fc9 100644 (file)
@@ -390,6 +390,14 @@ static uint32_t mbox_get_recent_count(struct index_mailbox *ibox)
        return 0; // FIXME
 }
 
+static void mbox_mail_deinit(struct index_mail *mail)
+{
+       if (mail->ibox->mbox_mail_lock_id != 0) {
+               (void)mbox_unlock(mail->ibox, mail->ibox->mbox_mail_lock_id);
+                mail->ibox->mbox_mail_lock_id = 0;
+       }
+}
+
 static struct mailbox *
 mbox_open(struct index_storage *storage, const char *name,
          enum mailbox_open_flags flags)
@@ -427,6 +435,7 @@ mbox_open(struct index_storage *storage, const char *name,
        ibox->mbox_extra_idx = mbox_extra_idx;
 
        ibox->get_recent_count = mbox_get_recent_count;
+       ibox->mail_deinit = mbox_mail_deinit;
        ibox->mail_interface = &mbox_mail;
 
        return &ibox->box;
index 540e524a6c02a4f7067cc6c77dea867740e7ddfb..08b8083e2de5b8b17e1f9d2ca2996c75bb7611fc 100644 (file)
@@ -83,7 +83,7 @@ struct mbox_sync_context {
        off_t expunged_space, space_diff;
 };
 
-int mbox_sync(struct index_mailbox *ibox, int last_commit);
+int mbox_sync(struct index_mailbox *ibox, int last_commit, int lock);
 void mbox_sync_parse_next_mail(struct istream *input,
                               struct mbox_sync_mail_context *ctx,
                               int rewriting);
index 51b1381c18307fcd3ee03992bc7fc3406e925c83..9d2bf6900fc91000d6a5c2124b5688464f5e5344 100644 (file)
@@ -864,12 +864,7 @@ static int mbox_sync_do(struct mbox_sync_context *sync_ctx)
        struct mbox_sync_mail_context mail_ctx;
        struct stat st;
        uint32_t min_msg_count;
-       int ret, lock_type;
-
-       lock_type = mail_index_sync_have_more(sync_ctx->index_sync_ctx) ?
-               F_WRLCK : F_RDLCK;
-       if (mbox_sync_lock(sync_ctx, lock_type) < 0)
-               return -1;
+       int ret;
 
        if (fstat(sync_ctx->fd, &st) < 0) {
                mbox_set_syscall_error(sync_ctx->ibox, "stat()");
@@ -949,17 +944,26 @@ static int mbox_sync_has_changed(struct index_mailbox *ibox)
                (uint64_t)st.st_size != hdr->sync_size;
 }
 
-int mbox_sync(struct index_mailbox *ibox, int last_commit)
+int mbox_sync(struct index_mailbox *ibox, int last_commit, int lock)
 {
        struct mail_index_sync_ctx *index_sync_ctx;
        struct mail_index_view *sync_view;
        struct mbox_sync_context sync_ctx;
        uint32_t seq;
        uoff_t offset;
-       int ret;
+       unsigned int lock_id = 0;
+       int ret, lock_type;
 
-       if ((ret = mbox_sync_has_changed(ibox)) < 0)
+       if (lock) {
+               if (mbox_lock(ibox, F_RDLCK, &lock_id) <= 0)
+                       return -1;
+       }
+
+       if ((ret = mbox_sync_has_changed(ibox)) < 0) {
+               if (lock)
+                       (void)mbox_unlock(ibox, lock_id);
                return -1;
+       }
        if (ret == 0 && !last_commit)
                return 0;
 
@@ -994,6 +998,15 @@ int mbox_sync(struct index_mailbox *ibox, int last_commit)
        ret = mail_index_get_header(sync_view, &sync_ctx.hdr);
        i_assert(ret == 0);
 
+       lock_type = mail_index_sync_have_more(index_sync_ctx) ?
+               F_WRLCK : F_RDLCK;
+       if (lock_type == F_WRLCK && lock) {
+               (void)mbox_unlock(ibox, lock_id);
+               lock_id = 0;
+       }
+       if (mbox_sync_lock(&sync_ctx, lock_type) < 0)
+               return -1;
+
        if (mbox_sync_do(&sync_ctx) < 0)
                ret = -1;
 
@@ -1009,7 +1022,7 @@ int mbox_sync(struct index_mailbox *ibox, int last_commit)
        if (mail_index_sync_end(index_sync_ctx) < 0)
                ret = -1;
 
-       if (sync_ctx.lock_id != 0) {
+       if (sync_ctx.lock_id != 0 && (ret < 0 || !lock)) {
                /* FIXME: drop to read locking and keep it MBOX_SYNC_SECS+1
                   to make sure we notice changes made by others */
                if (mbox_unlock(ibox, sync_ctx.lock_id) < 0)
@@ -1031,7 +1044,7 @@ int mbox_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags)
            ibox->sync_last_check + MAILBOX_FULL_SYNC_INTERVAL <= ioloop_time) {
                ibox->sync_last_check = ioloop_time;
 
-               if (mbox_sync(ibox, FALSE) < 0)
+               if (mbox_sync(ibox, FALSE, FALSE) < 0)
                        return -1;
        }
 
index d6ffebb959603eed07407f60cfedae910bf4e531..9fdb2a0bca030bc89eb6d52514af0360c473f577 100644 (file)
@@ -37,7 +37,7 @@ int mbox_transaction_commit(struct mailbox_transaction_context *_t)
        }
 
        if (ret == 0) {
-               if (mbox_sync(ibox, TRUE) < 0)
+               if (mbox_sync(ibox, TRUE, FALSE) < 0)
                        ret = -1;
        }