changeset 6023:56879cc53cec HEAD

mail_storage.create() now returns error message string. Also fixed handling "/" and empty root paths.
author Timo Sirainen <tss@iki.fi>
date Sun, 15 Jul 2007 15:30:00 +0300
parents 8da2881df0dc
children 6074e9e6059d
files src/deliver/deliver.c src/lib-storage/index/cydir/cydir-storage.c src/lib-storage/index/dbox/dbox-storage.c src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/mail-namespace.c src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h src/lib-storage/mailbox-list.c src/plugins/convert/convert-storage.c
diffstat 11 files changed, 127 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/src/deliver/deliver.c	Sun Jul 15 15:27:58 2007 +0300
+++ b/src/deliver/deliver.c	Sun Jul 15 15:30:00 2007 +0300
@@ -555,7 +555,7 @@
 	const char *envelope_sender = DEFAULT_ENVELOPE_SENDER;
 	const char *mailbox = "INBOX";
 	const char *auth_socket;
-	const char *home, *destination, *user, *value;
+	const char *home, *destination, *user, *value, *error;
 	struct mail_namespace *ns, *mbox_ns;
 	struct mail_storage *storage;
 	struct mailbox *box;
@@ -738,8 +738,8 @@
 
 	mbox_ns = mail_namespaces_init_empty(namespace_pool);
 	if (mail_storage_create(mbox_ns, "mbox", "/tmp", destination,
-				0, FILE_LOCK_METHOD_FCNTL) < 0)
-		i_fatal("Couldn't create internal mbox storage");
+				0, FILE_LOCK_METHOD_FCNTL, &error) < 0)
+		i_fatal("Couldn't create internal mbox storage: %s", error);
 	input = create_mbox_stream(0, envelope_sender);
 	box = mailbox_open(mbox_ns->storage, "Dovecot Delivery Mail", input,
 			   MAILBOX_OPEN_NO_INDEX_FILES |
--- a/src/lib-storage/index/cydir/cydir-storage.c	Sun Jul 15 15:27:58 2007 +0300
+++ b/src/lib-storage/index/cydir/cydir-storage.c	Sun Jul 15 15:30:00 2007 +0300
@@ -37,7 +37,8 @@
 
 static int
 cydir_get_list_settings(struct mailbox_list_settings *list_set,
-			const char *data, enum mail_storage_flags flags)
+			const char *data, enum mail_storage_flags flags,
+			const char **error_r)
 {
 	bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
 	const char *p;
@@ -47,10 +48,11 @@
 	list_set->subscription_fname = CYDIR_SUBSCRIPTION_FILE_NAME;
 	list_set->maildir_name = "";
 
-	if (data == NULL || *data == '\0') {
+	if (data == NULL || *data == '\0' || *data == ':') {
 		/* we won't do any guessing for this format. */
 		if (debug)
 			i_info("cydir: mailbox location not given");
+		*error_r = "Root mail directory not given";
 		return -1;
 	}
 
@@ -73,7 +75,7 @@
 
 	/* strip trailing '/' */
 	len = strlen(list_set->root_dir);
-	if (list_set->root_dir[len-1] == '/')
+	if (len > 1 && list_set->root_dir[len-1] == '/')
 		list_set->root_dir = t_strndup(list_set->root_dir, len-1);
 
 	if (list_set->index_dir != NULL &&
@@ -95,14 +97,15 @@
 	return &storage->storage;
 }
 
-static int cydir_create(struct mail_storage *_storage, const char *data)
+static int cydir_create(struct mail_storage *_storage, const char *data,
+			const char **error_r)
 {
 	struct cydir_storage *storage = (struct cydir_storage *)_storage;
 	struct mailbox_list_settings list_set;
-	const char *error;
 	struct stat st;
 
-	if (cydir_get_list_settings(&list_set, data, _storage->flags) < 0)
+	if (cydir_get_list_settings(&list_set, data, _storage->flags,
+				    error_r) < 0)
 		return -1;
 	list_set.mail_storage_flags = &_storage->flags;
 	list_set.lock_method = &_storage->lock_method;
@@ -110,7 +113,12 @@
 	if ((_storage->flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) {
 		if (stat(list_set.root_dir, &st) < 0) {
 			if (errno != ENOENT) {
-				i_error("stat(%s) failed: %m",
+				*error_r = t_strdup_printf(
+							"stat(%s) failed: %m",
+							list_set.root_dir);
+			} else {
+				*error_r = t_strdup_printf(
+					"Root mail directory doesn't exist: %s",
 					list_set.root_dir);
 			}
 			return -1;
@@ -118,18 +126,16 @@
 	} else {
 		if (mkdir_parents(list_set.root_dir, CREATE_MODE) < 0 &&
 		    errno != EEXIST) {
-			i_error("mkdir_parents(%s) failed: %m",
-				list_set.root_dir);
+			*error_r = t_strdup_printf("mkdir(%s) failed: %m",
+						   list_set.root_dir);
 			return -1;
 		}
 	}
 
 	if (mailbox_list_init(_storage->ns, "fs", &list_set,
 			      mail_storage_get_list_flags(_storage->flags),
-			      &_storage->list, &error) < 0) {
-		i_error("cydir fs: %s", error);
+			      &_storage->list, error_r) < 0)
 		return -1;
-	}
 	storage->list_module_ctx.super = _storage->list->v;
 	_storage->list->v.iter_is_mailbox = cydir_list_iter_is_mailbox;
 	_storage->list->v.delete_mailbox = cydir_list_delete_mailbox;
--- a/src/lib-storage/index/dbox/dbox-storage.c	Sun Jul 15 15:27:58 2007 +0300
+++ b/src/lib-storage/index/dbox/dbox-storage.c	Sun Jul 15 15:30:00 2007 +0300
@@ -117,7 +117,8 @@
 
 static int
 dbox_get_list_settings(struct mailbox_list_settings *list_set,
-		       const char *data, enum mail_storage_flags flags)
+		       const char *data, enum mail_storage_flags flags,
+		       const char **error_r)
 {
 	bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
 	const char *p;
@@ -127,10 +128,11 @@
 	list_set->subscription_fname = DBOX_SUBSCRIPTION_FILE_NAME;
 	list_set->maildir_name = DBOX_MAILDIR_NAME;
 
-	if (data == NULL || *data == '\0') {
+	if (data == NULL || *data == '\0' || *data == ':') {
 		/* we won't do any guessing for this format. */
 		if (debug)
 			i_info("dbox: mailbox location not given");
+		*error_r = "Root mail directory not given";
 		return -1;
 	}
 
@@ -175,15 +177,16 @@
 	return &storage->storage;
 }
 
-static int dbox_create(struct mail_storage *_storage, const char *data)
+static int dbox_create(struct mail_storage *_storage, const char *data,
+		       const char **error_r)
 {
 	struct dbox_storage *storage = (struct dbox_storage *)_storage;
 	struct mailbox_list_settings list_set;
 	struct mailbox_list *list;
-	const char *error;
 	struct stat st;
 
-	if (dbox_get_list_settings(&list_set, data, _storage->flags) < 0)
+	if (dbox_get_list_settings(&list_set, data, _storage->flags,
+				   error_r) < 0)
 		return -1;
 	list_set.mail_storage_flags = &_storage->flags;
 	list_set.lock_method = &_storage->lock_method;
@@ -191,7 +194,12 @@
 	if ((_storage->flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) {
 		if (stat(list_set.root_dir, &st) < 0) {
 			if (errno != ENOENT) {
-				i_error("stat(%s) failed: %m",
+				*error_r = t_strdup_printf(
+							"stat(%s) failed: %m",
+							list_set.root_dir);
+			} else {
+				*error_r = t_strdup_printf(
+					"Root mail directory doesn't exist: %s",
 					list_set.root_dir);
 			}
 			return -1;
@@ -199,18 +207,17 @@
 	} else {
 		if (mkdir_parents(list_set.root_dir, CREATE_MODE) < 0 &&
 		    errno != EEXIST) {
-			i_error("mkdir_parents(%s) failed: %m",
-				list_set.root_dir);
+			*error_r = t_strdup_printf("mkdir(%s) failed: %m",
+						   list_set.root_dir);
 			return -1;
 		}
 	}
 
 	if (mailbox_list_init(_storage->ns, "fs", &list_set,
 			      mail_storage_get_list_flags(_storage->flags),
-			      &list, &error) < 0) {
-		i_error("dbox fs: %s", error);
+			      &list, error_r) < 0)
 		return -1;
-	}
+
 	_storage->list = list;
 	storage->list_module_ctx.super = list->v;
 	list->v.is_valid_existing_name = dbox_storage_is_valid_existing_name;
--- a/src/lib-storage/index/maildir/maildir-storage.c	Sun Jul 15 15:27:58 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Sun Jul 15 15:30:00 2007 +0300
@@ -62,7 +62,7 @@
 {
 	size_t len = strlen(path);
 
-	if (len > 0 && path[len-1] == '/')
+	if (len > 1 && path[len-1] == '/')
 		return t_strndup(path, len-1);
 	else
 		return path;
@@ -76,7 +76,7 @@
 static int
 maildir_get_list_settings(struct mailbox_list_settings *list_set,
 			  const char *data, enum mail_storage_flags flags,
-			  const char **layout_r)
+			  const char **layout_r, const char **error_r)
 {
 	bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
 	const char *home, *path, *p;
@@ -89,7 +89,7 @@
 
 	if (data == NULL || *data == '\0') {
 		if ((flags & MAIL_STORAGE_FLAG_NO_AUTODETECTION) != 0) {
-			i_error("maildir: root directory not given");
+			*error_r = "Root mail directory not given";
 			return -1;
 		}
 
@@ -149,9 +149,10 @@
 		}
 	}
 
-	if (list_set->root_dir == NULL) {
+	if (list_set->root_dir == NULL || *list_set->root_dir == '\0') {
 		if (debug)
 			i_info("maildir: couldn't find root dir");
+		*error_r = "Root mail directory not given";
 		return -1;
 	}
 	list_set->root_dir = strip_tail_slash(list_set->root_dir);
@@ -223,16 +224,18 @@
 }
 
 static int
-maildir_create(struct mail_storage *_storage, const char *data)
+maildir_create(struct mail_storage *_storage, const char *data,
+	       const char **error_r)
 {
 	struct maildir_storage *storage = (struct maildir_storage *)_storage;
 	enum mail_storage_flags flags = _storage->flags;
 	struct mailbox_list_settings list_set;
 	struct mailbox_list *list;
-	const char *layout, *error;
+	const char *layout;
 	struct stat st;
 
-	if (maildir_get_list_settings(&list_set, data, flags, &layout) < 0)
+	if (maildir_get_list_settings(&list_set, data, flags, &layout,
+				      error_r) < 0)
 		return -1;
 	list_set.mail_storage_flags = &_storage->flags;
 	list_set.lock_method = &_storage->lock_method;
@@ -244,16 +247,16 @@
 				i_error("stat(%s) failed: %m",
 					list_set.root_dir);
 			}
+			*error_r = "Mail storage doesn't exist";
 			return -1;
 		}
 	}
 
 	if (mailbox_list_init(_storage->ns, layout, &list_set,
 			      mail_storage_get_list_flags(flags),
-			      &list, &error) < 0) {
-		i_error("maildir %s: %s", layout, error);
+			      &list, error_r) < 0)
 		return -1;
-	}
+
 	_storage->list = list;
 	storage->list_module_ctx.super = list->v;
 	if (strcmp(layout, MAILDIR_PLUSPLUS_DRIVER_NAME) == 0) {
--- a/src/lib-storage/index/mbox/mbox-storage.c	Sun Jul 15 15:27:58 2007 +0300
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Sun Jul 15 15:30:00 2007 +0300
@@ -253,20 +253,20 @@
 	return path;
 }
 
-static const char *create_root_dir(bool debug)
+static const char *create_root_dir(bool debug, const char **error_r)
 {
 	const char *home, *path;
 
 	home = getenv("HOME");
 	if (home == NULL) {
-		i_error("mbox: We need root mail directory, "
-			"but can't find it or HOME environment");
+		*error_r = "Root mail directory not set and "
+			"home directory is missing";
 		return NULL;
 	}
 
 	path = t_strconcat(home, "/mail", NULL);
 	if (mkdir_parents(path, CREATE_MODE) < 0) {
-		i_error("mbox: Can't create root mail directory %s: %m", path);
+		*error_r = t_strdup_printf("mkdir(%s) failed: %m", path);
 		return NULL;
 	}
 
@@ -278,7 +278,7 @@
 static int
 mbox_get_list_settings(struct mailbox_list_settings *list_set,
 		       const char *data, enum mail_storage_flags flags,
-		       const char **layout_r)
+		       const char **layout_r, const char **error_r)
 {
 	bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
 	const char *p;
@@ -294,7 +294,7 @@
 	autodetect = data == NULL || *data == '\0';
 	if (autodetect) {
 		if ((flags & MAIL_STORAGE_FLAG_NO_AUTODETECTION) != 0) {
-			i_error("mbox: root mail directory not given");
+			*error_r = "Root mail directory not given";
 			return -1;
 		}
 
@@ -335,18 +335,20 @@
 		}
 	}
 
-	if (list_set->root_dir == NULL) {
-		if ((flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0)
+	if (list_set->root_dir == NULL || *list_set->root_dir == '\0') {
+		if ((flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) {
+			*error_r = "Root mail directory not given";
 			return -1;
+		}
 
-		list_set->root_dir = create_root_dir(debug);
+		list_set->root_dir = create_root_dir(debug, error_r);
 		if (list_set->root_dir == NULL)
 			return -1;
 	} else {
 		/* strip trailing '/' */
 		size_t len = strlen(list_set->root_dir);
 
-		if (list_set->root_dir[len-1] == '/') {
+		if (len > 1 && list_set->root_dir[len-1] == '/') {
 			list_set->root_dir =
 				t_strndup(list_set->root_dir, len-1);
 		}
@@ -357,14 +359,18 @@
 		    lstat(list_set->root_dir, &st) == 0) {
 			/* yep, go ahead */
 		} else if (errno != ENOENT && errno != ENOTDIR) {
-			i_error("lstat(%s) failed: %m", list_set->root_dir);
+			*error_r = t_strdup_printf("lstat(%s) failed: %m",
+						   list_set->root_dir);
 			return -1;
 		} else if ((flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) {
+			*error_r = t_strdup_printf(
+					"Root mail directory doesn't exist: %s",
+					list_set->root_dir);
 			return -1;
 		} else if (mkdir_parents(list_set->root_dir, CREATE_MODE) < 0 &&
 			   errno != EEXIST) {
-			i_error("mkdir_parents(%s) failed: %m",
-				list_set->root_dir);
+			*error_r = t_strdup_printf("mkdir(%s) failed: %m",
+						   list_set->root_dir);
 			return -1;
 		}
 	}
@@ -413,24 +419,24 @@
 	return &storage->storage;
 }
 
-static int mbox_create(struct mail_storage *_storage, const char *data)
+static int mbox_create(struct mail_storage *_storage, const char *data,
+		       const char **error_r)
 {
 	struct mbox_storage *storage = (struct mbox_storage *)_storage;
 	struct mailbox_list_settings list_set;
-	const char *layout, *error;
+	const char *layout;
 
 	if (mbox_get_list_settings(&list_set, data,
-				   _storage->flags, &layout) < 0)
+				   _storage->flags, &layout, error_r) < 0)
 		return -1;
 	list_set.mail_storage_flags = &_storage->flags;
 	list_set.lock_method = &_storage->lock_method;
 
 	if (mailbox_list_init(_storage->ns, layout, &list_set,
 			      mail_storage_get_list_flags(_storage->flags),
-			      &_storage->list, &error) < 0) {
-		i_error("mbox %s: %s", layout, error);
+			      &_storage->list, error_r) < 0)
 		return -1;
-	}
+
 	storage->list_module_ctx.super = _storage->list->v;
 	if (strcmp(layout, "fs") == 0 && *list_set.maildir_name == '\0') {
 		/* have to use .imap/ directories */
--- a/src/lib-storage/mail-namespace.c	Sun Jul 15 15:27:58 2007 +0300
+++ b/src/lib-storage/mail-namespace.c	Sun Jul 15 15:30:00 2007 +0300
@@ -30,7 +30,7 @@
 		  enum file_lock_method lock_method)
 {
         struct mail_namespace *ns;
-	const char *sep, *type, *prefix;
+	const char *sep, *type, *prefix, *error;
 
 	ns = p_new(pool, struct mail_namespace, 1);
 
@@ -69,9 +69,9 @@
 	}
 
 	ns->prefix = p_strdup(pool, prefix);
-	if (mail_storage_create(ns, NULL, data, user, flags, lock_method) < 0) {
-		i_error("Namespace '%s' mail storage creation failed "
-			"with mail location: %s", ns->prefix, data);
+	if (mail_storage_create(ns, NULL, data, user, flags, lock_method,
+				&error) < 0) {
+		i_error("Namespace '%s': %s", ns->prefix, error);
 		return NULL;
 	}
 
@@ -164,7 +164,7 @@
 	struct mail_namespace *namespaces, *ns, **ns_p;
 	enum mail_storage_flags flags;
         enum file_lock_method lock_method;
-	const char *mail, *data;
+	const char *mail, *data, *error;
 	unsigned int i;
 
 	mail_storage_parse_env(&flags, &lock_method);
@@ -212,18 +212,13 @@
 	ns->flags = NAMESPACE_FLAG_INBOX | NAMESPACE_FLAG_LIST;
 	ns->prefix = "";
 
-	if (mail_storage_create(ns, NULL, mail, user, flags, lock_method) < 0) {
-		if (mail != NULL && *mail != '\0') {
-			i_error("Mail storage creation failed with "
-				"mail_location: %s", mail);
-		} else {
-			const char *home;
-
-			home = getenv("HOME");
-			if (home == NULL || *home == '\0') home = "(not set)";
-
+	if (mail_storage_create(ns, NULL, mail, user, flags, lock_method,
+				&error) < 0) {
+		if (mail != NULL && *mail != '\0')
+			i_error("mail_location: %s", error);
+		else {
 			i_error("mail_location not set and "
-				"autodetection failed with home=%s", home);
+				"autodetection failed: %s", error);
 		}
 		return -1;
 	}
--- a/src/lib-storage/mail-storage-private.h	Sun Jul 15 15:27:58 2007 +0300
+++ b/src/lib-storage/mail-storage-private.h	Sun Jul 15 15:30:00 2007 +0300
@@ -24,7 +24,8 @@
 	void (*class_deinit)(void);
 
 	struct mail_storage *(*alloc)(void);
-	int (*create)(struct mail_storage *storage, const char *data);
+	int (*create)(struct mail_storage *storage, const char *data,
+		      const char **error_r);
 	void (*destroy)(struct mail_storage *storage);
 
 	bool (*autodetect)(const char *data, enum mail_storage_flags flags);
--- a/src/lib-storage/mail-storage.c	Sun Jul 15 15:27:58 2007 +0300
+++ b/src/lib-storage/mail-storage.c	Sun Jul 15 15:30:00 2007 +0300
@@ -164,10 +164,12 @@
 int mail_storage_create(struct mail_namespace *ns, const char *driver,
 			const char *data, const char *user,
 			enum mail_storage_flags flags,
-			enum file_lock_method lock_method)
+			enum file_lock_method lock_method,
+			const char **error_r)
 {
 	struct mail_storage *storage_class, *storage;
 	struct mail_storage *const *classes;
+	const char *home;
 	unsigned int i, count;
 
 	if (data == NULL)
@@ -181,7 +183,8 @@
 	} else if (driver == NULL) {
 		storage_class = mail_storage_autodetect(data, flags);
 		if (storage_class == NULL) {
-			i_error("Ambiguous mail location setting, "
+			*error_r = t_strdup_printf(
+				"Ambiguous mail location setting, "
 				"don't know what to do with it: %s "
 				"(try prefixing it with mbox: or maildir:)",
 				data);
@@ -191,8 +194,11 @@
 		count = 1;
 	} else {
 		storage_class = mail_storage_find(driver);
-		if (storage_class == NULL)
+		if (storage_class == NULL) {
+			*error_r = t_strdup_printf(
+				"Unknown mail storage driver %s", driver);
 			return -1;
+		}
 		classes = &storage_class;
 		count = 1;
 	}
@@ -208,14 +214,31 @@
 			p_new(storage->pool, struct mail_storage_callbacks, 1);
 		p_array_init(&storage->module_contexts, storage->pool, 5);
 
-		if (classes[i]->v.create(storage, data) == 0)
+		if (classes[i]->v.create(storage, data, error_r) == 0)
 			break;
 
+		if ((flags & MAIL_STORAGE_FLAG_DEBUG) != 0 && count > 1) {
+			i_info("%s: Couldn't create mail storage %s: %s",
+			       classes[i]->name, data, *error_r);
+		}
+
 		/* try the next one */
 		pool_unref(storage->pool);
 	}
-	if (i == count)
+	if (i == count) {
+		if (count <= 1) {
+			*error_r = t_strdup_printf("%s: %s", classes[0]->name,
+						   *error_r);
+			return -1;
+		}
+
+		home = getenv("HOME");
+		if (home == NULL || *home == '\0') home = "(not set)";
+
+		*error_r = t_strdup_printf(
+			"Mail storage autodetection failed with home=%s", home);
 		return -1;
+	}
 
 	if (hook_mail_storage_created != NULL)
 		hook_mail_storage_created(storage);
--- a/src/lib-storage/mail-storage.h	Sun Jul 15 15:27:58 2007 +0300
+++ b/src/lib-storage/mail-storage.h	Sun Jul 15 15:30:00 2007 +0300
@@ -214,7 +214,8 @@
 int mail_storage_create(struct mail_namespace *ns, const char *driver,
 			const char *data, const char *user,
 			enum mail_storage_flags flags,
-			enum file_lock_method lock_method);
+			enum file_lock_method lock_method,
+			const char **error_r);
 void mail_storage_destroy(struct mail_storage **storage);
 
 char mail_storage_get_hierarchy_sep(struct mail_storage *storage);
--- a/src/lib-storage/mailbox-list.c	Sun Jul 15 15:27:58 2007 +0300
+++ b/src/lib-storage/mailbox-list.c	Sun Jul 15 15:30:00 2007 +0300
@@ -86,7 +86,8 @@
 	unsigned int idx;
 
 	if (!mailbox_list_driver_find(driver, &idx)) {
-		*error_r = "Unknown mailbox list driver";
+		*error_r = t_strdup_printf("Unknown mailbox list driver: %s",
+					   driver);
 		return -1;
 	}
 
--- a/src/plugins/convert/convert-storage.c	Sun Jul 15 15:27:58 2007 +0300
+++ b/src/plugins/convert/convert-storage.c	Sun Jul 15 15:30:00 2007 +0300
@@ -265,7 +265,7 @@
 	struct dotlock *dotlock;
         enum mail_storage_flags src_flags, dest_flags;
         enum file_lock_method lock_method;
-	const char *path;
+	const char *path, *error;
 	int ret;
 
 	source_ns = mail_namespaces_init_empty(pool_datastack_create());
@@ -274,7 +274,7 @@
 
 	src_flags |= MAIL_STORAGE_FLAG_NO_AUTOCREATE;
 	if (mail_storage_create(source_ns, NULL, source_data, set->user,
-				src_flags, lock_method) < 0) {
+				src_flags, lock_method, &error) < 0) {
 		/* No need for conversion. */
 		return 0;
 	}
@@ -283,9 +283,9 @@
 	   will most likely create it. So do this before locking. */
 	dest_ns = mail_namespaces_init_empty(pool_datastack_create());
 	if (mail_storage_create(dest_ns, NULL, dest_data, set->user,
-				dest_flags, lock_method) < 0) {
+				dest_flags, lock_method, &error) < 0) {
 		i_error("Mailbox conversion: Failed to create destination "
-			"storage with data: %s", dest_data);
+			"mail storage with data '%s': %s", dest_data, error);
 		mail_namespaces_deinit(&dest_ns);
 		mail_namespaces_deinit(&source_ns);
 		return -1;
@@ -306,7 +306,7 @@
 	   reopen the source storage */
 	mail_storage_destroy(&source_ns->storage);
 	if (mail_storage_create(source_ns, NULL, source_data, set->user,
-				src_flags, lock_method) < 0) {
+				src_flags, lock_method, &error) < 0) {
 		/* No need for conversion anymore. */
 		file_dotlock_delete(&dotlock);
 		return 0;