]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Removed mailbox.backend_readonly. Backends set it internally lazily...
authorTimo Sirainen <tss@iki.fi>
Mon, 6 Dec 2010 01:47:50 +0000 (01:47 +0000)
committerTimo Sirainen <tss@iki.fi>
Mon, 6 Dec 2010 01:47:50 +0000 (01:47 +0000)
12 files changed:
src/lib-storage/index/index-storage.c
src/lib-storage/index/maildir/maildir-storage.c
src/lib-storage/index/maildir/maildir-storage.h
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
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.c

index 9353901c3e8f4c3c831d263510b0ddf09a6d3139..3f907bda1a900a770a1078b40a0e2d2577f47455 100644 (file)
@@ -476,16 +476,7 @@ int index_storage_mailbox_rename(struct mailbox *src, struct mailbox *dest,
 
 bool index_storage_is_readonly(struct mailbox *box)
 {
-       if ((box->flags & MAILBOX_FLAG_READONLY) != 0)
-               return TRUE;
-
-       if (box->backend_readonly) {
-               /* return read-only only if there are no private flags
-                  (that are stored in index files) */
-               if (mailbox_get_private_flags_mask(box) == 0)
-                       return TRUE;
-       }
-       return FALSE;
+       return (box->flags & MAILBOX_FLAG_READONLY) != 0;
 }
 
 bool index_storage_allow_new_keywords(struct mailbox *box)
index de4e00bf45333e252fb0d8e10e3aabbff0231344..68d45806dbcf186166b799f071d2f5424e61fea5 100644 (file)
@@ -292,7 +292,6 @@ maildir_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
 static int maildir_mailbox_open_existing(struct mailbox *box)
 {
        struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
-       const char *box_path = mailbox_get_path(box);
 
        mbox->uidlist = maildir_uidlist_init(mbox);
        mbox->keywords = maildir_keywords_init(mbox);
@@ -305,9 +304,6 @@ static int maildir_mailbox_open_existing(struct mailbox *box)
                                                 mbox);
        }
 
-       if (access(t_strconcat(box_path, "/cur", NULL), W_OK) < 0 &&
-           errno == EACCES)
-               mbox->box.backend_readonly = TRUE;
        if (index_storage_mailbox_open(box, FALSE) < 0)
                return -1;
 
@@ -317,6 +313,22 @@ static int maildir_mailbox_open_existing(struct mailbox *box)
        return 0;
 }
 
+static bool maildir_storage_is_readonly(struct mailbox *box)
+{
+       struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
+
+       if (index_storage_is_readonly(box))
+               return TRUE;
+
+       if (maildir_is_backend_readonly(mbox)) {
+               /* return read-only only if there are no private flags
+                  (that are stored in index files) */
+               if (mailbox_get_private_flags_mask(box) == 0)
+                       return TRUE;
+       }
+       return FALSE;
+}
+
 static int maildir_mailbox_open(struct mailbox *box)
 {
        const char *box_path = mailbox_get_path(box);
@@ -589,6 +601,19 @@ static enum mail_flags maildir_get_private_flags_mask(struct mailbox *box)
        return mbox->_private_flags_mask;
 }
 
