dovecot-2.0: sdbox: Copying is now done with hard links.
dovecot at dovecot.org
dovecot at dovecot.org
Sun Mar 21 18:12:28 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/1bb98ad1af8b
changeset: 10965:1bb98ad1af8b
user: Timo Sirainen <tss at iki.fi>
date: Sun Mar 21 18:12:24 2010 +0200
description:
sdbox: Copying is now done with hard links.
diffstat:
src/lib-storage/index/dbox-common/dbox-save.h | 2 +
src/lib-storage/index/dbox-single/Makefile.am | 1 +
src/lib-storage/index/dbox-single/sdbox-copy.c | 89 ++++++++++++++++++++++
src/lib-storage/index/dbox-single/sdbox-file.c | 16 ++-
src/lib-storage/index/dbox-single/sdbox-file.h | 1 +
src/lib-storage/index/dbox-single/sdbox-save.c | 21 ++---
src/lib-storage/index/dbox-single/sdbox-storage.h | 1 +
7 files changed, 113 insertions(+), 18 deletions(-)
diffs (213 lines):
diff -r cc42255736ad -r 1bb98ad1af8b src/lib-storage/index/dbox-common/dbox-save.h
--- a/src/lib-storage/index/dbox-common/dbox-save.h Sun Mar 21 17:08:36 2010 +0200
+++ b/src/lib-storage/index/dbox-common/dbox-save.h Sun Mar 21 18:12:24 2010 +0200
@@ -1,6 +1,8 @@
#ifndef DBOX_SAVE_H
#define DBOX_SAVE_H
+#include "dbox-storage.h"
+
struct dbox_save_context {
struct mail_save_context ctx;
struct mail_index_transaction *trans;
diff -r cc42255736ad -r 1bb98ad1af8b src/lib-storage/index/dbox-single/Makefile.am
--- a/src/lib-storage/index/dbox-single/Makefile.am Sun Mar 21 17:08:36 2010 +0200
+++ b/src/lib-storage/index/dbox-single/Makefile.am Sun Mar 21 18:12:24 2010 +0200
@@ -11,6 +11,7 @@
-I$(top_srcdir)/src/lib-storage/index/dbox-common
libstorage_dbox_single_la_SOURCES = \
+ sdbox-copy.c \
sdbox-file.c \
sdbox-mail.c \
sdbox-save.c \
diff -r cc42255736ad -r 1bb98ad1af8b src/lib-storage/index/dbox-single/sdbox-copy.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/dbox-single/sdbox-copy.c Sun Mar 21 18:12:24 2010 +0200
@@ -0,0 +1,89 @@
+/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "nfs-workarounds.h"
+#include "dbox-save.h"
+#include "sdbox-storage.h"
+#include "sdbox-file.h"
+#include "mail-copy.h"
+
+static int
+sdbox_copy_hardlink(struct mail_save_context *_ctx, struct mail *mail)
+{
+ struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
+ struct sdbox_mailbox *dest_mbox =
+ (struct sdbox_mailbox *)_ctx->transaction->box;
+ struct sdbox_mailbox *src_mbox;
+ struct dbox_file *src_file, *dest_file;
+ const char *src_path;
+ int ret;
+
+ if (strcmp(mail->box->storage->name, SDBOX_STORAGE_NAME) == 0)
+ src_mbox = (struct sdbox_mailbox *)mail->box;
+ else {
+ /* Source storage isn't sdbox, can't hard link */
+ return 0;
+ }
+
+ src_file = sdbox_file_init(src_mbox, mail->uid);
+ dest_file = sdbox_file_init(dest_mbox, 0);
+
+ src_path = src_file->primary_path;
+ ret = nfs_safe_link(src_path, dest_file->cur_path, FALSE);
+ if (ret < 0 && errno == ENOENT && src_file->alt_path != NULL) {
+ src_path = src_file->alt_path;
+ ret = nfs_safe_link(src_path, dest_file->cur_path, FALSE);
+ }
+ if (ret < 0) {
+ if (ECANTLINK(errno))
+ return 0;
+
+ if (errno == ENOENT)
+ mail_set_expunged(mail);
+ else {
+ mail_storage_set_critical(
+ _ctx->transaction->box->storage,
+ "link(%s, %s) failed: %m",
+ src_path, dest_file->cur_path);
+ }
+ return -1;
+ }
+
+ dbox_save_add_to_index(ctx);
+ sdbox_save_add_file(_ctx, dest_file);
+ if (_ctx->dest_mail != NULL)
+ mail_set_seq(_ctx->dest_mail, ctx->seq);
+ return 1;
+}
+
+static bool
+sdbox_compatible_file_modes(struct mailbox *box1, struct mailbox *box2)
+{
+ return box1->file_create_mode == box2->file_create_mode &&
+ box1->file_create_gid == box2->file_create_gid;
+}
+
+int sdbox_copy(struct mail_save_context *_ctx, struct mail *mail)
+{
+ struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
+ struct mailbox_transaction_context *_t = _ctx->transaction;
+ struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)_t->box;
+ int ret;
+
+ i_assert((_t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
+
+ ctx->finished = TRUE;
+ if (sdbox_compatible_file_modes(&mbox->box, mail->box)) {
+ T_BEGIN {
+ ret = sdbox_copy_hardlink(_ctx, mail);
+ } T_END;
+
+ if (ret != 0) {
+ index_save_context_free(_ctx);
+ return ret > 0 ? 0 : -1;
+ }
+
+ /* non-fatal hardlinking failure, try the slow way */
+ }
+ return mail_storage_copy(_ctx, mail);
+}
diff -r cc42255736ad -r 1bb98ad1af8b src/lib-storage/index/dbox-single/sdbox-file.c
--- a/src/lib-storage/index/dbox-single/sdbox-file.c Sun Mar 21 17:08:36 2010 +0200
+++ b/src/lib-storage/index/dbox-single/sdbox-file.c Sun Mar 21 18:12:24 2010 +0200
@@ -45,13 +45,17 @@
}
} T_END;
dbox_file_init(&file->file);
+ return &file->file;
+}
- if (uid == 0) {
- file->file.fd = file->file.storage->v.
- file_create_fd(&file->file, file->file.primary_path,
- FALSE);
- }
- return &file->file;
+struct dbox_file *sdbox_file_create(struct sdbox_mailbox *mbox)
+{
+ struct dbox_file *file;
+
+ file = sdbox_file_init(mbox, 0);
+ file->fd = file->storage->v.
+ file_create_fd(file, file->primary_path, FALSE);
+ return file;
}
int sdbox_file_assign_uid(struct sdbox_file *file, uint32_t uid)
diff -r cc42255736ad -r 1bb98ad1af8b src/lib-storage/index/dbox-single/sdbox-file.h
--- a/src/lib-storage/index/dbox-single/sdbox-file.h Sun Mar 21 17:08:36 2010 +0200
+++ b/src/lib-storage/index/dbox-single/sdbox-file.h Sun Mar 21 18:12:24 2010 +0200
@@ -12,6 +12,7 @@
};
struct dbox_file *sdbox_file_init(struct sdbox_mailbox *mbox, uint32_t uid);
+struct dbox_file *sdbox_file_create(struct sdbox_mailbox *mbox);
/* Assign UID for a newly created file (by renaming it) */
int sdbox_file_assign_uid(struct sdbox_file *file, uint32_t uid);
diff -r cc42255736ad -r 1bb98ad1af8b src/lib-storage/index/dbox-single/sdbox-save.c
--- a/src/lib-storage/index/dbox-single/sdbox-save.c Sun Mar 21 17:08:36 2010 +0200
+++ b/src/lib-storage/index/dbox-single/sdbox-save.c Sun Mar 21 18:12:24 2010 +0200
@@ -70,13 +70,20 @@
return t->save_ctx;
}
+void sdbox_save_add_file(struct mail_save_context *_ctx, struct dbox_file *file)
+{
+ struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;
+
+ array_append(&ctx->files, &file, 1);
+}
+
int sdbox_save_begin(struct mail_save_context *_ctx, struct istream *input)
{
struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;
struct dbox_file *file;
int ret;
- file = sdbox_file_init(ctx->mbox, 0);
+ file = sdbox_file_create(ctx->mbox);
ctx->append_ctx = dbox_file_append_init(file);
ret = dbox_file_get_append_stream(ctx->append_ctx,
&ctx->ctx.dbox_output);
@@ -93,7 +100,7 @@
if (ctx->first_saved_seq == 0)
ctx->first_saved_seq = ctx->ctx.seq;
- array_append(&ctx->files, &file, 1);
+ sdbox_save_add_file(_ctx, file);
return ctx->ctx.failed ? -1 : 0;
}
@@ -295,13 +302,3 @@
mail_free(&ctx->ctx.mail);
i_free(ctx);
}
-
-int sdbox_copy(struct mail_save_context *_ctx, struct mail *mail)
-{
- struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
-
- /* FIXME: use hard linking */
-
- ctx->finished = TRUE;
- return mail_storage_copy(_ctx, mail);
-}
diff -r cc42255736ad -r 1bb98ad1af8b src/lib-storage/index/dbox-single/sdbox-storage.h
--- a/src/lib-storage/index/dbox-single/sdbox-storage.h Sun Mar 21 17:08:36 2010 +0200
+++ b/src/lib-storage/index/dbox-single/sdbox-storage.h Sun Mar 21 18:12:24 2010 +0200
@@ -53,6 +53,7 @@
struct dbox_file *
sdbox_save_file_get_file(struct mailbox_transaction_context *t, uint32_t seq);
+void sdbox_save_add_file(struct mail_save_context *ctx, struct dbox_file *file);
int sdbox_transaction_save_commit_pre(struct mail_save_context *ctx);
void sdbox_transaction_save_commit_post(struct mail_save_context *ctx,
More information about the dovecot-cvs
mailing list