[dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-copy.c,
1.31, 1.32 maildir-save.c, 1.37, 1.38 maildir-storage.c, 1.82,
1.83 maildir-storage.h, 1.26, 1.27 maildir-transaction.c, 1.2, 1.3
cras at dovecot.org
cras at dovecot.org
Sun Aug 22 12:17:11 EEST 2004
- Previous message: [dovecot-cvs] dovecot/src/lib-storage Makefile.am, 1.10,
1.11 mail-copy.c, NONE, 1.1 mail-copy.h, NONE, 1.1 mail-save.c,
1.12, NONE mail-save.h, 1.3, NONE mail-storage-private.h, 1.7,
1.8 mail-storage.c, 1.28, 1.29 mail-storage.h, 1.76,
1.77 proxy-mailbox.c, 1.9, 1.10
- Next message: [dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-save.c, 1.57,
1.58 mbox-storage.c, 1.90, 1.91 mbox-storage.h, 1.27,
1.28 mbox-transaction.c, 1.4, 1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/dovecot/src/lib-storage/index/maildir
In directory talvi:/tmp/cvs-serv2400/lib-storage/index/maildir
Modified Files:
maildir-copy.c maildir-save.c maildir-storage.c
maildir-storage.h maildir-transaction.c
Log Message:
Changed mail saving API to be nonblocking.
Index: maildir-copy.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/maildir/maildir-copy.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- maildir-copy.c 20 Jun 2004 03:25:33 -0000 1.31
+++ maildir-copy.c 22 Aug 2004 09:17:08 -0000 1.32
@@ -3,7 +3,7 @@
#include "lib.h"
#include "ioloop.h"
#include "maildir-storage.h"
-#include "mail-save.h"
+#include "mail-copy.h"
#include <stdlib.h>
#include <unistd.h>
@@ -100,13 +100,13 @@
return ctx;
}
-int maildir_copy_commit(struct maildir_copy_context *ctx)
+int maildir_transaction_copy_commit(struct maildir_copy_context *ctx)
{
pool_unref(ctx->pool);
return 0;
}
-void maildir_copy_rollback(struct maildir_copy_context *ctx)
+void maildir_transaction_copy_rollback(struct maildir_copy_context *ctx)
{
struct rollback *rb;
Index: maildir-save.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/maildir/maildir-save.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- maildir-save.c 15 Aug 2004 03:40:32 -0000 1.37
+++ maildir-save.c 22 Aug 2004 09:17:08 -0000 1.38
@@ -6,7 +6,6 @@
#include "str.h"
#include "maildir-storage.h"
#include "maildir-uidlist.h"
-#include "mail-save.h"
#include <stdio.h>
#include <stdlib.h>
@@ -21,6 +20,7 @@
};
struct maildir_save_context {
+ struct mail_save_context ctx;
pool_t pool;
struct index_mailbox *ibox;
@@ -29,49 +29,16 @@
const char *tmpdir, *newdir, *curdir;
struct maildir_filename *files;
-};
-static const char *
-maildir_read_into_tmp(struct index_mailbox *ibox, const char *dir,
- struct istream *input)
-{
- const char *path, *fname;
+ struct istream *input;
struct ostream *output;
- int fd, crlf;
-
- fd = maildir_create_tmp(ibox, dir, ibox->mail_create_mode, &path);
- if (fd == -1)
- return NULL;
-
- fname = strrchr(path, '/');
- i_assert(fname != NULL);
- fname++;
-
- output = o_stream_create_file(fd, pool_datastack_create(), 0, FALSE);
-
- crlf = getenv("MAIL_SAVE_CRLF") != NULL;
- if (mail_storage_save(ibox->box.storage, path, input, output,
- crlf, crlf, NULL, NULL) < 0)
- fname = NULL;
-
- o_stream_unref(output);
- /* FIXME: when saving multiple messages, we could get better
- performance if we left the fd open and fsync()ed it later */
- if (fsync(fd) < 0) {
- mail_storage_set_critical(ibox->box.storage,
- "fsync() failed for %s: %m", path);
- fname = NULL;
- }
- if (close(fd) < 0) {
- mail_storage_set_critical(ibox->box.storage,
- "close() failed for %s: %m", path);
- fname = NULL;
- }
+ int fd;
+ time_t received_date;
+ uint32_t seq;
- if (fname == NULL)
- (void)unlink(path);
- return fname;
-}
+ unsigned int save_crlf:1;
+ unsigned int failed:1;
+};
static int maildir_file_move(struct maildir_save_context *ctx,
const char *basename, const char *dest)
@@ -112,7 +79,7 @@
}
static struct maildir_save_context *
-mailbox_save_init(struct maildir_transaction_context *t)
+maildir_transaction_save_init(struct maildir_transaction_context *t)
{
struct index_mailbox *ibox = t->ictx.ibox;
struct maildir_save_context *ctx;
@@ -120,6 +87,7 @@
pool = pool_alloconly_create("maildir_save_context", 4096);
ctx = p_new(pool, struct maildir_save_context, 1);
+ ctx->ctx.box = &ibox->box;
ctx->pool = pool;
ctx->ibox = ibox;
ctx->trans = t->ictx.trans;
@@ -129,30 +97,50 @@
ctx->tmpdir = p_strconcat(pool, ibox->path, "/tmp", NULL);
ctx->newdir = p_strconcat(pool, ibox->path, "/new", NULL);
ctx->curdir = p_strconcat(pool, ibox->path, "/cur", NULL);
+
+ ctx->save_crlf = getenv("MAIL_SAVE_CRLF") != NULL;
return ctx;
}
-int maildir_save(struct mailbox_transaction_context *_t,
- const struct mail_full_flags *flags,
- time_t received_date, int timezone_offset __attr_unused__,
- const char *from_envelope __attr_unused__,
- struct istream *data, struct mail **mail_r)
+struct mail_save_context *
+maildir_save_init(struct mailbox_transaction_context *_t,
+ const struct mail_full_flags *flags,
+ time_t received_date, int timezone_offset __attr_unused__,
+ const char *from_envelope __attr_unused__,
+ struct istream *input, int want_mail __attr_unused__)
{
struct maildir_transaction_context *t =
(struct maildir_transaction_context *)_t;
struct maildir_save_context *ctx;
struct index_mailbox *ibox = t->ictx.ibox;
struct maildir_filename *mf;
- struct utimbuf buf;
- const char *fname, *dest_fname, *tmp_path;
+ const char *fname, *dest_fname, *path;
enum mail_flags mail_flags;
keywords_mask_t keywords;
- uint32_t seq;
+
+ t_push();
if (t->save_ctx == NULL)
- t->save_ctx = mailbox_save_init(t);
+ t->save_ctx = maildir_transaction_save_init(t);
ctx = t->save_ctx;
+ /* create a new file in tmp/ directory */
+ ctx->fd = maildir_create_tmp(ibox, ctx->tmpdir, ibox->mail_create_mode,
+ &path);
+ if (ctx->fd == -1) {
+ ctx->failed = TRUE;
+ t_pop();
+ return &ctx->ctx;
+ }
+
+ fname = strrchr(path, '/');
+ i_assert(fname != NULL);
+ fname++;
+
+ ctx->received_date = received_date;
+ ctx->input = input;
+ ctx->output = o_stream_create_file(ctx->fd, system_pool, 0, FALSE);
+
mail_flags = (flags->flags & ~MAIL_RECENT) |
(ibox->keep_recent ? MAIL_RECENT : 0);
/*FIXME:if (!index_mailbox_fix_keywords(ibox, &mail_flags,
@@ -160,29 +148,6 @@
flags->keywords_count))
return FALSE;*/
- t_push();
-
- /* create the file into tmp/ directory */
- fname = maildir_read_into_tmp(ibox, ctx->tmpdir, data);
- if (fname == NULL) {
- t_pop();
- return -1;
- }
-
- tmp_path = t_strconcat(ctx->tmpdir, "/", fname, NULL);
-
- if (received_date != (time_t)-1) {
- /* set the received_date by modifying mtime */
- buf.actime = ioloop_time;
- buf.modtime = received_date;
- if (utime(tmp_path, &buf) < 0) {
- mail_storage_set_critical(ibox->box.storage,
- "utime(%s) failed: %m", tmp_path);
- t_pop();
- return -1;
- }
- }
-
/* now, we want to be able to rollback the whole append session,
so we'll just store the name of this temp file and move it later
into new/ or cur/. if dest_fname is NULL, it's moved to new/,
@@ -200,20 +165,113 @@
memset(keywords, 0, INDEX_KEYWORDS_BYTE_COUNT);
// FIXME: set keywords
- mail_index_append(t->ictx.trans, 0, &seq);
- mail_index_update_flags(t->ictx.trans, seq, MODIFY_REPLACE,
+ mail_index_append(t->ictx.trans, 0, &ctx->seq);
+ mail_index_update_flags(t->ictx.trans, ctx->seq, MODIFY_REPLACE,
mail_flags, keywords);
t_pop();
+ ctx->failed = FALSE;
+ return &ctx->ctx;
+}
+
+int maildir_save_continue(struct mail_save_context *_ctx)
+{
+ struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
+
+ if (ctx->failed)
+ return -1;
+
+ if (o_stream_send_istream(ctx->output, ctx->input) < 0) {
+ ctx->failed = TRUE;
+ return -1;
+ }
+ return 0;
+}
+
+int maildir_save_finish(struct mail_save_context *_ctx, struct mail **mail_r)
+{
+ struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
+ struct utimbuf buf;
+ const char *path;
+
+ if (ctx->failed && ctx->fd == -1) {
+ /* tmp file creation failed */
+ return -1;
+ }
+
+ t_push();
+ path = t_strconcat(ctx->tmpdir, "/", ctx->files->basename, NULL);
+
+ if (ctx->received_date != (time_t)-1) {
+ /* set the received_date by modifying mtime */
+ buf.actime = ioloop_time;
+ buf.modtime = ctx->received_date;
+
+ if (utime(path, &buf) < 0) {
+ ctx->failed = TRUE;
+ mail_storage_set_critical(ctx->ibox->box.storage,
+ "utime(%s) failed: %m", path);
+ }
+ }
+
+ o_stream_unref(ctx->output);
+ ctx->output = NULL;
+
+ /* FIXME: when saving multiple messages, we could get better
+ performance if we left the fd open and fsync()ed it later */
+ if (fsync(ctx->fd) < 0) {
+ mail_storage_set_critical(ctx->ibox->box.storage,
+ "fsync(%s) failed: %m", path);
+ ctx->failed = TRUE;
+ }
+ if (close(ctx->fd) < 0) {
+ mail_storage_set_critical(ctx->ibox->box.storage,
+ "close(%s) failed: %m", path);
+ ctx->failed = TRUE;
+ }
+ ctx->fd = -1;
+
+ if (ctx->failed) {
+ /* delete the tmp file */
+ if (unlink(path) < 0 && errno != ENOENT) {
+ mail_storage_set_critical(ctx->ibox->box.storage,
+ "unlink(%s) failed: %m", path);
+ }
+
+ errno = ctx->output->stream_errno;
+ if (ENOSPACE(errno)) {
+ mail_storage_set_error(ctx->ibox->box.storage,
+ "Not enough disk space");
+ } else if (errno != 0) {
+ mail_storage_set_critical(ctx->ibox->box.storage,
+ "write(%s) failed: %m", ctx->ibox->path);
+ }
+
+ ctx->files = ctx->files->next;
+ t_pop();
+ return -1;
+ }
+
if (mail_r != NULL) {
- if (index_mail_next(&ctx->mail, seq) < 0)
+ i_assert(ctx->seq != 0);
+
+ if (index_mail_next(&ctx->mail, ctx->seq) < 0)
return -1;
*mail_r = &ctx->mail.mail;
}
+ t_pop();
return 0;
}
+void maildir_save_cancel(struct mail_save_context *_ctx)
+{
+ struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
+
+ ctx->failed = TRUE;
+ (void)maildir_save_finish(_ctx, NULL);
+}
+
static void maildir_save_commit_abort(struct maildir_save_context *ctx,
struct maildir_filename *pos)
{
@@ -235,10 +293,10 @@
ctx->files = pos;
t_pop();
- maildir_save_rollback(ctx);
+ maildir_transaction_save_rollback(ctx);
}
-int maildir_save_commit(struct maildir_save_context *ctx)
+int maildir_transaction_save_commit(struct maildir_save_context *ctx)
{
struct maildir_uidlist_sync_ctx *sync_ctx;
struct maildir_filename *mf;
@@ -247,6 +305,8 @@
const char *fname;
int ret = 0;
+ i_assert(ctx->output == NULL);
+
ret = maildir_uidlist_lock(ctx->ibox->uidlist);
if (ret <= 0) {
/* error or timeout - our transaction is broken */
@@ -284,11 +344,13 @@
return ret;
}
-void maildir_save_rollback(struct maildir_save_context *ctx)
+void maildir_transaction_save_rollback(struct maildir_save_context *ctx)
{
struct maildir_filename *mf;
string_t *str;
+ i_assert(ctx->output == NULL);
+
t_push();
str = t_str_new(1024);
Index: maildir-storage.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/maildir/maildir-storage.c,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -d -r1.82 -r1.83
--- maildir-storage.c 22 Jul 2004 21:20:01 -0000 1.82
+++ maildir-storage.c 22 Aug 2004 09:17:08 -0000 1.83
@@ -805,7 +805,10 @@
index_storage_search_init,
index_storage_search_deinit,
index_storage_search_next,
- maildir_save,
+ maildir_save_init,
+ maildir_save_continue,
+ maildir_save_finish,
+ maildir_save_cancel,
maildir_copy,
index_storage_is_inconsistent
};
Index: maildir-storage.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/maildir/maildir-storage.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- maildir-storage.h 22 Jul 2004 21:20:01 -0000 1.26
+++ maildir-storage.h 22 Aug 2004 09:17:08 -0000 1.27
@@ -48,18 +48,23 @@
int maildir_transaction_commit(struct mailbox_transaction_context *t);
void maildir_transaction_rollback(struct mailbox_transaction_context *t);
-int maildir_save(struct mailbox_transaction_context *t,
- const struct mail_full_flags *flags,
- time_t received_date, int timezone_offset,
- const char *from_envelope, struct istream *data,
- struct mail **mail_r);
-int maildir_save_commit(struct maildir_save_context *ctx);
-void maildir_save_rollback(struct maildir_save_context *ctx);
+struct mail_save_context *
+maildir_save_init(struct mailbox_transaction_context *_t,
+ const struct mail_full_flags *flags,
+ time_t received_date, int timezone_offset,
+ const char *from_envelope, struct istream *input,
+ int want_mail);
+int maildir_save_continue(struct mail_save_context *ctx);
+int maildir_save_finish(struct mail_save_context *ctx, struct mail **mail_r);
+void maildir_save_cancel(struct mail_save_context *ctx);
+
+int maildir_transaction_save_commit(struct maildir_save_context *ctx);
+void maildir_transaction_save_rollback(struct maildir_save_context *ctx);
int maildir_copy(struct mailbox_transaction_context *t, struct mail *mail,
struct mail **dest_mail_r);
-int maildir_copy_commit(struct maildir_copy_context *ctx);
-void maildir_copy_rollback(struct maildir_copy_context *ctx);
+int maildir_transaction_copy_commit(struct maildir_copy_context *ctx);
+void maildir_transaction_copy_rollback(struct maildir_copy_context *ctx);
const char *maildir_get_path(struct index_storage *storage, const char *name);
Index: maildir-transaction.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/maildir/maildir-transaction.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- maildir-transaction.c 22 Jun 2004 07:36:33 -0000 1.2
+++ maildir-transaction.c 22 Aug 2004 09:17:08 -0000 1.3
@@ -22,11 +22,11 @@
int ret = 0;
if (t->save_ctx != NULL) {
- if (maildir_save_commit(t->save_ctx) < 0)
+ if (maildir_transaction_save_commit(t->save_ctx) < 0)
ret = -1;
}
if (t->copy_ctx != NULL) {
- if (maildir_copy_commit(t->copy_ctx) < 0)
+ if (maildir_transaction_copy_commit(t->copy_ctx) < 0)
ret = -1;
}
@@ -42,8 +42,8 @@
(struct maildir_transaction_context *)_t;
if (t->save_ctx != NULL)
- maildir_save_rollback(t->save_ctx);
+ maildir_transaction_save_rollback(t->save_ctx);
if (t->copy_ctx != NULL)
- maildir_copy_rollback(t->copy_ctx);
+ maildir_transaction_copy_rollback(t->copy_ctx);
index_transaction_rollback(_t);
}
- Previous message: [dovecot-cvs] dovecot/src/lib-storage Makefile.am, 1.10,
1.11 mail-copy.c, NONE, 1.1 mail-copy.h, NONE, 1.1 mail-save.c,
1.12, NONE mail-save.h, 1.3, NONE mail-storage-private.h, 1.7,
1.8 mail-storage.c, 1.28, 1.29 mail-storage.h, 1.76,
1.77 proxy-mailbox.c, 1.9, 1.10
- Next message: [dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-save.c, 1.57,
1.58 mbox-storage.c, 1.90, 1.91 mbox-storage.h, 1.27,
1.28 mbox-transaction.c, 1.4, 1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list