According to /usr/include/zlib.h, for the call to compress2:

 Upon entry, destLen is the total size of the
   destination buffer, which must be at least the value returned by
   compressBound(sourceLen). 

On my system where page_size is 16384, compressBound(16384) returns
16400.  This allows compress2 to "compress" an uncompressible block of
data into a header plus the original data (for a result that is larger
than the original).

Since compress2 is currently called with size_out = 16384,
uncompressible pages return Z_BUF_ERROR because there is not enough room
in the output buffer.  Since compress2 returns an error, makedumpfile
uses the original page instead and marks it as not compressed.  

With a fix as shown below, compress2 returns a "compressed" page that is
larger than the original with Z_OK, and makedumpfile uses the original
page instead and marks it as not compressed :-)

In other words, there is no change in the dumpfile that is created,
since uncompressible pages are rejected because the result is too large
instead of because the compress2 call failed with Z_BUF_ERROR.

But the world seems cleaner this way, doesn't it?  I didn't see any
appreciable speed difference.

Bob Montgomery


--- makedumpfile.c.orig 2006-12-07 21:38:51.000000000 -0700
+++ makedumpfile.c      2006-12-08 14:25:26.000000000 -0700
@@ -3160,6 +3160,7 @@ write_kdump_pages(struct DumpInfo *info)
        off_t offset_data = 0, offset_memory = 0;
        struct disk_dump_header *dh = info->dump_header;
        unsigned char *buf = NULL, *buf_out = NULL;
+       unsigned long len_buf_out;
        struct cache_data bm2, pdesc, pdata;
        struct dump_bitmap bitmap1, bitmap2;
        const off_t failed = (off_t)-1;
@@ -3205,7 +3206,8 @@ write_kdump_pages(struct DumpInfo *info)
                    strerror(errno));
                goto out;
        }
-       if ((buf_out = malloc(info->page_size)) == NULL) {
+       len_buf_out = compressBound(info->page_size);
+       if ((buf_out = malloc(len_buf_out)) == NULL) {
                ERRMSG("Can't allocate memory for the compression buffer. %s\n",
                    strerror(errno));
                goto out;
@@ -3323,7 +3325,7 @@ write_kdump_pages(struct DumpInfo *info)
                /*
                 * Compress the page data.
                 */
-               size_out = info->page_size;
+               size_out = len_buf_out;
                if (info->flag_compress
                    && (compress2(buf_out, &size_out, buf,
                    info->page_size, Z_BEST_SPEED) == Z_OK)




_______________________________________________
fastboot mailing list
[email protected]
https://lists.osdl.org/mailman/listinfo/fastboot

Reply via email to