void index_transaction_init(struct mailbox_transaction_context *t,
			    struct mailbox *box,
			    enum mailbox_transaction_flags flags)
{
	enum mail_index_transaction_flags itrans_flags;

	i_assert(box->opened);

	itrans_flags = index_transaction_flags_get(flags);
	if ((flags & MAILBOX_TRANSACTION_FLAG_REFRESH) != 0)
		mail_index_refresh(box->index);

	t->box = box;
	t->itrans = mail_index_transaction_begin(box->view, itrans_flags);
	t->view = mail_index_transaction_open_updated_view(t->itrans);

	array_create(&t->module_contexts, default_pool,
		     sizeof(void *), 5);

	t->cache_view = mail_cache_view_open(box->cache, t->view);
	t->cache_trans = mail_cache_get_transaction(t->cache_view, t->itrans);

	if ((flags & MAILBOX_TRANSACTION_FLAG_NO_CACHE_DEC) != 0)
		mail_cache_view_update_cache_decisions(t->cache_view, FALSE);

	/* set up after mail_cache_get_transaction(), so that we'll still
	   have the cache_trans available in _index_commit() */
	t->super = t->itrans->v;
	t->itrans->v.commit = index_transaction_index_commit;
	t->itrans->v.rollback = index_transaction_index_rollback;
	MODULE_CONTEXT_SET(t->itrans, mail_storage_mail_index_module, t);
}
Exemplo n.º 2
0
mdbox_write_index_header(struct mailbox *box,
                         const struct mailbox_update *update,
                         struct mail_index_transaction *trans)
{
    struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box;
    struct mail_index_transaction *new_trans = NULL;
    struct mail_index_view *view;
    const struct mail_index_header *hdr;
    uint32_t uid_validity, uid_next;

    if (mdbox_map_open_or_create(mbox->storage->map) < 0)
        return -1;

    if (trans == NULL) {
        new_trans = mail_index_transaction_begin(box->view, 0);
        trans = new_trans;
    }

    view = mail_index_view_open(box->index);
    hdr = mail_index_get_header(view);
    uid_validity = hdr->uid_validity;
    if (update != NULL && update->uid_validity != 0)
        uid_validity = update->uid_validity;
    else if (uid_validity == 0) {
        /* set uidvalidity */
        uid_validity = dbox_get_uidvalidity_next(box->list);
    }

    if (hdr->uid_validity != uid_validity) {
        mail_index_update_header(trans,
                                 offsetof(struct mail_index_header, uid_validity),
                                 &uid_validity, sizeof(uid_validity), TRUE);
    }
void mailbox_list_index_refresh_later(struct mailbox_list *list)
{
	struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list);
	struct mailbox_list_index_header new_hdr;
	struct mail_index_view *view;
	struct mail_index_transaction *trans;

	if (!ilist->has_backing_store)
		return;

	(void)mailbox_list_index_index_open(list);

