# HG changeset patch # User Timo Sirainen # Date 1255712565 14400 # Node ID ebb44fb7d9decc520ff8e946aef9683b4d3c41d8 # Parent d55146fea954370ec11fdd75c60c35da4330f1b2 mbox: Make sure failed saves get rolled back with NFS. diff -r d55146fea954 -r ebb44fb7d9de src/lib-storage/index/mbox/mbox-save.c --- a/src/lib-storage/index/mbox/mbox-save.c Thu Oct 15 22:26:03 2009 -0400 +++ b/src/lib-storage/index/mbox/mbox-save.c Fri Oct 16 13:02:45 2009 -0400 @@ -710,6 +710,22 @@ i_free(ctx); } +static void mbox_save_truncate(struct mbox_save_context *ctx) +{ + if (ctx->append_offset == (uoff_t)-1 || ctx->mbox->mbox_fd == -1) + return; + + i_assert(ctx->mbox->mbox_lock_type == F_WRLCK); + + /* failed, truncate file back to original size. output stream needs to + be flushed before truncating so unref() won't write anything. */ + if (ctx->output != NULL) + o_stream_flush(ctx->output); + + if (ftruncate(ctx->mbox->mbox_fd, (off_t)ctx->append_offset) < 0) + mbox_set_syscall_error(ctx->mbox, "ftruncate()"); +} + int mbox_transaction_save_commit(struct mbox_save_context *ctx) { struct mbox_transaction_context *t = @@ -754,10 +770,11 @@ mbox_set_syscall_error(mbox, "utime()"); } - if (!ctx->synced && mbox->mbox_fd != -1 && - !mbox->mbox_writeonly && !mbox->ibox.fsync_disable) { + if (mbox->mbox_fd != -1 && !mbox->mbox_writeonly && + !mbox->ibox.fsync_disable) { if (fdatasync(mbox->mbox_fd) < 0) { mbox_set_syscall_error(mbox, "fdatasync()"); + mbox_save_truncate(ctx); ret = -1; } } @@ -768,23 +785,9 @@ void mbox_transaction_save_rollback(struct mbox_save_context *ctx) { - struct mbox_mailbox *mbox = ctx->mbox; - if (!ctx->finished) mbox_save_cancel(&ctx->ctx); - if (ctx->append_offset != (uoff_t)-1 && mbox->mbox_fd != -1) { - i_assert(mbox->mbox_lock_type == F_WRLCK); - - /* failed, truncate file back to original size. - output stream needs to be flushed before truncating - so unref() won't write anything. */ - if (ctx->output != NULL) - o_stream_flush(ctx->output); - - if (ftruncate(mbox->mbox_fd, (off_t)ctx->append_offset) < 0) - mbox_set_syscall_error(mbox, "ftruncate()"); - } - + mbox_save_truncate(ctx); mbox_transaction_save_deinit(ctx); }