iolog: fix bug when decompressing chunks with different sequence numbers
authorJens Axboe <axboe@fb.com>
Fri, 4 Jul 2014 03:57:29 +0000 (21:57 -0600)
committerJens Axboe <axboe@fb.com>
Fri, 4 Jul 2014 03:57:29 +0000 (21:57 -0600)
We need to re-start on inflate, like we do on deflate. Otherwise
we get stream end when the first chunk is done. Keep track of
this in iolog_file_inflate(), since we know how much we need to
decompress.

Signed-off-by: Jens Axboe <axboe@fb.com>
iolog.c

diff --git a/iolog.c b/iolog.c
index c725a4fd4d3f06f9c476cdc29a3ee21378c781c6..29997cee18925b4cbda30996cbae511eea5d9d43 100644 (file)
--- a/iolog.c
+++ b/iolog.c
@@ -723,8 +723,8 @@ static void finish_chunk(z_stream *stream, FILE *f,
        iter->buf_size = iter->buf_used = 0;
 }
 
-static int flush_chunk(struct iolog_compress *ic, int gz_hdr, FILE *f,
-                      z_stream *stream, struct flush_chunk_iter *iter)
+static size_t flush_chunk(struct iolog_compress *ic, int gz_hdr, FILE *f,
+                         z_stream *stream, struct flush_chunk_iter *iter)
 {
        if (ic->seq != iter->seq) {
                if (iter->seq)
@@ -767,7 +767,7 @@ static int flush_chunk(struct iolog_compress *ic, int gz_hdr, FILE *f,
                        break;
        }
 
-       return 0;
+       return (void *) stream->next_in - ic->buf;
 }
 
 static void flush_gz_chunks(struct io_log *log, FILE *f)
@@ -802,6 +802,8 @@ int iolog_file_inflate(const char *file)
        z_stream stream;
        struct stat sb;
        ssize_t ret;
+       size_t total;
+       void *buf;
        FILE *f;
 
        f = fopen(file, "r");
@@ -816,7 +818,7 @@ int iolog_file_inflate(const char *file)
                return 1;
        }
 
-       ic.buf = malloc(sb.st_size);
+       ic.buf = buf = malloc(sb.st_size);
        ic.len = sb.st_size;
        ic.seq = 1;
 
@@ -833,14 +835,26 @@ int iolog_file_inflate(const char *file)
 
        fclose(f);
 
-       flush_chunk(&ic,  1, stdout, &stream, &iter);
+       total = ic.len;
+       do {
+               size_t ret;
+
+               ret = flush_chunk(&ic,  1, stdout, &stream, &iter);
+               total -= ret;
+               if (!total)
+                       break;
+
+               ic.seq++;
+               ic.len -= ret;
+               ic.buf += ret;
+       } while (1);
 
        if (iter.seq) {
                finish_chunk(&stream, stdout, &iter);
                free(iter.buf);
        }
 
-       free(ic.buf);
+       free(buf);
        return 0;
 }