EXPORTED void mailbox_unlock_index(struct mailbox *mailbox, struct statusdata *sdata)
{
    struct statusdata mysdata = STATUSDATA_INIT;
    struct timeval endtime;
    double timediff;
    int r;
    const char *index_fname = mailbox_meta_fname(mailbox, META_INDEX);

    /* this is kinda awful, but too much code expects it to work, and the
     * refcounting isn't good about partial commit/abort and all the
     * unwinding, so here you are.  At least if you mailbox_abort, then
     * it resets the dirty flags, so this becomes a NOOP during close */
    /* naughty - you can't unlock a dirty mailbox! */
    r = mailbox_commit(mailbox);
    if (r) {
        xsyslog(LOG_ERR, "IOERROR: failed to commit mailbox, "
                            "probably need to reconstruct",
                         "mailbox=<%s>",
                         mailbox_name(mailbox));
        abort();
    }

    if (mailbox->has_changed) {
        if (updatenotifier) updatenotifier(mailbox_name(mailbox));
        sync_log_mailbox(mailbox_name(mailbox));

        if (!sdata) {
            status_fill_mailbox(mailbox, &mysdata);
            sdata = &mysdata;
        }

        mailbox->has_changed = 0;
    }

    // we always write if given new statusdata, or if we changed the mailbox
    if (sdata)
        statuscache_invalidate(mailbox_name(mailbox), sdata);

    if (mailbox->index_locktype) {
        if (lock_unlock(mailbox->index_fd, index_fname))
            xsyslog(LOG_ERR, "IOERROR: unlocking index failed",
                             "mailbox=<%s>",
                             mailbox_name(mailbox));
        mailbox->index_locktype = 0;

        gettimeofday(&endtime, 0);
        timediff = timesub(&mailbox->starttime, &endtime);
        if (timediff > 1.0) {
            syslog(LOG_NOTICE, "mailbox: longlock %s for %0.1f seconds",
                mailbox_name(mailbox), timediff);
        }
    }

    if (mailbox->local_cstate) {
        int r = conversations_commit(&mailbox->local_cstate);
        if (r)
            syslog(LOG_ERR, "Error committing to conversations database for mailbox %s: %s",
                   mailbox_name(mailbox), error_message(r));
    }

    // release the namespacelock here
    if (mailbox->local_namespacelock) {
        mboxname_release(&mailbox->local_namespacelock);
    }
}
EXPORTED void mailbox_unlock_index(struct mailbox *mailbox, struct statusdata *sdata)
{
    struct statusdata mysdata = STATUSDATA_INIT;
    struct timeval endtime;
    double timediff;
    int r;
    const char *index_fname = mailbox_meta_fname(mailbox, META_INDEX);

     
     
    r = mailbox_commit(mailbox);
    if (r) {
        xsyslog(LOG_ERR, "IOERROR: failed to commit mailbox, "
                            "probably need to reconstruct",
                         "mailbox=<%s>",
                         mailbox_name(mailbox));
        abort();
    }

    if (mailbox->has_changed) {
        if (updatenotifier) updatenotifier(mailbox_name(mailbox));
        sync_log_mailbox(mailbox_name(mailbox));

        if (!sdata) {
            status_fill_mailbox(mailbox, &mysdata);
            sdata = &mysdata;
        }

        mailbox->has_changed = 0;
    }

     
    if (sdata)
        statuscache_invalidate(mailbox_name(mailbox), sdata);

    if (mailbox->index_locktype) {
        if (lock_unlock(mailbox->index_fd, index_fname))
            xsyslog(LOG_ERR, "IOERROR: unlocking index failed",
                             "mailbox=<%s>",
                             mailbox_name(mailbox));
        mailbox->index_locktype = 0;

        gettimeofday(&endtime, 0);
        timediff = timesub(&mailbox->starttime, &endtime);
        if (timediff > 1.0) {
            syslog(LOG_NOTICE, "mailbox: longlock %s for %0.1f seconds",
                mailbox_name(mailbox), timediff);
        }
    }

    if (mailbox->local_cstate) {
        int r = conversations_commit(&mailbox->local_cstate);
        if (r)
            syslog(LOG_ERR, "Error committing to conversations database for mailbox %s: %s",
                   mailbox_name(mailbox), error_message(r));
    }

     
    if (mailbox->local_namespacelock) {
        mboxname_release(&mailbox->local_namespacelock);
    }
}