]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Cleaned up read-only mailbox handling. Fixes a bug with Maildir syncing.
authorTimo Sirainen <tss@iki.fi>
Wed, 14 Jan 2009 18:56:01 +0000 (13:56 -0500)
committerTimo Sirainen <tss@iki.fi>
Wed, 14 Jan 2009 18:56:01 +0000 (13:56 -0500)
If Maildir was opened read-only (STATUS, EXAMINE) then all flag changes were
saved to index as dirty.

--HG--
branch : HEAD

src/lib-storage/index/index-storage.c
src/lib-storage/index/index-storage.h
src/lib-storage/index/maildir/maildir-storage.c
src/lib-storage/index/maildir/maildir-sync-index.c
src/lib-storage/index/mbox/mbox-file.c
src/lib-storage/index/mbox/mbox-lock.c
src/lib-storage/index/mbox/mbox-save.c
src/lib-storage/index/mbox/mbox-storage.c
src/lib-storage/index/mbox/mbox-storage.h
src/lib-storage/index/mbox/mbox-sync.c

index cabca38be5c2baf58f276bd39c4c6e1092b7410f..5dc73984b1637f3558c6c24ce4cd19076e0d87ff 100644 (file)
@@ -463,7 +463,6 @@ void index_storage_mailbox_init(struct index_mailbox *ibox, const char *name,
        array_create(&ibox->box.module_contexts,
                     ibox->box.pool, sizeof(void *), 5);
 
-       ibox->readonly = (flags & MAILBOX_OPEN_READONLY) != 0;
        ibox->keep_recent = (flags & MAILBOX_OPEN_KEEP_RECENT) != 0;
        ibox->keep_locked = (flags & MAILBOX_OPEN_KEEP_LOCKED) != 0;
        ibox->move_to_memory = move_to_memory;
@@ -514,15 +513,14 @@ bool index_storage_is_readonly(struct mailbox *box)
 {
        struct index_mailbox *ibox = (struct index_mailbox *) box;
 
-       return ibox->readonly;
+       return (ibox->box.open_flags & MAILBOX_OPEN_READONLY) != 0 ||
+               ibox->backend_readonly;
 }
 
 bool index_storage_allow_new_keywords(struct mailbox *box)
 {
-       struct index_mailbox *ibox = (struct index_mailbox *) box;
-
        /* FIXME: return FALSE if we're full */
-       return !ibox->readonly;
+       return index_storage_is_readonly(box);
 }
 
 bool index_storage_is_inconsistent(struct mailbox *box)
index b0c7e8df204da1b380ca7cbc5d806f8cabb962a8..bde4f9fee190ec19dbf1c131872857ce2e24adb0 100644 (file)
@@ -55,7 +55,8 @@ struct index_mailbox {
 
        time_t sync_last_check;
 
-       unsigned int readonly:1;
+       /* we've discovered there aren't enough permissions to modify mailbox */
+       unsigned int backend_readonly:1;
        unsigned int keep_recent:1;
        unsigned int keep_locked:1;
        unsigned int sent_diskspace_warning:1;
index 6bfdb818f406b38acd3e041c9145aea4d2534f44..5068bf2089bf20032b7e5400f921bf6bb524d264 100644 (file)
@@ -468,7 +468,7 @@ maildir_open(struct maildir_storage *storage, const char *name,
 
        if (access(t_strconcat(path, "/cur", NULL), W_OK) < 0 &&
            errno == EACCES)
-               mbox->ibox.readonly = TRUE;
+               mbox->ibox.backend_readonly = TRUE;
 
        mbox->keywords = maildir_keywords_init(mbox);
        return &mbox->ibox.box;
index 1bf57f10c344605b0af654b64e84d5a119bfe6f1..3c03b8c48596f27fbf47077a27570c8421e6ef1e 100644 (file)
@@ -193,10 +193,10 @@ int maildir_sync_index_begin(struct maildir_mailbox *mbox,
        ctx->trans = trans;
        ctx->keywords_sync_ctx =
                maildir_keywords_sync_init(mbox->keywords, mbox->ibox.index);
-
-       ctx->sync_changes = index_sync_changes_init(&mbox->ibox, ctx->sync_ctx,
-                                                   ctx->view, ctx->trans,
-                                                   mbox->ibox.readonly);
+       ctx->sync_changes =
+               index_sync_changes_init(&mbox->ibox, ctx->sync_ctx,
+                                       ctx->view, ctx->trans,
+                                       mbox->ibox.backend_readonly);
 
        *ctx_r = ctx;
        return 0;
index 0c7d02b3dc8e8f04013530d814a99b64f3647733..ff4361df290f9ff9ab45c0752f5988d58e695ffb 100644 (file)
@@ -19,13 +19,13 @@ int mbox_file_open(struct mbox_mailbox *mbox)
 
        if (mbox->mbox_file_stream != NULL) {
                /* read-only mbox stream */
-               i_assert(mbox->mbox_readonly);
+               i_assert(mbox->ibox.backend_readonly);
                return 0;
        }
 
-       fd = open(mbox->path, mbox->mbox_readonly ? O_RDONLY : O_RDWR);
-       if (fd == -1 && errno == EACCES && !mbox->mbox_readonly) {
-                mbox->mbox_readonly = TRUE;
+       fd = open(mbox->path, mbox->ibox.backend_readonly ? O_RDONLY : O_RDWR);
+       if (fd == -1 && errno == EACCES && !mbox->ibox.backend_readonly) {
+                mbox->ibox.backend_readonly = TRUE;
                fd = open(mbox->path, O_RDONLY);
        }
 
@@ -65,7 +65,7 @@ int mbox_file_open_stream(struct mbox_mailbox *mbox)
 
        if (mbox->mbox_file_stream != NULL) {
                /* read-only mbox stream */
-               i_assert(mbox->mbox_fd == -1 && mbox->mbox_readonly);
+               i_assert(mbox->mbox_fd == -1 && mbox->ibox.backend_readonly);
        } else {
                if (mbox->mbox_fd == -1) {
                        if (mbox_file_open(mbox) < 0)
@@ -95,7 +95,7 @@ static void mbox_file_fix_atime(struct mbox_mailbox *mbox)
        struct stat st;
 
        if (mbox->ibox.recent_flags_count > 0 && mbox->ibox.keep_recent &&
-           mbox->mbox_fd != -1 && !mbox->mbox_readonly) {
+           mbox->mbox_fd != -1 && !mbox->ibox.backend_readonly) {
                /* we've seen recent messages which we want to keep recent.
                   keep file's atime lower than mtime so \Marked status
                   gets shown while listing */
@@ -124,7 +124,7 @@ void mbox_file_close_stream(struct mbox_mailbox *mbox)
        if (mbox->mbox_file_stream != NULL) {
                if (mbox->mbox_fd == -1) {
                        /* read-only mbox stream */
-                       i_assert(mbox->mbox_readonly);
+                       i_assert(mbox->ibox.backend_readonly);
                        i_stream_seek(mbox->mbox_file_stream, 0);
                } else {
                        i_stream_destroy(&mbox->mbox_file_stream);
index 030144f35b98c965c990bf7817e79fefb667c280..50a3eab4109ec88d695124cce7d7e1d937b4a0b2 100644 (file)
@@ -621,7 +621,7 @@ static int mbox_update_locking(struct mbox_mailbox *mbox, int lock_type,
 
        if (mbox->mbox_fd == -1 && mbox->mbox_file_stream != NULL) {
                /* read-only mbox stream. no need to lock. */
-               i_assert(mbox->mbox_readonly);
+               i_assert(mbox->ibox.backend_readonly);
                mbox->mbox_lock_type = lock_type;
                return 1;
        }
index 226d66f83e436dd3377742a0850654ef39f8e986..82a3b69ef0b7875741bebc0b972354b1a5b06480 100644 (file)
@@ -254,7 +254,7 @@ mbox_save_init_file(struct mbox_save_context *ctx,
        bool empty = FALSE;
        int ret;
 
-       if (ctx->mbox->mbox_readonly) {
+       if (ctx->mbox->ibox.backend_readonly) {
                mail_storage_set_error(storage, MAIL_ERROR_PERM,
                                       "Read-only mbox");
                return -1;
index f87119f8f8d1b283ada66b6cae628a87eb9c28a1..3324061a7eff00d171c0e29c7171c1061da92939 100644 (file)
@@ -615,10 +615,8 @@ mbox_open(struct mbox_storage *storage, const char *name,
        if (access(path, R_OK|W_OK) < 0) {
                if (errno < EACCES)
                        mbox_set_syscall_error(mbox, "access()");
-               else {
-                       mbox->ibox.readonly = TRUE;
-                       mbox->mbox_readonly = TRUE;
-               }
+               else
+                       mbox->ibox.backend_readonly = TRUE;
        }
 
        if (strcmp(name, "INBOX") == 0) {
@@ -652,7 +650,7 @@ mbox_mailbox_open_stream(struct mbox_storage *storage, const char *name,
 
        i_stream_ref(input);
        mbox->mbox_file_stream = input;
-       mbox->mbox_readonly = TRUE;
+       mbox->ibox.backend_readonly = TRUE;
        mbox->no_mbox_file = TRUE;
 
        mbox->path = "(read-only mbox stream)";
@@ -785,7 +783,7 @@ static int mbox_storage_mailbox_close(struct mailbox *box)
        if (mbox->ibox.view != NULL) {
                hdr = mail_index_get_header(mbox->ibox.view);
                if ((hdr->flags & MAIL_INDEX_HDR_FLAG_HAVE_DIRTY) != 0 &&
-                   !mbox->mbox_readonly) {
+                   !mbox->ibox.backend_readonly) {
                        /* we've done changes to mbox which haven't been
                           written yet. do it now. */
                        sync_flags |= MBOX_SYNC_REWRITE;
index c0cc58979f3658bd8b6cff45fc18d32c9afb5431..e61b95ee1c2877bfdbb85c942ce9256bf718cdb1 100644 (file)
@@ -41,7 +41,7 @@ struct mbox_mailbox {
        struct dotlock *mbox_dotlock;
        unsigned int mbox_lock_id, mbox_global_lock_id;
        struct timeout *keep_lock_to;
-       bool mbox_readonly, mbox_writeonly;
+       bool mbox_writeonly;
 
        uint32_t mbox_ext_idx;
        struct mbox_index_header mbox_hdr;
index e2901045f13c248bcfec607102f4d4a68526fadf..4ae5c99657cecbab932a915c18bf505725dfc4b2 100644 (file)
@@ -173,7 +173,7 @@ static void mbox_sync_read_index_syncs(struct mbox_sync_context *sync_ctx,
        }
 
        index_sync_changes_read(sync_ctx->sync_changes, uid, sync_expunge_r);
-       if (sync_ctx->mbox->mbox_readonly) {
+       if (sync_ctx->mbox->ibox.backend_readonly) {
                /* we can't expunge anything from read-only mboxes */
                *sync_expunge_r = FALSE;
        }
@@ -1535,7 +1535,8 @@ static int mbox_sync_do(struct mbox_sync_context *sync_ctx,
                /* a) partial sync didn't work
                   b) we ran out of UIDs
                   c) syncing had errors */
-               if (sync_ctx->delay_writes && !sync_ctx->mbox->mbox_readonly &&
+               if (sync_ctx->delay_writes &&
+                   !sync_ctx->mbox->ibox.backend_readonly &&
                    (sync_ctx->errors || sync_ctx->renumber_uids)) {
                        /* fixing a broken mbox state, be sure to write
                           the changes. */
@@ -1672,7 +1673,7 @@ static int mbox_sync_int(struct mbox_mailbox *mbox, enum mbox_sync_flags flags,
        int ret, changed;
        bool delay_writes;
 
-       delay_writes = mbox->mbox_readonly ||
+       delay_writes = mbox->ibox.backend_readonly ||
                ((flags & MBOX_SYNC_REWRITE) == 0 &&
                 getenv("MBOX_LAZY_WRITES") != NULL);
 
@@ -1715,7 +1716,7 @@ again:
                   lock it for writing immediately. the mbox must be locked
                   before index syncing is started to avoid deadlocks, so we
                   don't have much choice either (well, easy ones anyway). */
-               int lock_type = mbox->mbox_readonly ? F_RDLCK : F_WRLCK;
+               int lock_type = mbox->ibox.backend_readonly ? F_RDLCK : F_WRLCK;
 
                if ((ret = mbox_lock(mbox, lock_type, lock_id)) <= 0) {
                        if (ret == 0 || lock_type == F_RDLCK)
@@ -1724,7 +1725,7 @@ again:
                        /* try as read-only */
                        if (mbox_lock(mbox, F_RDLCK, lock_id) <= 0)
                                return -1;
-                       mbox->mbox_readonly = TRUE;
+                       mbox->ibox.backend_readonly = TRUE;
                }
        }
 
@@ -1790,7 +1791,8 @@ again:
        i_array_init(&sync_ctx.mails, 64);
 
        sync_ctx.flags = flags;
-       sync_ctx.delay_writes = delay_writes || sync_ctx.mbox->mbox_readonly;
+       sync_ctx.delay_writes = delay_writes ||
+               sync_ctx.mbox->ibox.backend_readonly;
 
        sync_ctx.sync_changes =
                index_sync_changes_init(&mbox->ibox, index_sync_ctx,
@@ -1846,7 +1848,7 @@ again:
        sync_ctx.index_sync_ctx = NULL;
 
        if (ret == 0 && mbox->mbox_fd != -1 && mbox->ibox.keep_recent &&
-           !sync_ctx.mbox->mbox_readonly) {
+           !sync_ctx.mbox->ibox.backend_readonly) {
                /* try to set atime back to its original value */
                struct utimbuf buf;
                struct stat st;