]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
fs-api: Add and use fs_write_stream_abort_error
authorAki Tuomi <aki.tuomi@dovecot.fi>
Fri, 19 Aug 2016 13:00:30 +0000 (16:00 +0300)
committerGitLab <gitlab@git.dovecot.net>
Tue, 23 Aug 2016 10:27:37 +0000 (13:27 +0300)
This lets caller to specify error instead of setting it
with fs_error. Doing it like this lets us percolate the
error upwards.

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

index e53059348ce22b9228ee604586e25f33f1475ea6..15dc85d233dd7edad4f7f23811622d3227912ead 100644 (file)
@@ -276,7 +276,7 @@ void fs_file_close(struct fs_file *file)
 
        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 {
@@ -610,10 +610,9 @@ int fs_write_via_stream(struct fs_file *file, const void *data, size_t size)
                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;
                }
@@ -719,9 +718,11 @@ int fs_write_stream_finish_async(struct fs_file *file)
        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);
@@ -730,9 +731,16 @@ void fs_write_stream_abort(struct fs_file *file, struct ostream **output)
        *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,
@@ -904,19 +912,19 @@ int fs_default_copy(struct fs_file *src, struct fs_file *dest)
                return -1;
        case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT:
                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;
        case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT:
                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;
        }
        i_stream_unref(&dest->copy_input);
index cf285b1716b4cc21741ec797d65f6472ce2acab8..1ef7b478a47400482cbbf92ded992e90fcd9c5ce 100644 (file)
@@ -275,6 +275,7 @@ int fs_write_stream_finish_async(struct fs_file *file);
    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
index 4b5627737e4cb57916ce81cd314f8e6b9e3ed0f9..663adad8831836265225a853d529e900c779f4a2 100644 (file)
@@ -364,7 +364,9 @@ static int fs_metawrap_write_stream_finish(struct fs_file *_file, bool success)
                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);
index 484a12328b1b2f135617271461dc5270bd3c8f7e..a1593290e64a105c99a8859c48d4e49586bd5b2d 100644 (file)
@@ -402,7 +402,7 @@ static int fs_randomfail_write_stream_finish(struct fs_file *_file, bool success
                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;
                }
        }
index 1e38d643db1868c9ade07445d9ffcbb0aaab80a1..3936933355e3db5b54cc29cb6aab48776d72d35e 100644 (file)
@@ -149,7 +149,10 @@ static int fs_sis_queue_write_stream_finish(struct fs_file *_file, bool success)
 
        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;
        }
 
index eb947c101f337964adef28af659a9743fd0f6d49..d36daf501262b0b09f223abfdfe51b545629d667 100644 (file)
@@ -287,7 +287,10 @@ static int fs_sis_write_stream_finish(struct fs_file *_file, bool success)
 
        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;
        }
index 524f1131314c5f1612ba93ebda1578e9a50d5730..85c194b99e39713260fdbf2f1f88844e37ad8f40 100644 (file)
@@ -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 @@ void fs_wrapper_write_stream(struct fs_file *file)
 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;
        }
 
index 3bfb3d387e580119b224958f710b492ff5dfe787..4d0a5daae43d869f1ea1c926947227a588e2bef0 100644 (file)
@@ -138,7 +138,9 @@ index_attachment_close_ostream(struct ostream *output, bool success,
        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),
index e1e3ceafa3739e63dc462f735ef67a583d4b7dc0..f582c3bd5484a71f1a524d699e0c0c5f73147a1b 100644 (file)
@@ -201,7 +201,10 @@ static int fs_compress_write_stream_finish(struct fs_file *_file, bool success)
                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;
        }