source: rtems/cpukit/libfs/src/jffs2/src/compr_zlib.c @ 3c96bee

4.115
Last change on this file since 3c96bee was 3c96bee, checked in by Sebastian Huber <sebastian.huber@…>, on 09/12/13 at 13:32:07

JFFS2: Add RTEMS support

  • Property mode set to 100644
File size: 4.6 KB
RevLine 
[0c0f128]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
34static DEFINE_MUTEX(deflate_mutex);
35static DEFINE_MUTEX(inflate_mutex);
36
[3c96bee]37static rtems_jffs2_compressor_zlib_control *get_zlib_control(
38        rtems_jffs2_compressor_control *super
39)
[0c0f128]40{
[3c96bee]41        return (rtems_jffs2_compressor_zlib_control *) super;
[0c0f128]42}
43
[3c96bee]44uint16_t rtems_jffs2_compressor_zlib_compress(
45        rtems_jffs2_compressor_control *super,
46        unsigned char *data_in,
47        unsigned char *cpage_out,
48        uint32_t *sourcelen,
49        uint32_t *dstlen
50)
[0c0f128]51{
[3c96bee]52        rtems_jffs2_compressor_zlib_control *self = get_zlib_control(super);
53        z_stream *def_strm = &self->stream;
[0c0f128]54        int ret;
55
56        if (*dstlen <= STREAM_END_SPACE)
[3c96bee]57                return JFFS2_COMPR_NONE;
[0c0f128]58
59        mutex_lock(&deflate_mutex);
60
[3c96bee]61        if (Z_OK != zlib_deflateInit(def_strm, 3)) {
[0c0f128]62                pr_warn("deflateInit failed\n");
63                mutex_unlock(&deflate_mutex);
[3c96bee]64                return JFFS2_COMPR_NONE;
[0c0f128]65        }
66
[3c96bee]67        def_strm->next_in = data_in;
68        def_strm->total_in = 0;
[0c0f128]69
[3c96bee]70        def_strm->next_out = cpage_out;
71        def_strm->total_out = 0;
[0c0f128]72
[3c96bee]73        while (def_strm->total_out < *dstlen - STREAM_END_SPACE && def_strm->total_in < *sourcelen) {
74                def_strm->avail_out = *dstlen - (def_strm->total_out + STREAM_END_SPACE);
75                def_strm->avail_in = min((unsigned)(*sourcelen-def_strm->total_in), def_strm->avail_out);
[0c0f128]76                jffs2_dbg(1, "calling deflate with avail_in %d, avail_out %d\n",
[3c96bee]77                          def_strm->avail_in, def_strm->avail_out);
78                ret = zlib_deflate(def_strm, Z_PARTIAL_FLUSH);
[0c0f128]79                jffs2_dbg(1, "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n",
[3c96bee]80                          def_strm->avail_in, def_strm->avail_out,
81                          def_strm->total_in, def_strm->total_out);
[0c0f128]82                if (ret != Z_OK) {
83                        jffs2_dbg(1, "deflate in loop returned %d\n", ret);
[3c96bee]84                        zlib_deflateEnd(def_strm);
[0c0f128]85                        mutex_unlock(&deflate_mutex);
[3c96bee]86                        return JFFS2_COMPR_NONE;
[0c0f128]87                }
88        }
[3c96bee]89        def_strm->avail_out += STREAM_END_SPACE;
90        def_strm->avail_in = 0;
91        ret = zlib_deflate(def_strm, Z_FINISH);
92        zlib_deflateEnd(def_strm);
[0c0f128]93
94        if (ret != Z_STREAM_END) {
95                jffs2_dbg(1, "final deflate returned %d\n", ret);
[3c96bee]96                ret = JFFS2_COMPR_NONE;
[0c0f128]97                goto out;
98        }
99
[3c96bee]100        if (def_strm->total_out >= def_strm->total_in) {
[0c0f128]101                jffs2_dbg(1, "zlib compressed %ld bytes into %ld; failing\n",
[3c96bee]102                          def_strm->total_in, def_strm->total_out);
103                ret = JFFS2_COMPR_NONE;
[0c0f128]104                goto out;
105        }
106
107        jffs2_dbg(1, "zlib compressed %ld bytes into %ld\n",
[3c96bee]108                  def_strm->total_in, def_strm->total_out);
[0c0f128]109
[3c96bee]110        *dstlen = def_strm->total_out;
111        *sourcelen = def_strm->total_in;
112        ret = JFFS2_COMPR_ZLIB;
[0c0f128]113 out:
114        mutex_unlock(&deflate_mutex);
115        return ret;
116}
117
[3c96bee]118int rtems_jffs2_compressor_zlib_decompress(
119        rtems_jffs2_compressor_control *super,
120        uint16_t comprtype,
121        unsigned char *data_in,
122        unsigned char *cpage_out,
123        uint32_t srclen,
124        uint32_t destlen
125)
[0c0f128]126{
[3c96bee]127        rtems_jffs2_compressor_zlib_control *self = get_zlib_control(super);
128        z_stream *inf_strm = &self->stream;
[0c0f128]129        int ret;
130        int wbits = MAX_WBITS;
131
[3c96bee]132        if (comprtype != JFFS2_COMPR_ZLIB) {
133                return -EIO;
134        }
135
[0c0f128]136        mutex_lock(&inflate_mutex);
137
[3c96bee]138        inf_strm->next_in = data_in;
139        inf_strm->avail_in = srclen;
140        inf_strm->total_in = 0;
[0c0f128]141
[3c96bee]142        inf_strm->next_out = cpage_out;
143        inf_strm->avail_out = destlen;
144        inf_strm->total_out = 0;
[0c0f128]145
146        /* If it's deflate, and it's got no preset dictionary, then
147           we can tell zlib to skip the adler32 check. */
148        if (srclen > 2 && !(data_in[1] & PRESET_DICT) &&
149            ((data_in[0] & 0x0f) == Z_DEFLATED) &&
150            !(((data_in[0]<<8) + data_in[1]) % 31)) {
151
152                jffs2_dbg(2, "inflate skipping adler32\n");
153                wbits = -((data_in[0] >> 4) + 8);
[3c96bee]154                inf_strm->next_in += 2;
155                inf_strm->avail_in -= 2;
[0c0f128]156        } else {
157                /* Let this remain D1 for now -- it should never happen */
158                jffs2_dbg(1, "inflate not skipping adler32\n");
159        }
160
161
[3c96bee]162        if (Z_OK != zlib_inflateInit2(inf_strm, wbits)) {
[0c0f128]163                pr_warn("inflateInit failed\n");
164                mutex_unlock(&inflate_mutex);
[3c96bee]165                return -EIO;
[0c0f128]166        }
167
[3c96bee]168        while((ret = zlib_inflate(inf_strm, Z_FINISH)) == Z_OK)
[0c0f128]169                ;
170        if (ret != Z_STREAM_END) {
171                pr_notice("inflate returned %d\n", ret);
172        }
[3c96bee]173        zlib_inflateEnd(inf_strm);
[0c0f128]174        mutex_unlock(&inflate_mutex);
175        return 0;
176}
Note: See TracBrowser for help on using the repository browser.