linux/fs/logfs/compr.c
<<
>>
Prefs
   1/*
   2 * fs/logfs/compr.c     - compression routines
   3 *
   4 * As should be obvious for Linux kernel code, license is GPLv2
   5 *
   6 * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org>
   7 */
   8#include "logfs.h"
   9#include <linux/vmalloc.h>
  10#include <linux/zlib.h>
  11
  12#define COMPR_LEVEL 3
  13
  14static DEFINE_MUTEX(compr_mutex);
  15static struct z_stream_s stream;
  16
  17int logfs_compress(void *in, void *out, size_t inlen, size_t outlen)
  18{
  19        int err, ret;
  20
  21        ret = -EIO;
  22        mutex_lock(&compr_mutex);
  23        err = zlib_deflateInit(&stream, COMPR_LEVEL);
  24        if (err != Z_OK)
  25                goto error;
  26
  27        stream.next_in = in;
  28        stream.avail_in = inlen;
  29        stream.total_in = 0;
  30        stream.next_out = out;
  31        stream.avail_out = outlen;
  32        stream.total_out = 0;
  33
  34        err = zlib_deflate(&stream, Z_FINISH);
  35        if (err != Z_STREAM_END)
  36                goto error;
  37
  38        err = zlib_deflateEnd(&stream);
  39        if (err != Z_OK)
  40                goto error;
  41
  42        if (stream.total_out >= stream.total_in)
  43                goto error;
  44
  45        ret = stream.total_out;
  46error:
  47        mutex_unlock(&compr_mutex);
  48        return ret;
  49}
  50
  51int logfs_uncompress(void *in, void *out, size_t inlen, size_t outlen)
  52{
  53        int err, ret;
  54
  55        ret = -EIO;
  56        mutex_lock(&compr_mutex);
  57        err = zlib_inflateInit(&stream);
  58        if (err != Z_OK)
  59                goto error;
  60
  61        stream.next_in = in;
  62        stream.avail_in = inlen;
  63        stream.total_in = 0;
  64        stream.next_out = out;
  65        stream.avail_out = outlen;
  66        stream.total_out = 0;
  67
  68        err = zlib_inflate(&stream, Z_FINISH);
  69        if (err != Z_STREAM_END)
  70                goto error;
  71
  72        err = zlib_inflateEnd(&stream);
  73        if (err != Z_OK)
  74                goto error;
  75
  76        ret = 0;
  77error:
  78        mutex_unlock(&compr_mutex);
  79        return ret;
  80}
  81
  82int __init logfs_compr_init(void)
  83{
  84        size_t size = max(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
  85                        zlib_inflate_workspacesize());
  86        stream.workspace = vmalloc(size);
  87        if (!stream.workspace)
  88                return -ENOMEM;
  89        return 0;
  90}
  91
  92void logfs_compr_exit(void)
  93{
  94        vfree(stream.workspace);
  95}
  96