Mercurial > dovecot > original-hg > dovecot-1.2
changeset 9569:2129667cb499 HEAD
maildir: Fixed a memory leak when copying with hardlinks.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 14 May 2010 16:29:27 +0200 |
parents | 46d3128626b7 |
children | 5f0e937ae245 |
files | src/lib-storage/index/maildir/maildir-copy.c |
diffstat | 1 files changed, 26 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/maildir/maildir-copy.c Fri May 14 16:18:03 2010 +0200 +++ b/src/lib-storage/index/maildir/maildir-copy.c Fri May 14 16:29:27 2010 +0200 @@ -155,12 +155,11 @@ static int maildir_copy_hardlink(struct maildir_transaction_context *t, struct mail *mail, enum mail_flags flags, struct mail_keywords *keywords, - struct mail *dest_mail) + struct mail *dest_mail, struct hardlink_ctx *do_ctx) { struct maildir_mailbox *dest_mbox = (struct maildir_mailbox *)t->ictx.ibox; struct maildir_mailbox *src_mbox; - struct hardlink_ctx do_ctx; const char *path, *filename = NULL; i_assert((t->ictx.flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0); @@ -183,8 +182,7 @@ if (dest_mbox->ibox.keep_recent) flags |= MAIL_RECENT; - memset(&do_ctx, 0, sizeof(do_ctx)); - do_ctx.dest_path = str_new(default_pool, 512); + do_ctx->dest_path = str_new(default_pool, 512); if (dest_mbox->storage->copy_preserve_filename && src_mbox != NULL) { filename = maildir_copy_get_preserved_fname(src_mbox, dest_mbox, @@ -193,10 +191,10 @@ if (filename == NULL) { /* the generated filename is _always_ unique, so we don't bother trying to check if it already exists */ - do_ctx.dest_fname = maildir_filename_generate(); + do_ctx->dest_fname = maildir_filename_generate(); } else { - do_ctx.dest_fname = filename; - do_ctx.preserve_filename = TRUE; + do_ctx->dest_fname = filename; + do_ctx->preserve_filename = TRUE; } /* FIXME: We could hardlink the files directly to destination, but @@ -207,17 +205,17 @@ if (keywords == NULL || keywords->count == 0) { /* no keywords, hardlink directly to destination */ if (flags == MAIL_RECENT) { - str_printfa(do_ctx.dest_path, "%s/new/%s", - dest_mbox->path, do_ctx.dest_fname); - do_ctx.base_end_pos = str_len(do_ctx.dest_path); + str_printfa(do_ctx->dest_path, "%s/new/%s", + dest_mbox->path, do_ctx->dest_fname); + do_ctx->base_end_pos = str_len(do_ctx->dest_path); } else { - str_printfa(do_ctx.dest_path, "%s/cur/", + str_printfa(do_ctx->dest_path, "%s/cur/", dest_mbox->path); - do_ctx.base_end_pos = str_len(do_ctx.dest_path) + - strlen(do_ctx.dest_fname); - str_append(do_ctx.dest_path, + do_ctx->base_end_pos = str_len(do_ctx->dest_path) + + strlen(do_ctx->dest_fname); + str_append(do_ctx->dest_path, maildir_filename_set_flags(NULL, - do_ctx.dest_fname, + do_ctx->dest_fname, flags, NULL)); } } else @@ -225,25 +223,25 @@ { /* keywords, hardlink to tmp/ with basename and later when we have uidlist locked, move it to new/cur. */ - str_printfa(do_ctx.dest_path, "%s/tmp/%s", - dest_mbox->path, do_ctx.dest_fname); - do_ctx.base_end_pos = str_len(do_ctx.dest_path); + str_printfa(do_ctx->dest_path, "%s/tmp/%s", + dest_mbox->path, do_ctx->dest_fname); + do_ctx->base_end_pos = str_len(do_ctx->dest_path); } if (src_mbox != NULL) { /* maildir */ if (maildir_file_do(src_mbox, mail->uid, - do_hardlink, &do_ctx) < 0) + do_hardlink, do_ctx) < 0) return -1; } else { /* raw / deliver */ if (mail_get_special(mail, MAIL_FETCH_UIDL_FILE_NAME, &path) < 0 || *path == '\0') return 0; - if (do_hardlink(dest_mbox, path, &do_ctx) < 0) + if (do_hardlink(dest_mbox, path, do_ctx) < 0) return -1; } - if (!do_ctx.success) { + if (!do_ctx->success) { /* couldn't copy with hardlinking, fallback to copying */ return 0; } @@ -251,14 +249,14 @@ #if 0 if (keywords == NULL || keywords->count == 0) { /* hardlinked to destination, set hardlinked-flag */ - maildir_save_add(t, do_ctx.dest_fname, + maildir_save_add(t, do_ctx->dest_fname, flags | MAILDIR_SAVE_FLAG_HARDLINK, NULL, dest_mail); } else #endif { /* hardlinked to tmp/, treat as normal copied mail */ - maildir_save_add(t, do_ctx.dest_fname, flags, keywords, + maildir_save_add(t, do_ctx->dest_fname, flags, keywords, dest_mail); } return 1; @@ -276,14 +274,18 @@ struct maildir_transaction_context *t = (struct maildir_transaction_context *)ctx->transaction; struct maildir_mailbox *mbox = (struct maildir_mailbox *)t->ictx.ibox; + struct hardlink_ctx do_ctx; int ret; if (mbox->storage->copy_with_hardlinks && maildir_compatible_file_modes(&mbox->ibox.box, mail->box)) { T_BEGIN { + memset(&do_ctx, 0, sizeof(do_ctx)); ret = maildir_copy_hardlink(t, mail, ctx->flags, ctx->keywords, - ctx->dest_mail); + ctx->dest_mail, &do_ctx); + if (do_ctx.dest_path != NULL) + str_free(&do_ctx.dest_path); } T_END; if (ret != 0) {