dovecot-1.2: maildir: Fixed a memory leak when copying with hard...
dovecot at dovecot.org
dovecot at dovecot.org
Fri May 14 17:29:30 EEST 2010
details: http://hg.dovecot.org/dovecot-1.2/rev/2129667cb499
changeset: 9569:2129667cb499
user: Timo Sirainen <tss at iki.fi>
date: Fri May 14 16:29:27 2010 +0200
description:
maildir: Fixed a memory leak when copying with hardlinks.
diffstat:
src/lib-storage/index/maildir/maildir-copy.c | 50 +++++++++++++------------
1 files changed, 26 insertions(+), 24 deletions(-)
diffs (136 lines):
diff -r 46d3128626b7 -r 2129667cb499 src/lib-storage/index/maildir/maildir-copy.c
--- 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) {
More information about the dovecot-cvs
mailing list