	view = mail_index_view_open(ilist->index);
	if (!mailbox_list_index_need_refresh(ilist, view)) {
		new_hdr.refresh_flag = 1;

		trans = mail_index_transaction_begin(view,
					MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
		mail_index_update_header_ext(trans, ilist->ext_id,
			offsetof(struct mailbox_list_index_header, refresh_flag),
			&new_hdr.refresh_flag, sizeof(new_hdr.refresh_flag));
		if (mail_index_transaction_commit(&trans) < 0)
			mail_index_mark_corrupted(ilist->index);

	}
Exemplo n.º 4
0
int sdbox_mailbox_create_indexes(struct mailbox *box,
				 const struct mailbox_update *update,
				 struct mail_index_transaction *trans)
{
	struct sdbox_mailbox *mbox = SDBOX_MAILBOX(box);
	struct mail_index_transaction *new_trans = NULL;
	const struct mail_index_header *hdr;
	uint32_t uid_validity, uid_next;

	if (trans == NULL) {
		new_trans = mail_index_transaction_begin(box->view, 0);
		trans = new_trans;
	}

	hdr = mail_index_get_header(box->view);
	if (update != NULL && update->uid_validity != 0)
		uid_validity = update->uid_validity;
	else if (hdr->uid_validity != 0)
		uid_validity = hdr->uid_validity;
	else {
		/* set uidvalidity */
		uid_validity = dbox_get_uidvalidity_next(box->list);
	}

	if (hdr->uid_validity != uid_validity) {
		mail_index_update_header(trans,
			offsetof(struct mail_index_header, uid_validity),
			&uid_validity, sizeof(uid_validity), TRUE);
	}
Exemplo n.º 5
0
static int
index_storage_mailbox_update_pvt(struct mailbox *box,
				 const struct mailbox_update *update)
{
	struct mail_index_transaction *trans;
	struct mail_index_view *view;
	int ret;

	if ((ret = mailbox_open_index_pvt(box)) <= 0)
		return ret;

	mail_index_refresh(box->index_pvt);
	view = mail_index_view_open(box->index_pvt);
	trans = mail_index_transaction_begin(view,
					MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
	if (update->min_highest_modseq != 0 &&
	    mail_index_modseq_get_highest(view) < update->min_highest_pvt_modseq) {
		mail_index_modseq_enable(box->index_pvt);
		mail_index_update_highest_modseq(trans,
						 update->min_highest_pvt_modseq);
	}

	if ((ret = mail_index_transaction_commit(&trans)) < 0)
		mailbox_set_index_error(box);
	mail_index_view_close(&view);
	return ret;
}
Exemplo n.º 6
0
int index_storage_mailbox_update(struct mailbox *box,
				 const struct mailbox_update *update)
{
	const struct mail_index_header *hdr;
	struct mail_index_view *view;
	struct mail_index_transaction *trans;
	int ret;

	if (mailbox_open(box) < 0)
		return -1;

	/* make sure we get the latest index info */
	mail_index_refresh(box->index);
	view = mail_index_view_open(box->index);
	hdr = mail_index_get_header(view);

	trans = mail_index_transaction_begin(view,
					MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
	if (update->uid_validity != 0 &&
	    hdr->uid_validity != update->uid_validity) {
		uint32_t uid_validity = update->uid_validity;

		if (hdr->uid_validity != 0) {
			/* UIDVALIDITY change requires index to be reset */
			mail_index_reset(trans);
		}
		mail_index_update_header(trans,
			offsetof(struct mail_index_header, uid_validity),
			&uid_validity, sizeof(uid_validity), TRUE);
	}
Exemplo n.º 7
0
void index_transaction_init(struct index_transaction_context *it,
			    struct mailbox *box,
			    enum mailbox_transaction_flags flags)
{
	struct mailbox_transaction_context *t = &it->mailbox_ctx;
	enum mail_index_transaction_flags trans_flags;

	i_assert(box->opened);

	trans_flags = MAIL_INDEX_TRANSACTION_FLAG_AVOID_FLAG_UPDATES;
	if ((flags & MAILBOX_TRANSACTION_FLAG_HIDE) != 0)
		trans_flags |= MAIL_INDEX_TRANSACTION_FLAG_HIDE;
	if ((flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0)
		trans_flags |= MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL;
	if ((flags & MAILBOX_TRANSACTION_FLAG_REFRESH) != 0)
		(void)mail_index_refresh(box->index);

	t->box = box;
	t->itrans = mail_index_transaction_begin(box->view, trans_flags);
	t->view = mail_index_transaction_open_updated_view(t->itrans);

	array_create(&t->module_contexts, default_pool,
		     sizeof(void *), 5);

	it->cache_view = mail_cache_view_open(box->cache, t->view);
	it->cache_trans = mail_cache_get_transaction(it->cache_view, t->itrans);

	/* set up after mail_cache_get_transaction(), so that we'll still
	   have the cache_trans available in _index_commit() */
	it->super = t->itrans->v;
	t->itrans->v.commit = index_transaction_index_commit;
	t->itrans->v.rollback = index_transaction_index_rollback;
	MODULE_CONTEXT_SET(t->itrans, mail_storage_mail_index_module, it);
}
void index_transaction_init_pvt(struct mailbox_transaction_context *t)
{
	enum mail_index_transaction_flags itrans_flags;

	if (t->box->view_pvt == NULL || t->itrans_pvt != NULL)
		return;

	itrans_flags = index_transaction_flags_get(t->flags);
	t->itrans_pvt = mail_index_transaction_begin(t->box->view_pvt,
						     itrans_flags);
	t->view_pvt = mail_index_transaction_open_updated_view(t->itrans_pvt);
}
Exemplo n.º 9
0
static int
index_list_update(struct index_mailbox_list *ilist, struct mailbox *box,
		  struct mail_index_view *view, uint32_t seq,
		  const struct mailbox_status *status)
{
	struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
	struct mail_index_transaction *trans;
	struct mail_index_transaction_commit_result result;
	const void *data;
	const uint32_t *counter_p;
	uint32_t *ext_id_p;
	unsigned int i;
	bool expunged;
	int ret = 0;

	trans = mail_index_transaction_begin(view,
					MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);

	/* update counters */
	for (i = 0; index_list_map[i].name != NULL; i++) {
		ext_id_p = PTR_OFFSET(ilist, index_list_map[i].eid_offset);
		mail_index_lookup_ext(view, seq, *ext_id_p, &data, &expunged);
		if (expunged) {
			ret = -1;
			break;
		}

		counter_p = CONST_PTR_OFFSET(status,
					     index_list_map[i].status_offset);
		if (data == NULL ||
		    *(const uint32_t *)data != *counter_p) {
			mail_index_update_ext(trans, seq, *ext_id_p,
					      counter_p, NULL);
		}
	}

	if (box->v.list_index_update_sync(box, trans, seq) < 0)
		ret = -1;
	if (ret < 0) {
		mail_index_transaction_rollback(&trans);
		return -1;
	}

	if (mail_index_transaction_commit_full(&trans, &result) < 0)
		return -1;

	ibox->log_seq = result.log_file_seq;
	ibox->log_offset = result.log_file_offset;
	return 0;
}
Exemplo n.º 10
0
static void imapc_mailbox_init_delayed_trans(struct imapc_mailbox *mbox)
{
	if (mbox->delayed_sync_trans != NULL)
		return;

	i_assert(mbox->delayed_sync_cache_view == NULL);
	i_assert(mbox->delayed_sync_cache_trans == NULL);

	mbox->delayed_sync_trans =
		mail_index_transaction_begin(imapc_mailbox_get_sync_view(mbox),
					MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
	mbox->delayed_sync_view =
		mail_index_transaction_open_updated_view(mbox->delayed_sync_trans);

	mbox->delayed_sync_cache_view =
		mail_cache_view_open(mbox->box.cache, mbox->delayed_sync_view);
	mbox->delayed_sync_cache_trans =
		mail_cache_get_transaction(mbox->delayed_sync_cache_view,
					   mbox->delayed_sync_trans);
}
Exemplo n.º 11
0
static int imapc_mailbox_commit_delayed_expunges(struct imapc_mailbox *mbox)
{
	struct mail_index_view *view = imapc_mailbox_get_sync_view(mbox);
	struct mail_index_transaction *trans;
	struct seq_range_iter iter;
	unsigned int n;
	uint32_t lseq, uid;
	int ret;

	trans = mail_index_transaction_begin(view,
			MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);

	seq_range_array_iter_init(&iter, &mbox->delayed_expunged_uids); n = 0;
	while (seq_range_array_iter_nth(&iter, n++, &uid)) {
		if (mail_index_lookup_seq(view, uid, &lseq))
			mail_index_expunge(trans, lseq);
	}
	array_clear(&mbox->delayed_expunged_uids);
	ret = mail_index_transaction_commit(&trans);
	if (ret < 0)
		mailbox_set_index_error(&mbox->box);
	return ret;
}
Exemplo n.º 12
0
static int dbox_sync_mark_expunges(struct mdbox_sync_context *ctx)
{
	enum mail_index_transaction_flags flags =
		MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL;
	struct mailbox *box = &ctx->mbox->box;
	struct mail_index_transaction *trans;
	struct seq_range_iter iter;
	unsigned int n;
	const void *data;
	uint32_t seq, uid;

	/* use a separate transaction here so that we can commit the changes
	   during map transaction */
	trans = mail_index_transaction_begin(ctx->sync_view, flags);
	seq_range_array_iter_init(&iter, &ctx->expunged_seqs); n = 0;
	while (seq_range_array_iter_nth(&iter, n++, &seq)) {
		mail_index_lookup_uid(ctx->sync_view, seq, &uid);
		mail_index_lookup_ext(ctx->sync_view, seq,
				      ctx->mbox->guid_ext_id, &data, NULL);
		mail_index_expunge_guid(trans, seq, data);
	}
	if (mail_index_transaction_commit(&trans) < 0)
		return -1;

	if (box->v.sync_notify != NULL) {
		/* do notifications after commit finished successfully */
		box->tmp_sync_view = ctx->sync_view;
		seq_range_array_iter_init(&iter, &ctx->expunged_seqs); n = 0;
		while (seq_range_array_iter_nth(&iter, n++, &seq)) {
			mail_index_lookup_uid(ctx->sync_view, seq, &uid);
			box->v.sync_notify(box, uid, MAILBOX_SYNC_TYPE_EXPUNGE);
		}
		box->tmp_sync_view = NULL;
	}
	return 0;
}
Exemplo n.º 13
0
static int
mdbox_deleted_mailbox_create_indexes(struct mailbox *box,
				     const struct mailbox_update *update,
				     struct mail_index_transaction *trans)
{
	struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box;
	struct mail_index_transaction *new_trans = NULL;
	uint32_t uid_validity = ioloop_time;
	uint32_t uid_next = 1;

	if (update != NULL && update->uid_validity != 0)
		uid_validity = update->uid_validity;

	if (trans == NULL) {
		new_trans = mail_index_transaction_begin(box->view, 0);
		trans = new_trans;
	}

	mail_index_update_header(trans,
		offsetof(struct mail_index_header, uid_validity),
		&uid_validity, sizeof(uid_validity), TRUE);
	mail_index_update_header(trans,
		offsetof(struct mail_index_header, next_uid),
		&uid_next, sizeof(uid_next), TRUE);
	mbox->creating = TRUE;
	mdbox_update_header(mbox, trans, update);
	mbox->creating = FALSE;

	if (new_trans != NULL) {
		if (mail_index_transaction_commit(&new_trans) < 0) {
			mailbox_set_index_error(box);
			return -1;
		}
	}
	return 0;
}