# HG changeset patch # User Pascal Bellard # Date 1250448270 -7200 # Node ID efa4647a631cb5c7b39b8347c19f4bbfbae91649 # Parent 9a3ad6f0607b096e7b09c55e0f8fe46383f2f769 linux: no historic allocation for initramfs unlzma diff -r 9a3ad6f0607b -r efa4647a631c linux/receipt --- a/linux/receipt Sun Aug 16 19:13:58 2009 +0000 +++ b/linux/receipt Sun Aug 16 20:44:30 2009 +0200 @@ -35,6 +35,7 @@ $PACKAGE-utf8-$VERSION.u $PACKAGE-diff-$VERSION.u $PACKAGE-freeinitrd-$VERSION.u +$PACKAGE-unlzma-$VERSION.u EOT make mrproper cp ../stuff/$PACKAGE-$VERSION-slitaz.config .config diff -r 9a3ad6f0607b -r efa4647a631c linux/stuff/linux-unlzma-2.6.30.4.u --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linux/stuff/linux-unlzma-2.6.30.4.u Sun Aug 16 20:44:30 2009 +0200 @@ -0,0 +1,222 @@ +--- linux-2.6.30.4/init/initramfs.c ++++ linux-2.6.30.4/init/initramfs.c +@@ -425,7 +425,8 @@ + return len - count; + } + +-static int __init flush_buffer(void *bufv, unsigned len) +#define flush_buffer cpio_flush_buffer ++int __init flush_buffer(void *bufv, unsigned len) + { + char *buf = (char *) bufv; + int written; + +--- linux-2.6.30.4/lib/decompress_unlzma.c ++++ linux-2.6.30.4/lib/decompress_unlzma.c +@@ -278,6 +278,10 @@ + size_t global_pos; + int(*flush)(void*, unsigned int); + struct lzma_header *header; ++ int is_cpio_flush; ++ uint8_t **buffer_index; ++ int next_index; ++ int max_index; + }; + + struct cstate { +@@ -294,6 +298,14 @@ + static inline uint8_t INIT peek_old_byte(struct writer *wr, + uint32_t offs) + { ++ if (wr->is_cpio_flush) { ++ int32_t pos; ++ while (offs > wr->header->dict_size) ++ offs -= wr->header->dict_size; ++ pos = wr->buffer_pos - offs; ++ return wr->buffer_index[pos / LZMA_IOBUF_SIZE] ++ [pos % LZMA_IOBUF_SIZE]; ++ } + if (!wr->flush) { + int32_t pos; + while (offs > wr->header->dict_size) +@@ -311,6 +323,34 @@ + + static inline void INIT write_byte(struct writer *wr, uint8_t byte) + { ++ if (wr->is_cpio_flush) { ++ if (wr->buffer_pos % LZMA_IOBUF_SIZE == 0) { ++ // if the following large_malloc fails, the initramfs ++ // whould not be load with is_cpio_flush forced 0 too. ++ // Remember we do not allocate historic buffer. ++ // Let's assume it will never fail ! ++ if (wr->next_index >= wr->max_index) { ++ // realloc wr->buffer_index ++ uint8_t **p = wr->buffer_index; ++ wr->buffer_index = (uint8_t **) ++ large_malloc(LZMA_IOBUF_SIZE + ++ sizeof(*p) * wr->max_index); ++ if (wr->max_index) { ++ memcpy(wr->buffer_index, p, ++ sizeof(*p) * wr->max_index); ++ free(p); ++ } ++ wr->max_index += LZMA_IOBUF_SIZE / sizeof(*p); ++ } ++ wr->buffer_index[wr->next_index++] = ++ (uint8_t *) large_malloc(LZMA_IOBUF_SIZE); ++ } ++ wr->buffer_index[wr->buffer_pos / LZMA_IOBUF_SIZE] ++ [wr->buffer_pos % LZMA_IOBUF_SIZE] = ++ wr->previous_byte = byte; ++ wr->buffer_pos++; ++ return; ++ } + wr->buffer[wr->buffer_pos++] = wr->previous_byte = byte; + if (wr->flush && wr->buffer_pos == wr->header->dict_size) { + wr->buffer_pos = 0; +@@ -339,6 +379,9 @@ + int pos_state, uint16_t *prob, + int lc, uint32_t literal_pos_mask) { + int mi = 1; ++ static const int state[LZMA_NUM_STATES] = ++ { 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 }; ++ + rc_update_bit_0(rc, prob); + prob = (p + LZMA_LITERAL + + (LZMA_LIT_SIZE +@@ -369,18 +412,13 @@ + rc_get_bit(rc, prob_lit, &mi); + } + write_byte(wr, mi); +- if (cst->state < 4) +- cst->state = 0; +- else if (cst->state < 10) +- cst->state -= 3; +- else +- cst->state -= 6; ++ cst->state = state[cst->state]; + } + + static inline void INIT process_bit1(struct writer *wr, struct rc *rc, + struct cstate *cst, uint16_t *p, + int pos_state, uint16_t *prob) { +- int offset; ++ int offset; + uint16_t *prob_len; + int num_bits; + int len; +@@ -396,7 +434,7 @@ + prob = p + LZMA_LEN_CODER; + } else { + rc_update_bit_1(rc, prob); +- prob = p + LZMA_IS_REP_G0 + cst->state; ++ prob += LZMA_IS_REP_G0 - LZMA_IS_REP; + if (rc_is_bit_0(rc, prob)) { + rc_update_bit_0(rc, prob); + prob = (p + LZMA_IS_REP_0_LONG +@@ -417,13 +455,13 @@ + uint32_t distance; + + rc_update_bit_1(rc, prob); +- prob = p + LZMA_IS_REP_G1 + cst->state; ++ prob += LZMA_IS_REP_G1 - LZMA_IS_REP_G0; + if (rc_is_bit_0(rc, prob)) { + rc_update_bit_0(rc, prob); + distance = cst->rep1; + } else { + rc_update_bit_1(rc, prob); +- prob = p + LZMA_IS_REP_G2 + cst->state; ++ prob += LZMA_IS_REP_G2 - LZMA_IS_REP_G1; + if (rc_is_bit_0(rc, prob)) { + rc_update_bit_0(rc, prob); + distance = cst->rep2; +@@ -451,7 +489,7 @@ + num_bits = LZMA_LEN_NUM_LOW_BITS; + } else { + rc_update_bit_1(rc, prob_len); +- prob_len = prob + LZMA_LEN_CHOICE_2; ++ prob_len += LZMA_LEN_CHOICE_2 - LZMA_LEN_CHOICE; + if (rc_is_bit_0(rc, prob_len)) { + rc_update_bit_0(rc, prob_len); + prob_len = (prob + LZMA_LEN_MID +@@ -461,7 +499,7 @@ + num_bits = LZMA_LEN_NUM_MID_BITS; + } else { + rc_update_bit_1(rc, prob_len); +- prob_len = prob + LZMA_LEN_HIGH; ++ prob_len += LZMA_LEN_HIGH - LZMA_LEN_CHOICE_2; + offset = ((1 << LZMA_LEN_NUM_LOW_BITS) + + (1 << LZMA_LEN_NUM_MID_BITS)); + num_bits = LZMA_LEN_NUM_HIGH_BITS; +@@ -529,6 +567,7 @@ + void(*error_fn)(char *x) + ) + { ++ extern int cpio_flush_buffer(void*, unsigned int); + struct lzma_header header; + int lc, pb, lp; + uint32_t pos_state_mask; +@@ -563,6 +602,10 @@ + wr.global_pos = 0; + wr.previous_byte = 0; + wr.buffer_pos = 0; ++ wr.is_cpio_flush = 0; ++ if (flush == cpio_flush_buffer) ++ wr.is_cpio_flush = 1; ++ wr.buffer_index = NULL; + + rc_init(&rc, fill, inbuf, in_len); + +@@ -596,13 +639,13 @@ + if (header.dict_size == 0) + header.dict_size = 1; + +- if (output) ++ if (output || wr.is_cpio_flush) + wr.buffer = output; + else { + wr.bufsize = MIN(header.dst_size, header.dict_size); + wr.buffer = large_malloc(wr.bufsize); + } +- if (wr.buffer == NULL) ++ if (wr.buffer == NULL && !wr.is_cpio_flush) + goto exit_1; + + num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)); +@@ -612,7 +655,7 @@ + num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp)); + for (i = 0; i < num_probs; i++) + p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; +- ++ wr.max_index = wr.next_index = 0; + rc_init_code(&rc); + + while (get_pos(&wr) < header.dst_size) { +@@ -631,12 +674,25 @@ + + if (posp) + *posp = rc.ptr-rc.buffer; +- if (wr.flush) ++ if (wr.is_cpio_flush) { ++ int i; ++ for (i = 0; i < wr.next_index -1; i++) { ++ wr.flush(wr.buffer_index[i], LZMA_IOBUF_SIZE); ++ large_free(wr.buffer_index[i]); ++ } ++ if (i < wr.next_index) { ++ wr.flush(wr.buffer_index[i], ++ wr.buffer_pos % LZMA_IOBUF_SIZE); ++ large_free(wr.buffer_index[i]); ++ } ++ large_free(wr.buffer_index); ++ } ++ else if (wr.flush) + wr.flush(wr.buffer, wr.buffer_pos); + ret = 0; + large_free(p); + exit_2: +- if (!output) ++ if (!output && !wr.is_cpio_flush) + large_free(wr.buffer); + exit_1: + if (!buf)