+bool maildir_is_backend_readonly(struct maildir_mailbox *mbox)
+{
+       if (!mbox->backend_readonly_set) {
+               const char *box_path = mailbox_get_path(&mbox->box);
+
+               mbox->backend_readonly_set = TRUE;
+               if (access(t_strconcat(box_path, "/cur", NULL), W_OK) < 0 &&
+                   errno == EACCES)
+                       mbox->backend_readonly = TRUE;
+       }
+       return mbox->backend_readonly;
+}
+
 struct mail_storage maildir_storage = {
        .name = MAILDIR_STORAGE_NAME,
        .class_flags = 0,
@@ -608,7 +633,7 @@ struct mail_storage maildir_storage = {
 
 struct mailbox maildir_mailbox = {
        .v = {
-               index_storage_is_readonly,
+               maildir_storage_is_readonly,
                index_storage_allow_new_keywords,
                index_storage_mailbox_enable,
                maildir_mailbox_open,
index b0b2fb63275b55afdde436d700b9942cff6b30e6..dd50e22d4dd0b64c483fdfed2a879b59ff1b84a8 100644 (file)
@@ -91,6 +91,8 @@ struct maildir_mailbox {
        unsigned int synced:1;
        unsigned int syncing_commit:1;
        unsigned int private_flags_mask_set:1;
+       unsigned int backend_readonly:1;
+       unsigned int backend_readonly_set:1;
 };
 
 extern struct mail_vfuncs maildir_mail_vfuncs;
@@ -115,6 +117,7 @@ int maildir_file_do(struct maildir_mailbox *mbox, uint32_t uid,
 bool maildir_set_deleted(struct mailbox *box);
 uint32_t maildir_get_uidvalidity_next(struct mailbox_list *list);
 int maildir_lose_unexpected_dir(struct mail_storage *storage, const char *path);
+bool maildir_is_backend_readonly(struct maildir_mailbox *mbox);
 
 struct mail_save_context *
 maildir_save_alloc(struct mailbox_transaction_context *_t);
index 9d0b8eff945750b66f4d24c2563fbb025169c9e8..debc47d0b04b72376fa5f09921fbcee48fb0885c 100644 (file)
@@ -244,7 +244,7 @@ int maildir_sync_index_begin(struct maildir_mailbox *mbox,
                maildir_keywords_sync_init(mbox->keywords, _box->index);
        ctx->sync_changes =
                index_sync_changes_init(ctx->sync_ctx, ctx->view, ctx->trans,
-                                       mbox->box.backend_readonly);
+                                       maildir_is_backend_readonly(mbox));
        ctx->start_time = time(NULL);
 
        *ctx_r = ctx;
index 1798fffcc35aabd8b697979de0d2fe5cb2f4354f..3d23a48d7f0cdac19e4ec8c60dd5c816bb8a0313 100644 (file)
@@ -21,14 +21,14 @@ int mbox_file_open(struct mbox_mailbox *mbox)
 
        if (mbox->mbox_file_stream != NULL) {
                /* read-only mbox stream */
-               i_assert(mbox->box.backend_readonly);
+               i_assert(mbox_is_backend_readonly(mbox));
                return 0;
        }
 
        fd = open(mailbox_get_path(&mbox->box),
-                 mbox->box.backend_readonly ? O_RDONLY : O_RDWR);
-       if (fd == -1 && errno == EACCES && !mbox->box.backend_readonly) {
-                mbox->box.backend_readonly = TRUE;
+                 mbox_is_backend_readonly(mbox) ? O_RDONLY : O_RDWR);
+       if (fd == -1 && errno == EACCES && !mbox->backend_readonly) {
+               mbox->backend_readonly = TRUE;
                fd = open(mailbox_get_path(&mbox->box), O_RDONLY);
        }
 
@@ -68,7 +68,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->box.backend_readonly);
+               i_assert(mbox->mbox_fd == -1 && mbox_is_backend_readonly(mbox));
        } else {
                if (mbox->mbox_fd == -1) {
                        if (mbox_file_open(mbox) < 0)
@@ -104,7 +104,7 @@ static void mbox_file_fix_atime(struct mbox_mailbox *mbox)
 
        if (ibox->recent_flags_count > 0 &&
            (mbox->box.flags & MAILBOX_FLAG_KEEP_RECENT) != 0 &&
-           mbox->mbox_fd != -1 && !mbox->box.backend_readonly) {
+           mbox->mbox_fd != -1 && !mbox_is_backend_readonly(mbox)) {
                /* 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 */
@@ -133,7 +133,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->box.backend_readonly);
+                       i_assert(mbox_is_backend_readonly(mbox));
                        i_stream_seek(mbox->mbox_file_stream, 0);
                } else {
                        i_stream_destroy(&mbox->mbox_file_stream);
index 13c2bd9e8bf2c22bd5123d3830d560e567699a99..0cb4a52ad4a7e6291516050c58338dfd06fd137d 100644 (file)
@@ -708,7 +708,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->box.backend_readonly);
+               i_assert(mbox_is_backend_readonly(mbox));
                mbox->mbox_lock_type = lock_type;
                return 1;
        }
index 2d7c76695925cd1ad0c4f91fa64ab846a31a562b..cd7e1ddb361ae2691cc7945d73f851805034d1f3 100644 (file)
@@ -261,7 +261,7 @@ mbox_save_init_file(struct mbox_save_context *ctx,
        bool empty = FALSE;
        int ret;
 
-       if (ctx->mbox->box.backend_readonly) {
+       if (mbox_is_backend_readonly(ctx->mbox)) {
                mail_storage_set_error(storage, MAIL_ERROR_PERM,
                                       "Read-only mbox");
                return -1;
index 1ea3c843107036af41193116c2b1ad4cc87f930f..003b59d71abe3adac1bcd141e016ea06eae47fa2 100644 (file)
@@ -402,13 +402,6 @@ static int mbox_mailbox_open_existing(struct mbox_mailbox *mbox)
        const char *rootdir, *box_path = mailbox_get_path(box);
        bool move_to_memory;
 
-       if (access(box_path, R_OK|W_OK) < 0) {
-               if (errno != EACCES) {
-                       mbox_set_syscall_error(mbox, "access()");
-                       return -1;
-               }
-               mbox->box.backend_readonly = TRUE;
-       }
        move_to_memory = want_memory_indexes(mbox->storage, box_path);
 
        if (box->inbox_any || strcmp(box->name, "INBOX") == 0) {
@@ -432,6 +425,22 @@ static int mbox_mailbox_open_existing(struct mbox_mailbox *mbox)
        return mbox_mailbox_open_finish(mbox, move_to_memory);
 }
 
+static bool mbox_storage_is_readonly(struct mailbox *box)
+{
+       struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
+
+       if (index_storage_is_readonly(box))
+               return TRUE;
+
+       if (mbox_is_backend_readonly(mbox)) {
+               /* return read-only only if there are no private flags
+                  (that are stored in index files) */
+               if (mailbox_get_private_flags_mask(box) == 0)
+                       return TRUE;
+       }
+       return FALSE;
+}
+
 static int mbox_mailbox_open(struct mailbox *box)
 {
        struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
@@ -441,7 +450,8 @@ static int mbox_mailbox_open(struct mailbox *box)
        if (box->input != NULL) {
                i_stream_ref(box->input);
                mbox->mbox_file_stream = box->input;
-               mbox->box.backend_readonly = TRUE;
+               mbox->backend_readonly = TRUE;
+               mbox->backend_readonly_set = TRUE;
                mbox->no_mbox_file = TRUE;
                return mbox_mailbox_open_finish(mbox, FALSE);
        }
@@ -561,7 +571,7 @@ static void mbox_mailbox_close(struct mailbox *box)
        if (box->view != NULL) {
                hdr = mail_index_get_header(box->view);
                if ((hdr->flags & MAIL_INDEX_HDR_FLAG_HAVE_DIRTY) != 0 &&
-                   !mbox->box.backend_readonly) {
+                   !mbox_is_backend_readonly(mbox)) {
                        /* we've done changes to mbox which haven't been
                           written yet. do it now. */
                        sync_flags |= MBOX_SYNC_REWRITE;
@@ -696,6 +706,17 @@ mbox_transaction_rollback(struct mailbox_transaction_context *t)
        mbox_transaction_unlock(box, lock_id);
 }
 
+bool mbox_is_backend_readonly(struct mbox_mailbox *mbox)
+{
+       if (!mbox->backend_readonly_set) {
+               mbox->backend_readonly_set = TRUE;
+               if (access(mailbox_get_path(&mbox->box), R_OK|W_OK) < 0 &&
+                   errno == EACCES)
+                       mbox->backend_readonly = TRUE;
+       }
+       return mbox->backend_readonly;
+}
+
 struct mail_storage mbox_storage = {
        .name = MBOX_STORAGE_NAME,
        .class_flags = MAIL_STORAGE_CLASS_FLAG_MAILBOX_IS_FILE |
@@ -716,7 +737,7 @@ struct mail_storage mbox_storage = {
 
 struct mailbox mbox_mailbox = {
        .v = {
-               index_storage_is_readonly,
+               mbox_storage_is_readonly,
                index_storage_allow_new_keywords,
                index_storage_mailbox_enable,
                mbox_mailbox_open,
index 93aa371f47290adf7dc8e9682ea94d324a559ec3..d770b6eb0f6edc4a29c43a48a400899502aba019 100644 (file)
@@ -57,6 +57,8 @@ struct mbox_mailbox {
        unsigned int mbox_used_privileges:1;
        unsigned int mbox_privileged_locking:1;
        unsigned int syncing:1;
+       unsigned int backend_readonly:1;
+       unsigned int backend_readonly_set:1;
 };
 
 struct mbox_transaction_context {
@@ -87,4 +89,6 @@ void mbox_transaction_save_commit_post(struct mail_save_context *ctx,
                                       struct mail_index_transaction_commit_result *result);
 void mbox_transaction_save_rollback(struct mail_save_context *ctx);
 
+bool mbox_is_backend_readonly(struct mbox_mailbox *mbox);
+
 #endif
index 24775f5172b8487526a6588610cf16451f84ea83..fc53776afa6684eda343f88dc89528fe8a8cc116 100644 (file)
@@ -1733,7 +1733,7 @@ static int mbox_sync_int(struct mbox_mailbox *mbox, enum mbox_sync_flags flags,
        int ret, changed;
        bool delay_writes, readonly;
 
-       readonly = mbox->box.backend_readonly ||
+       readonly = mbox_is_backend_readonly(mbox) ||
                (flags & MBOX_SYNC_READONLY) != 0;
        delay_writes = readonly ||
                ((flags & MBOX_SYNC_REWRITE) == 0 &&
@@ -1791,7 +1791,8 @@ again:
                        /* try as read-only */
                        if (mbox_lock(mbox, F_RDLCK, lock_id) <= 0)
                                return -1;
-                       mbox->box.backend_readonly = readonly = TRUE;
+                       mbox->backend_readonly = readonly = TRUE;
+                       mbox->backend_readonly_set = TRUE;
                        delay_writes = TRUE;
                }
        }
index 60b3b2a2ea37ee15fbff1dabdbcabff133bdeea9..5098ce37d8cc11d6c12228a57b878ef812f96ebf 100644 (file)
@@ -280,8 +280,6 @@ struct mailbox {
        unsigned int opened:1;
        /* Mailbox was deleted while we had it open. */
        unsigned int mailbox_deleted:1;
-       /* we've discovered there aren't enough permissions to modify mailbox */
-       unsigned int backend_readonly:1;
        /* Mailbox is being deleted */
        unsigned int deleting:1;
        /* Mailbox was already marked as deleted within this allocation. */
index 51ec53f0046e779ca7dfcd275a28dd9ef676048b..598f6eeb09ad74f75a7dd803eeeda000175be4de 100644 (file)
@@ -652,7 +652,6 @@ void mailbox_close(struct mailbox *box)
 
        box->opened = FALSE;
        box->mailbox_deleted = FALSE;
-       box->backend_readonly = FALSE;
        array_clear(&box->search_results);
 }