Hello Rafael, This is *UNTESTED* suggestion for switching into lzo without the memcpy. Please see if I missed something as I the code combination of global variables, local memory pool and unrelated sizes is difficult to understand/maintain.
Basically, I've modify the init_swap_writer() so that it is the only function knowing the size of the swap_map_handle needs. When you call it with NULL you get the number of bytes it needs. I also don't fully understand why the encryption and compression/write blocks are related in size.... And why you remove the encryption block from mem_size. Alon. --- diff -urNp suspend.org/Makefile suspend.compress/Makefile --- suspend.org/Makefile 2007-07-29 21:30:27.000000000 +0300 +++ suspend.compress/Makefile 2007-08-04 02:29:36.000000000 +0300 @@ -41,7 +41,7 @@ endif ifdef CONFIG_COMPRESS CC_FLAGS += -DCONFIG_COMPRESS -SWSUSP_LD_FLAGS += -llzf +SWSUSP_LD_FLAGS += -llzo2 endif ifdef CONFIG_ENCRYPT diff -urNp suspend.org/resume.c suspend.compress/resume.c --- suspend.org/resume.c 2007-05-13 20:53:13.000000000 +0300 +++ suspend.compress/resume.c 2007-08-04 02:26:11.000000000 +0300 @@ -26,9 +26,7 @@ #include <string.h> #include <errno.h> #ifdef CONFIG_COMPRESS -#include <lzf.h> -#else -#define lzf_decompress(a, b, c, d) 0 +#include <lzo/lzo1x.h> #endif #include "swsusp.h" @@ -276,21 +274,28 @@ static int restore(struct swap_map_handl void *buf = handle->page_buffer; block = (struct buf_block *)(handle->read_buffer + disp); +#ifdef CONFIG_COMPRESS if (decompress) { unsigned short cnt = block->size; if (cnt == page_size) { memcpy(buf, block->data, page_size); } else if (cnt < page_size) { - cnt = lzf_decompress(block->data, cnt, buf, page_size); - if (cnt != page_size) + lzo_uint result_len = page_size; + + if ( + lzo1x_decompress_safe((lzo_bytep)block->data, cnt, buf, &result_len, NULL) != LZO_E_OK || + result_len != page_size + ) { return -ENODATA; + } } else { return -EINVAL; } block->size += sizeof(short); return block->size; } +#endif memcpy(buf, block, page_size); return page_size; } @@ -589,6 +594,10 @@ static int read_image(int dev, int fd, s printf("resume: Compressed image\n"); #ifdef CONFIG_COMPRESS decompress = 1; + if (lzo_init() != LZO_E_OK) { + fprintf(stderr, "suspend: Could not initialize compress\n"); + error = -ENOPKG; + } #else fprintf(stderr,"resume: Compression not supported\n"); error = -EINVAL; diff -urNp suspend.org/suspend.c suspend.compress/suspend.c --- suspend.org/suspend.c 2007-07-29 21:30:27.000000000 +0300 +++ suspend.compress/suspend.c 2007-08-04 02:29:13.000000000 +0300 @@ -33,9 +33,7 @@ #include <signal.h> #include <termios.h> #ifdef CONFIG_COMPRESS -#include <lzf.h> -#else -#define lzf_compress(a, b, c, d) 0 +#include <lzo/lzo1x.h> #endif #include "swsusp.h" @@ -61,6 +59,7 @@ static int suspend_loglevel = SUSPEND_LO static char compute_checksum; #ifdef CONFIG_COMPRESS static char compress; +static lzo_byte compress_work_buffer[LZO1X_1_MEM_COMPRESS]; #else #define compress 0 #endif @@ -268,21 +267,36 @@ struct swap_map_handle { #endif }; +/* + * If handle and buf are NULL, returns required memory size + */ static int init_swap_writer(struct swap_map_handle *handle, int dev, int fd, void *buf) { - if (!buf) + char *p = (char *)buf; + if (handle != NULL && buf == NULL) return -EINVAL; - handle->areas = buf; - handle->areas_per_page = (page_size - sizeof(loff_t)) / - sizeof(struct swap_area); - handle->next_swap = (loff_t *)(handle->areas + handle->areas_per_page); - handle->page_buffer = (char *)buf + page_size; - handle->write_buffer = handle->page_buffer + page_size; + if (handle != NULL) { + handle->areas = (struct swap_area *)p; + handle->areas_per_page = (page_size - sizeof(loff_t)) / + sizeof(struct swap_area); + handle->next_swap = (loff_t *)p; + } + p += page_size; + if (handle != NULL) + handle->page_buffer = p; + p += page_size; + if (handle != NULL) + handle->write_buffer = p; + p += buffer_size; #ifdef CONFIG_ENCRYPT - handle->encrypt_buffer = (unsigned char *)(handle->write_buffer + - buffer_size); + if (handle != NULL) + handle->encrypt_buffer = (unsigned char *)p; + p += buffer_size; #endif + if (handle == NULL) + return p-(char *)buf; + memset(handle->areas, 0, page_size); handle->cur_swap = get_swap_page(dev); if (!handle->cur_swap) @@ -306,12 +320,15 @@ static int prepare(struct swap_map_handl void *buf = handle->page_buffer; block = (struct buf_block *)(handle->write_buffer + disp); +#ifdef CONFIG_COMPRESS if (compress) { - unsigned short cnt; + lzo_uint cnt = 0; - cnt = lzf_compress(buf, page_size, - block->data, page_size - sizeof(short)); - if (!cnt) { + /* NOTICE: Assuming block->data large enough as lzo does not check for limits */ + if ( + lzo1x_1_compress(buf, page_size, (lzo_bytep)block->data, &cnt, compress_work_buffer) != LZO_E_OK || + cnt >= page_size - sizeof(short) + ) { memcpy(block->data, buf, page_size); cnt = page_size; } else { @@ -322,6 +339,7 @@ static int prepare(struct swap_map_handl cnt += sizeof(short); return cnt; } +#endif memcpy(block, buf, page_size); return page_size; } @@ -1348,8 +1366,21 @@ int main(int argc, char *argv[]) page_size = getpagesize(); buffer_size = BUFFER_PAGES * page_size; + #define COMPRESS_BUFFER_SIZE(b) ((b) + (b)/16 + 64 + 3) + if (buffer_size < COMPRESS_BUFFER_SIZE(page_size)) { + buffer_size = COMPRESS_BUFFER_SIZE(page_size); + } - mem_size = 3 * page_size + buffer_size; + /* The extra page is work area */ + mem_size = page_size + init_swap_writer (NULL, 0, 0, NULL); +#ifdef CONFIG_COMPRESS + if (compress) { + if (lzo_init() != LZO_E_OK) { + fprintf(stderr, "suspend: Could not initialize compress\n"); + return ENOPKG; + } + } +#endif #ifdef CONFIG_ENCRYPT if (encrypt) mem_size += buffer_size; ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ Suspend-devel mailing list Suspend-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/suspend-devel