changeset 20673:246105771e0e

fs-api: Add and use fs_write_stream_abort_error This lets caller to specify error instead of setting it with fs_error. Doing it like this lets us percolate the error upwards.
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Fri, 19 Aug 2016 16:00:30 +0300
parents f3a80b431fb1
children 5f7da2341648
files src/lib-fs/fs-api.c src/lib-fs/fs-api.h src/lib-fs/fs-metawrap.c src/lib-fs/fs-randomfail.c src/lib-fs/fs-sis-queue.c src/lib-fs/fs-sis.c src/lib-fs/fs-wrapper.c src/lib-storage/index/index-attachment.c src/plugins/fs-compress/fs-compress.c
diffstat 9 files changed, 64 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-fs/fs-api.c	Fri Aug 19 14:47:33 2016 +0300
+++ b/src/lib-fs/fs-api.c	Fri Aug 19 16:00:30 2016 +0300
@@ -272,7 +272,7 @@
 
 	if (file->copy_input != NULL) {
 		i_stream_unref(&file->copy_input);
-		(void)fs_write_stream_abort(file, &file->copy_output);
+		fs_write_stream_abort(file, &file->copy_output);
 	}
 	i_free_and_null(file->write_digest);
 	if (file->fs->v.file_close != NULL) T_BEGIN {
@@ -596,10 +596,9 @@
 		output = fs_write_stream(file);
 		if ((ret = o_stream_send(output, data, size)) < 0) {
 			err = errno;
-			fs_set_error(file->fs, "fs_write(%s) failed: %s",
-				     o_stream_get_name(output),
-				     o_stream_get_error(output));
-			fs_write_stream_abort(file, &output);
+			fs_write_stream_abort_error(file, &output, "fs_write(%s) failed: %s",
+						    o_stream_get_name(output),
+						    o_stream_get_error(output));
 			errno = err;
 			return -1;
 		}
@@ -705,9 +704,11 @@
 	return fs_write_stream_finish_int(file, TRUE);
 }
 
