LCOV - code coverage report
Current view: top level - fs/jffs2 - compr_zlib.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 75 0.0 %
Date: 2014-02-18 Functions: 0 6 0.0 %
Branches: 0 36 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * JFFS2 -- Journalling Flash File System, Version 2.
       3                 :            :  *
       4                 :            :  * Copyright © 2001-2007 Red Hat, Inc.
       5                 :            :  * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
       6                 :            :  *
       7                 :            :  * Created by David Woodhouse <dwmw2@infradead.org>
       8                 :            :  *
       9                 :            :  * For licensing information, see the file 'LICENCE' in this directory.
      10                 :            :  *
      11                 :            :  */
      12                 :            : 
      13                 :            : #if !defined(__KERNEL__) && !defined(__ECOS)
      14                 :            : #error "The userspace support got too messy and was removed. Update your mkfs.jffs2"
      15                 :            : #endif
      16                 :            : 
      17                 :            : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      18                 :            : 
      19                 :            : #include <linux/kernel.h>
      20                 :            : #include <linux/zlib.h>
      21                 :            : #include <linux/zutil.h>
      22                 :            : #include "nodelist.h"
      23                 :            : #include "compr.h"
      24                 :            : 
      25                 :            :         /* Plan: call deflate() with avail_in == *sourcelen,
      26                 :            :                 avail_out = *dstlen - 12 and flush == Z_FINISH.
      27                 :            :                 If it doesn't manage to finish, call it again with
      28                 :            :                 avail_in == 0 and avail_out set to the remaining 12
      29                 :            :                 bytes for it to clean up.
      30                 :            :            Q: Is 12 bytes sufficient?
      31                 :            :         */
      32                 :            : #define STREAM_END_SPACE 12
      33                 :            : 
      34                 :            : static DEFINE_MUTEX(deflate_mutex);
      35                 :            : static DEFINE_MUTEX(inflate_mutex);
      36                 :            : static z_stream inf_strm, def_strm;
      37                 :            : 
      38                 :            : #ifdef __KERNEL__ /* Linux-only */
      39                 :            : #include <linux/vmalloc.h>
      40                 :            : #include <linux/init.h>
      41                 :            : #include <linux/mutex.h>
      42                 :            : 
      43                 :          0 : static int __init alloc_workspaces(void)
      44                 :            : {
      45                 :          0 :         def_strm.workspace = vmalloc(zlib_deflate_workspacesize(MAX_WBITS,
      46                 :            :                                                         MAX_MEM_LEVEL));
      47         [ #  # ]:          0 :         if (!def_strm.workspace)
      48                 :            :                 return -ENOMEM;
      49                 :            : 
      50                 :            :         jffs2_dbg(1, "Allocated %d bytes for deflate workspace\n",
      51                 :            :                   zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL));
      52                 :          0 :         inf_strm.workspace = vmalloc(zlib_inflate_workspacesize());
      53         [ #  # ]:          0 :         if (!inf_strm.workspace) {
      54                 :          0 :                 vfree(def_strm.workspace);
      55                 :          0 :                 return -ENOMEM;
      56                 :            :         }
      57                 :            :         jffs2_dbg(1, "Allocated %d bytes for inflate workspace\n",
      58                 :            :                   zlib_inflate_workspacesize());
      59                 :            :         return 0;
      60                 :            : }
      61                 :            : 
      62                 :          0 : static void free_workspaces(void)
      63                 :            : {
      64                 :          0 :         vfree(def_strm.workspace);
      65                 :          0 :         vfree(inf_strm.workspace);
      66                 :          0 : }
      67                 :            : #else
      68                 :            : #define alloc_workspaces() (0)
      69                 :            : #define free_workspaces() do { } while(0)
      70                 :            : #endif /* __KERNEL__ */
      71                 :            : 
      72                 :          0 : static int jffs2_zlib_compress(unsigned char *data_in,
      73                 :            :                                unsigned char *cpage_out,
      74                 :            :                                uint32_t *sourcelen, uint32_t *dstlen)
      75                 :            : {
      76                 :            :         int ret;
      77                 :            : 
      78         [ #  # ]:          0 :         if (*dstlen <= STREAM_END_SPACE)
      79                 :            :                 return -1;
      80                 :            : 
      81                 :          0 :         mutex_lock(&deflate_mutex);
      82                 :            : 
      83         [ #  # ]:          0 :         if (Z_OK != zlib_deflateInit(&def_strm, 3)) {
      84                 :          0 :                 pr_warn("deflateInit failed\n");
      85                 :          0 :                 mutex_unlock(&deflate_mutex);
      86                 :          0 :                 return -1;
      87                 :            :         }
      88                 :            : 
      89                 :          0 :         def_strm.next_in = data_in;
      90                 :          0 :         def_strm.total_in = 0;
      91                 :            : 
      92                 :          0 :         def_strm.next_out = cpage_out;
      93                 :          0 :         def_strm.total_out = 0;
      94                 :            : 
      95 [ #  # ][ #  # ]:          0 :         while (def_strm.total_out < *dstlen - STREAM_END_SPACE && def_strm.total_in < *sourcelen) {
      96                 :          0 :                 def_strm.avail_out = *dstlen - (def_strm.total_out + STREAM_END_SPACE);
      97                 :          0 :                 def_strm.avail_in = min((unsigned)(*sourcelen-def_strm.total_in), def_strm.avail_out);
      98                 :            :                 jffs2_dbg(1, "calling deflate with avail_in %d, avail_out %d\n",
      99                 :            :                           def_strm.avail_in, def_strm.avail_out);
     100                 :          0 :                 ret = zlib_deflate(&def_strm, Z_PARTIAL_FLUSH);
     101                 :            :                 jffs2_dbg(1, "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n",
     102                 :            :                           def_strm.avail_in, def_strm.avail_out,
     103                 :            :                           def_strm.total_in, def_strm.total_out);
     104         [ #  # ]:          0 :                 if (ret != Z_OK) {
     105                 :            :                         jffs2_dbg(1, "deflate in loop returned %d\n", ret);
     106                 :          0 :                         zlib_deflateEnd(&def_strm);
     107                 :          0 :                         mutex_unlock(&deflate_mutex);
     108                 :          0 :                         return -1;
     109                 :            :                 }
     110                 :            :         }
     111                 :          0 :         def_strm.avail_out += STREAM_END_SPACE;
     112                 :          0 :         def_strm.avail_in = 0;
     113                 :          0 :         ret = zlib_deflate(&def_strm, Z_FINISH);
     114                 :          0 :         zlib_deflateEnd(&def_strm);
     115                 :            : 
     116         [ #  # ]:          0 :         if (ret != Z_STREAM_END) {
     117                 :            :                 jffs2_dbg(1, "final deflate returned %d\n", ret);
     118                 :            :                 ret = -1;
     119                 :            :                 goto out;
     120                 :            :         }
     121                 :            : 
     122         [ #  # ]:          0 :         if (def_strm.total_out >= def_strm.total_in) {
     123                 :            :                 jffs2_dbg(1, "zlib compressed %ld bytes into %ld; failing\n",
     124                 :            :                           def_strm.total_in, def_strm.total_out);
     125                 :            :                 ret = -1;
     126                 :            :                 goto out;
     127                 :            :         }
     128                 :            : 
     129                 :            :         jffs2_dbg(1, "zlib compressed %ld bytes into %ld\n",
     130                 :            :                   def_strm.total_in, def_strm.total_out);
     131                 :            : 
     132                 :          0 :         *dstlen = def_strm.total_out;
     133                 :          0 :         *sourcelen = def_strm.total_in;
     134                 :            :         ret = 0;
     135                 :            :  out:
     136                 :          0 :         mutex_unlock(&deflate_mutex);
     137                 :          0 :         return ret;
     138                 :            : }
     139                 :            : 
     140                 :          0 : static int jffs2_zlib_decompress(unsigned char *data_in,
     141                 :            :                                  unsigned char *cpage_out,
     142                 :            :                                  uint32_t srclen, uint32_t destlen)
     143                 :            : {
     144                 :            :         int ret;
     145                 :            :         int wbits = MAX_WBITS;
     146                 :            : 
     147                 :          0 :         mutex_lock(&inflate_mutex);
     148                 :            : 
     149                 :          0 :         inf_strm.next_in = data_in;
     150                 :          0 :         inf_strm.avail_in = srclen;
     151                 :          0 :         inf_strm.total_in = 0;
     152                 :            : 
     153                 :          0 :         inf_strm.next_out = cpage_out;
     154                 :          0 :         inf_strm.avail_out = destlen;
     155                 :          0 :         inf_strm.total_out = 0;
     156                 :            : 
     157                 :            :         /* If it's deflate, and it's got no preset dictionary, then
     158                 :            :            we can tell zlib to skip the adler32 check. */
     159 [ #  # ][ #  # ]:          0 :         if (srclen > 2 && !(data_in[1] & PRESET_DICT) &&
                 [ #  # ]
     160         [ #  # ]:          0 :             ((data_in[0] & 0x0f) == Z_DEFLATED) &&
     161                 :          0 :             !(((data_in[0]<<8) + data_in[1]) % 31)) {
     162                 :            : 
     163                 :            :                 jffs2_dbg(2, "inflate skipping adler32\n");
     164                 :          0 :                 wbits = -((data_in[0] >> 4) + 8);
     165                 :          0 :                 inf_strm.next_in += 2;
     166                 :          0 :                 inf_strm.avail_in -= 2;
     167                 :            :         } else {
     168                 :            :                 /* Let this remain D1 for now -- it should never happen */
     169                 :            :                 jffs2_dbg(1, "inflate not skipping adler32\n");
     170                 :            :         }
     171                 :            : 
     172                 :            : 
     173         [ #  # ]:          0 :         if (Z_OK != zlib_inflateInit2(&inf_strm, wbits)) {
     174                 :          0 :                 pr_warn("inflateInit failed\n");
     175                 :          0 :                 mutex_unlock(&inflate_mutex);
     176                 :          0 :                 return 1;
     177                 :            :         }
     178                 :            : 
     179         [ #  # ]:          0 :         while((ret = zlib_inflate(&inf_strm, Z_FINISH)) == Z_OK)
     180                 :            :                 ;
     181         [ #  # ]:          0 :         if (ret != Z_STREAM_END) {
     182                 :          0 :                 pr_notice("inflate returned %d\n", ret);
     183                 :            :         }
     184                 :          0 :         zlib_inflateEnd(&inf_strm);
     185                 :          0 :         mutex_unlock(&inflate_mutex);
     186                 :          0 :         return 0;
     187                 :            : }
     188                 :            : 
     189                 :            : static struct jffs2_compressor jffs2_zlib_comp = {
     190                 :            :     .priority = JFFS2_ZLIB_PRIORITY,
     191                 :            :     .name = "zlib",
     192                 :            :     .compr = JFFS2_COMPR_ZLIB,
     193                 :            :     .compress = &jffs2_zlib_compress,
     194                 :            :     .decompress = &jffs2_zlib_decompress,
     195                 :            : #ifdef JFFS2_ZLIB_DISABLED
     196                 :            :     .disabled = 1,
     197                 :            : #else
     198                 :            :     .disabled = 0,
     199                 :            : #endif
     200                 :            : };
     201                 :            : 
     202                 :          0 : int __init jffs2_zlib_init(void)
     203                 :            : {
     204                 :            :     int ret;
     205                 :            : 
     206                 :          0 :     ret = alloc_workspaces();
     207         [ #  # ]:          0 :     if (ret)
     208                 :            :             return ret;
     209                 :            : 
     210                 :          0 :     ret = jffs2_register_compressor(&jffs2_zlib_comp);
     211         [ #  # ]:          0 :     if (ret)
     212                 :          0 :             free_workspaces();
     213                 :            : 
     214                 :          0 :     return ret;
     215                 :            : }
     216                 :            : 
     217                 :          0 : void jffs2_zlib_exit(void)
     218                 :            : {
     219                 :          0 :     jffs2_unregister_compressor(&jffs2_zlib_comp);
     220                 :          0 :     free_workspaces();
     221                 :          0 : }

Generated by: LCOV version 1.9