int index_transaction_commit(struct mailbox_transaction_context *t, struct mail_transaction_commit_changes *changes_r) { struct mailbox *box = t->box; struct mail_index_transaction *itrans = t->itrans; struct mail_index_transaction_commit_result result; int ret = 0; memset(changes_r, 0, sizeof(*changes_r)); changes_r->pool = pool_alloconly_create(MEMPOOL_GROWING "transaction changes", 512); p_array_init(&changes_r->saved_uids, changes_r->pool, 32); t->changes = changes_r; if (t->itrans_pvt != NULL) ret = mail_index_transaction_commit(&t->itrans_pvt); if (mail_index_transaction_commit_full(&itrans, &result) < 0) ret = -1; t = NULL; if (ret < 0 && mail_index_is_deleted(box->index)) mailbox_set_deleted(box); changes_r->ignored_modseq_changes = result.ignored_modseq_changes; return ret; }
static int mbox_file_open_latest(struct mbox_lock_context *ctx, int lock_type) { struct mbox_mailbox *mbox = ctx->mbox; struct stat st; if (ctx->checked_file || lock_type == F_UNLCK) return 0; if (mbox->mbox_fd != -1) { /* we could flush NFS file handle cache here if we wanted to be sure that the file is latest, but mbox files get rarely deleted and the flushing might cause errors (e.g. EBUSY for trying to flush a /var/mail mountpoint) */ if (nfs_safe_stat(mailbox_get_path(&mbox->box), &st) < 0) { if (errno == ENOENT) mailbox_set_deleted(&mbox->box); else mbox_set_syscall_error(mbox, "stat()"); return -1; } if (st.st_ino != mbox->mbox_ino || !CMP_DEV_T(st.st_dev, mbox->mbox_dev)) mbox_file_close(mbox); } if (mbox->mbox_fd == -1) { if (mbox_file_open(mbox) < 0) return -1; } ctx->checked_file = TRUE; return 0; }
int index_storage_mailbox_open(struct mailbox *box, bool move_to_memory) { struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box); enum mail_index_open_flags index_flags; int ret; i_assert(!box->opened); index_flags = ibox->index_flags; if (move_to_memory) ibox->index_flags &= ~MAIL_INDEX_OPEN_FLAG_CREATE; if (index_storage_mailbox_alloc_index(box) < 0) return -1; /* make sure mail_index_set_permissions() has been called */ (void)mailbox_get_permissions(box); ret = mail_index_open(box->index, index_flags); if (ret <= 0 || move_to_memory) { if ((index_flags & MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY) != 0) { i_assert(ret <= 0); mailbox_set_index_error(box); return -1; } if (mail_index_move_to_memory(box->index) < 0) { /* try opening once more. it should be created directly into memory now. */ if (mail_index_open_or_create(box->index, index_flags) < 0) i_panic("in-memory index creation failed"); } } if ((index_flags & MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY) != 0) { if (mail_index_is_in_memory(box->index)) { mail_storage_set_critical(box->storage, "Couldn't create index file"); mail_index_close(box->index); return -1; } } if ((box->flags & MAILBOX_FLAG_OPEN_DELETED) == 0) { if (mail_index_is_deleted(box->index)) { mailbox_set_deleted(box); mail_index_close(box->index); return -1; } } box->cache = mail_index_get_cache(box->index); index_cache_register_defaults(box); box->view = mail_index_view_open(box->index); ibox->keyword_names = mail_index_get_keywords(box->index); ibox->vsize_hdr_ext_id = mail_index_ext_register(box->index, "hdr-vsize", sizeof(struct index_vsize_header), 0, sizeof(uint64_t)); box->opened = TRUE; if ((box->enabled_features & MAILBOX_FEATURE_CONDSTORE) != 0) mail_index_modseq_enable(box->index); index_thread_mailbox_opened(box); hook_mailbox_opened(box); return 0; }