dovecot-2.0-sslstream: mdbox: Purging now also moves mails to al...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 13 03:00:27 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0-sslstream/rev/c60910419861
changeset: 10636:c60910419861
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Feb 02 23:49:32 2010 +0200
description:
mdbox: Purging now also moves mails to alt storage (if it's used).
mdbox_altmove setting specifies how old files should be moved.

diffstat:

13 files changed, 312 insertions(+), 81 deletions(-)
doc/example-config/conf.d/mail.conf                  |    3 
src/lib-storage/index/dbox-common/dbox-file.c        |   29 +-
src/lib-storage/index/dbox-common/dbox-file.h        |    2 
src/lib-storage/index/dbox-multi/mdbox-file-purge.c  |    8 
src/lib-storage/index/dbox-multi/mdbox-file.c        |   30 ++
src/lib-storage/index/dbox-multi/mdbox-file.h        |    2 
src/lib-storage/index/dbox-multi/mdbox-map-private.h |    3 
src/lib-storage/index/dbox-multi/mdbox-map.c         |  216 +++++++++++++-----
src/lib-storage/index/dbox-multi/mdbox-map.h         |    9 
src/lib-storage/index/dbox-multi/mdbox-save.c        |    2 
src/lib-storage/index/dbox-multi/mdbox-settings.c    |    2 
src/lib-storage/index/dbox-multi/mdbox-settings.h    |    1 
src/lib-storage/index/dbox-multi/mdbox-sync.c        |   86 ++++++-

diffs (truncated from 753 to 300 lines):

diff -r 55cce06818b8 -r c60910419861 doc/example-config/conf.d/mail.conf
--- a/doc/example-config/conf.d/mail.conf	Tue Feb 02 23:24:52 2010 +0200
+++ b/doc/example-config/conf.d/mail.conf	Tue Feb 02 23:49:32 2010 +0200
@@ -310,3 +310,6 @@
 # Maximum dbox file age until it's rotated. Typically in days. Day begins
 # from midnight, so 1d = today, 2d = yesterday, etc. 0 = check disabled.
 #mdbox_rotate_interval = 1d
+
+# When purging, move unchanged files to alt storage after this much time.
+#mdbox_altmove = 1w
diff -r 55cce06818b8 -r c60910419861 src/lib-storage/index/dbox-common/dbox-file.c
--- a/src/lib-storage/index/dbox-common/dbox-file.c	Tue Feb 02 23:24:52 2010 +0200
+++ b/src/lib-storage/index/dbox-common/dbox-file.c	Tue Feb 02 23:49:32 2010 +0200
@@ -155,7 +155,7 @@ static int dbox_file_read_header(struct 
 	return ret;
 }
 
-static int dbox_file_open_fd(struct dbox_file *file)
+static int dbox_file_open_fd(struct dbox_file *file, bool try_altpath)
 {
 	const char *path;
 	bool alt = FALSE;
@@ -169,7 +169,7 @@ static int dbox_file_open_fd(struct dbox
 			return -1;
 		}
 
-		if (file->alt_path == NULL || alt) {
+		if (file->alt_path == NULL || alt || !try_altpath) {
 			/* not found */
 			return 0;
 		}
@@ -182,22 +182,23 @@ static int dbox_file_open_fd(struct dbox
 	return 1;
 }
 
-int dbox_file_open(struct dbox_file *file, bool *deleted_r)
-{
-	int ret;
-
-	*deleted_r = FALSE;
+static int dbox_file_open_full(struct dbox_file *file, bool try_altpath,
+			       bool *notfound_r)
+{
+	int ret;
+
+	*notfound_r = FALSE;
 	if (file->input != NULL)
 		return 1;
 
 	if (file->fd == -1) {
 		T_BEGIN {
-			ret = dbox_file_open_fd(file);
+			ret = dbox_file_open_fd(file, try_altpath);
 		} T_END;
 		if (ret <= 0) {
 			if (ret < 0)
 				return -1;
-			*deleted_r = TRUE;
+			*notfound_r = TRUE;
 			return 1;
 		}
 	}
@@ -205,6 +206,16 @@ int dbox_file_open(struct dbox_file *fil
 	file->input = i_stream_create_fd(file->fd, 0, FALSE);
 	i_stream_set_init_buffer_size(file->input, DBOX_READ_BLOCK_SIZE);
 	return dbox_file_read_header(file);
+}
+
+int dbox_file_open(struct dbox_file *file, bool *deleted_r)
+{
+	return dbox_file_open_full(file, TRUE, deleted_r);
+}
+
+int dbox_file_open_primary(struct dbox_file *file, bool *notfound_r)
+{
+	return dbox_file_open_full(file, FALSE, notfound_r);
 }
 
 int dbox_file_header_write(struct dbox_file *file, struct ostream *output)
diff -r 55cce06818b8 -r c60910419861 src/lib-storage/index/dbox-common/dbox-file.h
--- a/src/lib-storage/index/dbox-common/dbox-file.h	Tue Feb 02 23:24:52 2010 +0200
+++ b/src/lib-storage/index/dbox-common/dbox-file.h	Tue Feb 02 23:49:32 2010 +0200
@@ -125,6 +125,8 @@ void dbox_file_unref(struct dbox_file **
 /* Open the file. Returns 1 if ok, 0 if file header is corrupted, -1 if error.
    If file is deleted, deleted_r=TRUE and 1 is returned. */
 int dbox_file_open(struct dbox_file *file, bool *deleted_r);
+/* Try to open file only from primary path. */
+int dbox_file_open_primary(struct dbox_file *file, bool *notfound_r);
 /* Close the file handle from the file, but don't free it. */
 void dbox_file_close(struct dbox_file *file);
 
diff -r 55cce06818b8 -r c60910419861 src/lib-storage/index/dbox-multi/mdbox-file-purge.c
--- a/src/lib-storage/index/dbox-multi/mdbox-file-purge.c	Tue Feb 02 23:24:52 2010 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-file-purge.c	Tue Feb 02 23:49:32 2010 +0200
@@ -95,6 +95,7 @@ int mdbox_file_purge(struct dbox_file *f
 	ARRAY_TYPE(uint32_t) copied_map_uids;
 	unsigned int i, count;
 	uoff_t offset, physical_size, msg_size;
+	enum dbox_map_append_flags append_flags = 0;
 	int ret;
 
 	if ((ret = dbox_file_try_lock(file)) <= 0)
@@ -111,6 +112,11 @@ int mdbox_file_purge(struct dbox_file *f
 			"stat(%s) failed: %m", file->cur_path);
 		return -1;
 	}
+
+	if (dstorage->set->mdbox_altmove > 0 &&
+	    st.st_mtime + dstorage->set->mdbox_altmove < ioloop_time &&
+	    dstorage->alt_storage_dir != NULL)
+		append_flags |= DBOX_MAP_APPEND_FLAG_ALT;
 
 	i_array_init(&msgs_arr, 128);
 	if (dbox_map_get_file_msgs(dstorage->map,
@@ -124,7 +130,7 @@ int mdbox_file_purge(struct dbox_file *f
 	array_sort(&msgs_arr, mdbox_map_file_msg_offset_cmp);
 
 	msgs = array_get(&msgs_arr, &count);
-	append_ctx = dbox_map_append_begin(dstorage->map);
+	append_ctx = dbox_map_append_begin(dstorage->map, append_flags);
 	i_array_init(&copied_map_uids, I_MIN(count, 1));
 	i_array_init(&expunged_map_uids, I_MIN(count, 1));
 	offset = file->file_header_size;
diff -r 55cce06818b8 -r c60910419861 src/lib-storage/index/dbox-multi/mdbox-file.c
--- a/src/lib-storage/index/dbox-multi/mdbox-file.c	Tue Feb 02 23:24:52 2010 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-file.c	Tue Feb 02 23:49:32 2010 +0200
@@ -103,10 +103,12 @@ static void mdbox_file_init_paths(struct
 
 static int mdbox_file_create(struct dbox_file *file)
 {
+	bool create_parents;
 	int ret;
 
+	create_parents = dbox_file_is_in_alt(file);
 	file->fd = file->storage->v.
-		file_create_fd(file, file->primary_path, FALSE);
+		file_create_fd(file, file->cur_path, create_parents);
 
 	/* even though we don't need it locked while writing to it, by the
 	   time we rename() it it needs to be locked. so we might as well do
@@ -122,8 +124,9 @@ static int mdbox_file_create(struct dbox
 	return 0;
 }
 
-struct dbox_file *
-mdbox_file_init(struct mdbox_storage *storage, uint32_t file_id)
+static struct dbox_file *
+mdbox_file_init_full(struct mdbox_storage *storage,
+		     uint32_t file_id, bool alt_dir)
 {
 	struct mdbox_file *file;
 	const char *fname;
@@ -150,6 +153,8 @@ mdbox_file_init(struct mdbox_storage *st
 		t_strdup_printf(MDBOX_MAIL_FILE_FORMAT, file_id);
 	mdbox_file_init_paths(file, fname);
 	dbox_file_init(&file->file);
+	if (alt_dir)
+		file->file.cur_path = file->file.alt_path;
 
 	if (file_id != 0)
 		array_append(&storage->open_files, &file, 1);
@@ -158,18 +163,31 @@ mdbox_file_init(struct mdbox_storage *st
 	return &file->file;
 }
 
+struct dbox_file *
+mdbox_file_init(struct mdbox_storage *storage, uint32_t file_id)
+{
+	return mdbox_file_init_full(storage, file_id, FALSE);
+}
+
+struct dbox_file *
+mdbox_file_init_new_alt(struct mdbox_storage *storage)
+{
+	return mdbox_file_init_full(storage, 0, TRUE);
+}
+
 int mdbox_file_assign_file_id(struct mdbox_file *file, uint32_t file_id)
 {
 	const char *old_path;
-	const char *new_fname, *new_path;
+	const char *new_dir, *new_fname, *new_path;
 
 	i_assert(file->file_id == 0);
 	i_assert(file_id != 0);
 
 	old_path = file->file.cur_path;
 	new_fname = t_strdup_printf(MDBOX_MAIL_FILE_FORMAT, file_id);
-	new_path = t_strdup_printf("%s/%s", file->storage->storage_dir,
-				   new_fname);
+	new_dir = !dbox_file_is_in_alt(&file->file) ?
+		file->storage->storage_dir : file->storage->alt_storage_dir;
+	new_path = t_strdup_printf("%s/%s", new_dir, new_fname);
 	if (rename(old_path, new_path) < 0) {
 		mail_storage_set_critical(&file->storage->storage.storage,
 					  "rename(%s, %s) failed: %m",
diff -r 55cce06818b8 -r c60910419861 src/lib-storage/index/dbox-multi/mdbox-file.h
--- a/src/lib-storage/index/dbox-multi/mdbox-file.h	Tue Feb 02 23:24:52 2010 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-file.h	Tue Feb 02 23:49:32 2010 +0200
@@ -12,6 +12,8 @@ struct mdbox_file {
 
 struct dbox_file *
 mdbox_file_init(struct mdbox_storage *storage, uint32_t file_id);
+struct dbox_file *
+mdbox_file_init_new_alt(struct mdbox_storage *storage);
 
 /* Assign file ID for a newly created file. */
 int mdbox_file_assign_file_id(struct mdbox_file *file, uint32_t file_id);
diff -r 55cce06818b8 -r c60910419861 src/lib-storage/index/dbox-multi/mdbox-map-private.h
--- a/src/lib-storage/index/dbox-multi/mdbox-map-private.h	Tue Feb 02 23:24:52 2010 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-map-private.h	Tue Feb 02 23:49:32 2010 +0200
@@ -19,7 +19,6 @@ struct dbox_map {
 	uint32_t created_uid_validity;
 
 	uint32_t map_ext_id, ref_ext_id;
-	ARRAY_TYPE(seq_range) ref0_file_ids;
 
 	mode_t create_mode, create_dir_mode;
 	gid_t create_gid;
@@ -33,6 +32,7 @@ struct dbox_map_append {
 
 struct dbox_map_append_context {
 	struct dbox_map *map;
+	enum dbox_map_append_flags flags;
 
 	struct mail_index_sync_ctx *sync_ctx;
 	struct mail_index_view *sync_view;
@@ -43,7 +43,6 @@ struct dbox_map_append_context {
 	ARRAY_DEFINE(appends, struct dbox_map_append);
 
 	uint32_t first_new_file_id;
-	uint32_t orig_next_uid;
 
 	unsigned int files_nonappendable_count;
 
diff -r 55cce06818b8 -r c60910419861 src/lib-storage/index/dbox-multi/mdbox-map.c
--- a/src/lib-storage/index/dbox-multi/mdbox-map.c	Tue Feb 02 23:24:52 2010 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-map.c	Tue Feb 02 23:49:32 2010 +0200
@@ -8,6 +8,9 @@
 #include "mdbox-storage.h"
 #include "mdbox-file.h"
 #include "mdbox-map-private.h"
+
+#include <stdlib.h>
+#include <dirent.h>
 
 #define MAX_BACKWARDS_LOOKUPS 10
 
@@ -75,8 +78,6 @@ void dbox_map_deinit(struct dbox_map **_
 
 	*_map = NULL;
 
-	if (array_is_created(&map->ref0_file_ids))
-		array_free(&map->ref0_file_ids);
 	if (map->view != NULL)
 		mail_index_view_close(&map->view);
 	mail_index_free(&map->index);
@@ -264,12 +265,8 @@ int dbox_map_get_file_msgs(struct dbox_m
 	return 0;
 }
 
-struct dbox_file_size {
-	uoff_t file_size;
-	uoff_t ref0_size;
-};
-
-const ARRAY_TYPE(seq_range) *dbox_map_get_zero_ref_files(struct dbox_map *map)
+int dbox_map_get_zero_ref_files(struct dbox_map *map,
+				ARRAY_TYPE(seq_range) *file_ids_r)
 {
 	const struct mail_index_header *hdr;
 	const struct dbox_map_mail_index_record *rec;
@@ -278,16 +275,12 @@ const ARRAY_TYPE(seq_range) *dbox_map_ge
 	uint32_t seq;
 	bool expunged;
 
-	if (array_is_created(&map->ref0_file_ids))
-		array_clear(&map->ref0_file_ids);
-	else
-		i_array_init(&map->ref0_file_ids, 64);
-
 	if (dbox_map_open(map, FALSE) < 0) {
 		/* some internal error */
-		return &map->ref0_file_ids;
-	}
-	(void)dbox_map_refresh(map);
+		return -1;
+	}
+	if (dbox_map_refresh(map) < 0)
+		return -1;
 
 	hdr = mail_index_get_header(map->view);
 	for (seq = 1; seq <= hdr->messages_count; seq++) {
@@ -303,11 +296,10 @@ const ARRAY_TYPE(seq_range) *dbox_map_ge
 				      &data, &expunged);
 		if (data != NULL && !expunged) {
 			rec = data;
-			seq_range_array_add(&map->ref0_file_ids, 0,
-					    rec->file_id);
-		}


More information about the dovecot-cvs mailing list