add another lzma pcomp fix by jeff hansen - fixes cleanup at the end of do_lzma proce...
[openwrt/svn-archive/archive.git] / target / linux / generic-2.6 / patches-2.6.30 / 052-pcomp_lzma_support.patch
index c5265e9..75dfc37 100644 (file)
@@ -1,6 +1,6 @@
 --- /dev/null
 +++ b/crypto/unlzma.c
-@@ -0,0 +1,710 @@
+@@ -0,0 +1,723 @@
 +/*
 + * LZMA uncompresion module for pcomp
 + * Copyright (C) 2009  Felix Fietkau <nbd@openwrt.org>
@@ -69,6 +69,7 @@
 +      u8 previous_byte;
 +      ssize_t pos;
 +      struct unlzma_buffer *head;
++      int buf_full;
 +
 +      /* cstate */
 +      int state;
 +}
 +
 +static void
++get_buffer(struct unlzma_ctx *ctx)
++{
++      struct unlzma_buffer *bh;
++
++      bh = kzalloc(sizeof(struct unlzma_buffer), GFP_KERNEL);
++      bh->ptr = ctx->next_out;
++      bh->offset = ctx->pos;
++      bh->last = ctx->head;
++      bh->size = ctx->avail_out;
++      ctx->head = bh;
++      ctx->buf_full = 0;
++}
++
++static void
 +unlzma_request_buffer(struct unlzma_ctx *ctx, int *avail)
 +{
-+      mutex_unlock(&ctx->mutex);
-+      wait_event(ctx->next_req, unlzma_should_stop(ctx) || (*avail > 0));
-+      mutex_lock(&ctx->mutex);
++      do {
++              mutex_unlock(&ctx->mutex);
++              if (wait_event_interruptible(ctx->next_req,
++                      unlzma_should_stop(ctx) || (*avail > 0)))
++                      schedule();
++              mutex_lock(&ctx->mutex);
++      } while (*avail <= 0 && !unlzma_should_stop(ctx));
++
++      if (!unlzma_should_stop(ctx) && ctx->buf_full)
++              get_buffer(ctx);
 +}
 +
 +static u8
 +
 +      while (bh->offset > pos) {
 +              bh = bh->last;
-+              if (!bh)
-+                      return 0;
++              BUG_ON(!bh);
 +      }
 +
 +      pos -= bh->offset;
-+      if (pos > bh->size)
-+              return 0;
++      BUG_ON(pos >= bh->size);
 +
 +      return bh->ptr[pos];
 +}
 +
 +static void
-+get_buffer(struct unlzma_ctx *ctx)
-+{
-+      struct unlzma_buffer *bh;
-+
-+      bh = kzalloc(sizeof(struct unlzma_buffer), GFP_KERNEL);
-+      bh->ptr = ctx->next_out;
-+      bh->offset = ctx->pos;
-+      bh->last = ctx->head;
-+      bh->size = ctx->avail_out;
-+      ctx->head = bh;
-+}
-+
-+static void
 +write_byte(struct unlzma_ctx *ctx, u8 byte)
 +{
 +      if (unlikely(ctx->avail_out <= 0)) {
 +              unlzma_request_buffer(ctx, &ctx->avail_out);
-+              get_buffer(ctx);
 +      }
 +
 +      if (!ctx->avail_out)
 +      ctx->previous_byte = byte;
 +      *(ctx->next_out++) = byte;
 +      ctx->avail_out--;
++      if (ctx->avail_out == 0)
++              ctx->buf_full = 1;
 +      ctx->pos++;
 +}
 +
 +      if (ctx->workspace_size < num_probs * sizeof(*p)) {
 +              if (ctx->workspace)
 +                      vfree(ctx->workspace);
-+              ctx->workspace = vmalloc(num_probs * sizeof(*p));
++              ctx->workspace_size = num_probs * sizeof(*p);
++              ctx->workspace = vmalloc(ctx->workspace_size);
 +      }
 +      p = (u16 *) ctx->workspace;
 +      if (!p)
 +              if (unlzma_should_stop(ctx))
 +                      break;
 +      }
++      if (likely(!unlzma_should_stop(ctx)))
++              rc_normalize(ctx);
 +
 +      return ctx->pos;
 +}
 +      req->avail_in = ctx->avail_in;
 +      req->next_out = ctx->next_out;
 +      req->avail_out = ctx->avail_out;
++      ctx->next_in = 0;
++      ctx->avail_in = 0;
 +      pos = ctx->pos - pos;
 +
 +out:
 +MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>");
 --- a/crypto/Kconfig
 +++ b/crypto/Kconfig
-@@ -728,6 +728,12 @@ config CRYPTO_ZLIB
+@@ -758,6 +758,12 @@ config CRYPTO_ZLIB
        help
          This is the zlib algorithm.
  
        select CRYPTO_ALGAPI
 --- a/crypto/Makefile
 +++ b/crypto/Makefile
-@@ -73,6 +73,7 @@ obj-$(CONFIG_CRYPTO_SEED) += seed.o
+@@ -75,6 +75,7 @@ obj-$(CONFIG_CRYPTO_SEED) += seed.o
  obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o
  obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
  obj-$(CONFIG_CRYPTO_ZLIB) += zlib.o