]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-fs: If fs_read_stream() creates a seekable stream, keep it open for future reads.
authorTimo Sirainen <tss@iki.fi>
Tue, 26 Feb 2013 15:44:34 +0000 (17:44 +0200)
committerTimo Sirainen <tss@iki.fi>
Tue, 26 Feb 2013 15:44:34 +0000 (17:44 +0200)
src/lib-fs/fs-api-private.h
src/lib-fs/fs-api.c

index 0174839a4dded8a14a128d9178aabea812677ab7..f07b2e478332b36f666eebc663be0daebf09c72b 100644 (file)
@@ -69,6 +69,7 @@ struct fs_file {
        char *path;
        enum fs_open_flags flags;
 
+       struct istream *seekable_input;
        struct istream *pending_read_input;
        bool write_pending;
 
index 8f67f1f864afdd563217c308e9a2862c0036c8f9..109b908b25815d71806ec0e8a99dad2302f69c08 100644 (file)
@@ -166,6 +166,8 @@ void fs_file_deinit(struct fs_file **_file)
 
        if (file->pending_read_input != NULL)
                i_stream_unref(&file->pending_read_input);
+       if (file->seekable_input != NULL)
+               i_stream_unref(&file->seekable_input);
 
        if (file->copy_input != NULL) {
                i_stream_unref(&file->copy_input);
@@ -287,6 +289,11 @@ struct istream *fs_read_stream(struct fs_file *file, size_t max_buffer_size)
        ssize_t ret;
        bool want_seekable = FALSE;
 
+       if (file->seekable_input != NULL) {
+               i_stream_seek(file->seekable_input, 0);
+               i_stream_ref(file->seekable_input);
+               return file->seekable_input;
+       }
        input = file->fs->v.read_stream(file, max_buffer_size);
        if (input->stream_errno != 0) {
                /* read failed already */
@@ -306,6 +313,9 @@ struct istream *fs_read_stream(struct fs_file *file, size_t max_buffer_size)
                                                file->fs->temp_path_prefix);
                i_stream_set_name(input, i_stream_get_name(inputs[0]));
                i_stream_unref(&inputs[0]);
+
+               file->seekable_input = input;
+               i_stream_ref(file->seekable_input);
        }
        if ((file->flags & FS_OPEN_FLAG_ASYNC) == 0 && !input->blocking) {
                /* read the whole input stream before returning */