From: Timo Sirainen Date: Mon, 6 Dec 2010 01:47:50 +0000 (+0000) Subject: lib-storage: Removed mailbox.backend_readonly. Backends set it internally lazily... X-Git-Tag: 2.1.alpha1~446 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c000c8eca8f24b2a0c76393ec4bbf76a505a4983;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Removed mailbox.backend_readonly. Backends set it internally lazily now. --- diff --git a/src/lib-storage/index/index-storage.c b/src/lib-storage/index/index-storage.c index 9353901c3e..3f907bda1a 100644 --- a/src/lib-storage/index/index-storage.c +++ b/src/lib-storage/index/index-storage.c @@ -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) diff --git a/src/lib-storage/index/maildir/maildir-storage.c b/src/lib-storage/index/maildir/maildir-storage.c index de4e00bf45..68d45806db 100644 --- a/src/lib-storage/index/maildir/maildir-storage.c +++ b/src/lib-storage/index/maildir/maildir-storage.c @@ -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, diff --git a/src/lib-storage/index/maildir/maildir-storage.h b/src/lib-storage/index/maildir/maildir-storage.h index b0b2fb6327..dd50e22d4d 100644 --- a/src/lib-storage/index/maildir/maildir-storage.h +++ b/src/lib-storage/index/maildir/maildir-storage.h @@ -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); diff --git a/src/lib-storage/index/maildir/maildir-sync-index.c b/src/lib-storage/index/maildir/maildir-sync-index.c index 9d0b8eff94..debc47d0b0 100644 --- a/src/lib-storage/index/maildir/maildir-sync-index.c +++ b/src/lib-storage/index/maildir/maildir-sync-index.c @@ -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; diff --git a/src/lib-storage/index/mbox/mbox-file.c b/src/lib-storage/index/mbox/mbox-file.c index 1798fffcc3..3d23a48d7f 100644 --- a/src/lib-storage/index/mbox/mbox-file.c +++ b/src/lib-storage/index/mbox/mbox-file.c @@ -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); diff --git a/src/lib-storage/index/mbox/mbox-lock.c b/src/lib-storage/index/mbox/mbox-lock.c index 13c2bd9e8b..0cb4a52ad4 100644 --- a/src/lib-storage/index/mbox/mbox-lock.c +++ b/src/lib-storage/index/mbox/mbox-lock.c @@ -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; } diff --git a/src/lib-storage/index/mbox/mbox-save.c b/src/lib-storage/index/mbox/mbox-save.c index 2d7c766959..cd7e1ddb36 100644 --- a/src/lib-storage/index/mbox/mbox-save.c +++ b/src/lib-storage/index/mbox/mbox-save.c @@ -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; diff --git a/src/lib-storage/index/mbox/mbox-storage.c b/src/lib-storage/index/mbox/mbox-storage.c index 1ea3c84310..003b59d71a 100644 --- a/src/lib-storage/index/mbox/mbox-storage.c +++ b/src/lib-storage/index/mbox/mbox-storage.c @@ -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, diff --git a/src/lib-storage/index/mbox/mbox-storage.h b/src/lib-storage/index/mbox/mbox-storage.h index 93aa371f47..d770b6eb0f 100644 --- a/src/lib-storage/index/mbox/mbox-storage.h +++ b/src/lib-storage/index/mbox/mbox-storage.h @@ -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 diff --git a/src/lib-storage/index/mbox/mbox-sync.c b/src/lib-storage/index/mbox/mbox-sync.c index 24775f5172..fc53776afa 100644 --- a/src/lib-storage/index/mbox/mbox-sync.c +++ b/src/lib-storage/index/mbox/mbox-sync.c @@ -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; } } diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index 60b3b2a2ea..5098ce37d8 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -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. */ diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index 51ec53f004..598f6eeb09 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -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); }