-void fs_write_stream_abort(struct fs_file *file, struct ostream **output)
+void fs_write_stream_abort_error(struct fs_file *file, struct ostream **output, const char *error_fmt, ...)
 {
 	int ret;
+	va_list args;
+	va_start(args, error_fmt);
 
 	i_assert(*output == file->output);
 	i_assert(file->output != NULL);
@@ -716,9 +717,16 @@
 	*output = NULL;
 	o_stream_ignore_last_errors(file->output);
 	/* make sure we don't have an old error lying around */
-	fs_set_error(file->fs, "Write aborted");
+	fs_set_verror(file->fs, error_fmt, args);
 	ret = fs_write_stream_finish_int(file, FALSE);
 	i_assert(ret != 0);
+
+	va_end(args);
+}
+
+void fs_write_stream_abort(struct fs_file *file, struct ostream **output)
+{
+	fs_write_stream_abort_error(file, output, "Write aborted");
 }
 
 void fs_write_set_hash(struct fs_file *file, const struct hash_method *method,
@@ -889,20 +897,20 @@
 	while (o_stream_send_istream(dest->copy_output, dest->copy_input) > 0) ;
 	if (dest->copy_input->stream_errno != 0) {
 		errno = dest->copy_input->stream_errno;
-		fs_set_error(dest->fs, "read(%s) failed: %s",
-			     i_stream_get_name(dest->copy_input),
-			     i_stream_get_error(dest->copy_input));
+		fs_write_stream_abort_error(dest, &dest->copy_output,
+					    "read(%s) failed: %s",
+					    i_stream_get_name(dest->copy_input),
+					    i_stream_get_error(dest->copy_input));
 		i_stream_unref(&dest->copy_input);
-		fs_write_stream_abort(dest, &dest->copy_output);
 		return -1;
 	}
 	if (dest->copy_output->stream_errno != 0) {
 		errno = dest->copy_output->stream_errno;
-		fs_set_error(dest->fs, "write(%s) failed: %s",
-			     o_stream_get_name(dest->copy_output),
-			     o_stream_get_error(dest->copy_output));
+		fs_write_stream_abort_error(dest, &dest->copy_output,
+					    "write(%s) failed: %s",
+					    o_stream_get_name(dest->copy_output),
+					    o_stream_get_error(dest->copy_output));
 		i_stream_unref(&dest->copy_input);
-		fs_write_stream_abort(dest, &dest->copy_output);
 		return -1;
 	}
 	if (!dest->copy_input->eof) {
--- a/src/lib-fs/fs-api.h	Fri Aug 19 14:47:33 2016 +0300
+++ b/src/lib-fs/fs-api.h	Fri Aug 19 16:00:30 2016 +0300
@@ -275,6 +275,7 @@
    fs_write_stream_finish(), i.e. it can't be used to abort a pending async
    write. */
 void fs_write_stream_abort(struct fs_file *file, struct ostream **output);
+void fs_write_stream_abort_error(struct fs_file *file, struct ostream **output, const char *error_fmt, ...) ATTR_FORMAT(3, 4);
 
 /* Set a hash to the following write. The storage can then verify that the
    input data matches the specified hash, or fail if it doesn't. Typically
--- a/src/lib-fs/fs-metawrap.c	Fri Aug 19 14:47:33 2016 +0300
+++ b/src/lib-fs/fs-metawrap.c	Fri Aug 19 16:00:30 2016 +0300
@@ -365,7 +365,9 @@
 		if (file->super_output != NULL) {
 			/* no metawrap */
 			i_assert(file->temp_output == NULL);
-			fs_write_stream_abort(_file->parent, &file->super_output);
+			fs_write_stream_abort_error(_file->parent, &file->super_output, "error(%s): %s",
+						    o_stream_get_name(file->super_output),
+						    o_stream_get_error(file->super_output));
 		} else {
 			i_assert(file->temp_output != NULL);
 			o_stream_destroy(&file->temp_output);
@@ -397,16 +399,16 @@
 	file->super_output = fs_write_stream(_file->parent);
 	(void)o_stream_send_istream(file->super_output, input);
 	if (input->stream_errno != 0) {
-		fs_set_error(_file->fs, "read(%s) failed: %s",
-			     i_stream_get_name(input),
-			     i_stream_get_error(input));
-		fs_write_stream_abort(_file->parent, &file->super_output);
+		fs_write_stream_abort_error(_file->parent, &file->super_output,
+					    "read(%s) failed: %s",
+					    i_stream_get_name(input),
+					    i_stream_get_error(input));
 		ret = -1;
 	} else if (file->super_output->stream_errno != 0) {
-		fs_set_error(_file->fs, "write(%s) failed: %s",
-			     o_stream_get_name(file->super_output),
-			     o_stream_get_error(file->super_output));
-		fs_write_stream_abort(_file->parent, &file->super_output);
+		fs_write_stream_abort_error(_file->parent, &file->super_output,
+					    "write(%s) failed: %s",
+					    o_stream_get_name(file->super_output),
+					    o_stream_get_error(file->super_output));
 		ret = -1;
 	} else {
 		i_assert(i_stream_is_eof(input));
--- a/src/lib-fs/fs-randomfail.c	Fri Aug 19 14:47:33 2016 +0300
+++ b/src/lib-fs/fs-randomfail.c	Fri Aug 19 16:00:30 2016 +0300
@@ -404,7 +404,7 @@
 		else
 			o_stream_unref(&_file->output);
 		if (!success || fs_random_fail(_file->fs, 1, FS_OP_WRITE)) {
-			fs_write_stream_abort(file->super, &file->super_output);
+			fs_write_stream_abort_error(file->super, &file->super_output, RANDOMFAIL_ERROR);
 			return -1;
 		}
 	}
--- a/src/lib-fs/fs-sis-queue.c	Fri Aug 19 14:47:33 2016 +0300
+++ b/src/lib-fs/fs-sis-queue.c	Fri Aug 19 16:00:30 2016 +0300
@@ -149,7 +149,10 @@
 
 	if (!success) {
 		if (_file->parent != NULL)
-			fs_write_stream_abort(_file->parent, &_file->output);
+			fs_write_stream_abort_error(_file->parent, &_file->output,
+						    "write(%s) failed: %s",
+						    o_stream_get_name(_file->output),
+						    o_stream_get_error(_file->output));
 		return -1;
 	}
 
--- a/src/lib-fs/fs-sis.c	Fri Aug 19 14:47:33 2016 +0300
+++ b/src/lib-fs/fs-sis.c	Fri Aug 19 16:00:30 2016 +0300
@@ -287,7 +287,10 @@
 
 	if (!success) {
 		if (_file->parent != NULL)
-			fs_write_stream_abort(_file->parent, &file->fs_output);
+			fs_write_stream_abort_error(_file->parent, &file->fs_output,
+						    "write(%s) error: %s",
+						    o_stream_get_name(file->fs_output),
+						    o_stream_get_error(file->fs_output));
 		o_stream_unref(&_file->output);
 		return -1;
 	}
--- a/src/lib-fs/fs-wrapper.c	Fri Aug 19 14:47:33 2016 +0300
+++ b/src/lib-fs/fs-wrapper.c	Fri Aug 19 16:00:30 2016 +0300
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "fs-api-private.h"
+#include "ostream.h"
 
 struct wrapper_fs_iter {
 	struct fs_iter iter;
@@ -78,7 +79,10 @@
 int fs_wrapper_write_stream_finish(struct fs_file *file, bool success)
 {
 	if (!success) {
-		fs_write_stream_abort(file->parent, &file->output);
+		fs_write_stream_abort_error(file->parent, &file->output,
+					    "write(%s) failed: %s",
+					    o_stream_get_name(file->output),
+					    o_stream_get_error(file->output));
 		return -1;
 	}
 
--- a/src/lib-storage/index/index-attachment.c	Fri Aug 19 14:47:33 2016 +0300
+++ b/src/lib-storage/index/index-attachment.c	Fri Aug 19 16:00:30 2016 +0300
@@ -138,7 +138,9 @@
 	i_assert(attach->cur_file != NULL);
 
 	if (ret < 0)
-		fs_write_stream_abort(attach->cur_file, &output);
+		fs_write_stream_abort_error(attach->cur_file, &output, "write(%s) failed: %s",
+					    o_stream_get_name(output),
+					    o_stream_get_error(output));
 	else if (fs_write_stream_finish(attach->cur_file, &output) < 0) {
 		*error_r = t_strdup_printf("Couldn't create attachment %s: %s",
 					   fs_file_path(attach->cur_file),
--- a/src/plugins/fs-compress/fs-compress.c	Fri Aug 19 14:47:33 2016 +0300
+++ b/src/plugins/fs-compress/fs-compress.c	Fri Aug 19 16:00:30 2016 +0300
@@ -201,7 +201,10 @@
 		if (file->temp_output != NULL)
 			o_stream_destroy(&file->temp_output);
 		if (file->super_output != NULL)
-			fs_write_stream_abort(_file->parent, &file->super_output);
+			fs_write_stream_abort_error(_file->parent, &file->super_output,
+						    "write(%s) failed: %s",
+						    o_stream_get_name(file->super_output),
+						    o_stream_get_error(file->super_output));
 		return -1;
 	}
 
@@ -220,17 +223,17 @@
 	if (o_stream_send_istream(file->super_output, input) >= 0)
 		ret = fs_write_stream_finish(_file->parent, &file->super_output);
 	else if (input->stream_errno != 0) {
-		fs_set_error(_file->fs, "read(%s) failed: %s",
-			     i_stream_get_name(input),
-			     i_stream_get_error(input));
-		fs_write_stream_abort(_file->parent, &file->super_output);
+		fs_write_stream_abort_error(_file->parent, &file->super_output,
+					    "read(%s) failed: %s",
+					    i_stream_get_name(input),
+					    i_stream_get_error(input));
 		ret = -1;
 	} else {
 		i_assert(file->super_output->stream_errno != 0);
-		fs_set_error(_file->fs, "write(%s) failed: %s",
-			     o_stream_get_name(file->super_output),
-			     o_stream_get_error(file->super_output));
-		fs_write_stream_abort(_file->parent, &file->super_output);
+		fs_write_stream_abort_error(_file->parent, &file->super_output,
+					    "write(%s) failed: %s",
+					    o_stream_get_name(file->super_output),
+					    o_stream_get_error(file->super_output));
 		ret = -1;
 	}
 	i_stream_unref(&input);