wok-next diff linux/stuff/linux-unlzma-2.6.30.4.u @ rev 3908

linux: no historic allocation for initramfs unlzma
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Aug 16 20:44:30 2009 +0200 (2009-08-16)
parents
children 1ef7110e0997
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/linux/stuff/linux-unlzma-2.6.30.4.u	Sun Aug 16 20:44:30 2009 +0200
     1.3 @@ -0,0 +1,222 @@
     1.4 +--- linux-2.6.30.4/init/initramfs.c
     1.5 ++++ linux-2.6.30.4/init/initramfs.c
     1.6 +@@ -425,7 +425,8 @@
     1.7 + 	return len - count;
     1.8 + }
     1.9 + 
    1.10 +-static int __init flush_buffer(void *bufv, unsigned len)
    1.11 +#define flush_buffer cpio_flush_buffer
    1.12 ++int __init flush_buffer(void *bufv, unsigned len)
    1.13 + {
    1.14 + 	char *buf = (char *) bufv;
    1.15 + 	int written;
    1.16 +
    1.17 +--- linux-2.6.30.4/lib/decompress_unlzma.c
    1.18 ++++ linux-2.6.30.4/lib/decompress_unlzma.c
    1.19 +@@ -278,6 +278,10 @@
    1.20 + 	size_t global_pos;
    1.21 + 	int(*flush)(void*, unsigned int);
    1.22 + 	struct lzma_header *header;
    1.23 ++	int is_cpio_flush;
    1.24 ++	uint8_t **buffer_index;
    1.25 ++	int next_index;
    1.26 ++	int max_index;
    1.27 + };
    1.28 + 
    1.29 + struct cstate {
    1.30 +@@ -294,6 +298,14 @@
    1.31 + static inline uint8_t INIT peek_old_byte(struct writer *wr,
    1.32 + 						uint32_t offs)
    1.33 + {
    1.34 ++	if (wr->is_cpio_flush) {
    1.35 ++		int32_t pos;
    1.36 ++		while (offs > wr->header->dict_size)
    1.37 ++			offs -= wr->header->dict_size;
    1.38 ++		pos = wr->buffer_pos - offs;
    1.39 ++		return wr->buffer_index[pos / LZMA_IOBUF_SIZE]
    1.40 ++				       [pos % LZMA_IOBUF_SIZE];
    1.41 ++	}
    1.42 + 	if (!wr->flush) {
    1.43 + 		int32_t pos;
    1.44 + 		while (offs > wr->header->dict_size)
    1.45 +@@ -311,6 +323,34 @@
    1.46 + 
    1.47 + static inline void INIT write_byte(struct writer *wr, uint8_t byte)
    1.48 + {
    1.49 ++	if (wr->is_cpio_flush) {
    1.50 ++		if (wr->buffer_pos % LZMA_IOBUF_SIZE == 0) {
    1.51 ++			// if the following large_malloc fails, the initramfs
    1.52 ++			// whould not be load with is_cpio_flush forced 0 too.
    1.53 ++			// Remember we do not allocate historic buffer.
    1.54 ++			// Let's assume it will never fail !
    1.55 ++			if (wr->next_index >= wr->max_index) {
    1.56 ++				// realloc wr->buffer_index
    1.57 ++				uint8_t **p = wr->buffer_index;
    1.58 ++				wr->buffer_index = (uint8_t **) 
    1.59 ++					large_malloc(LZMA_IOBUF_SIZE + 
    1.60 ++						    sizeof(*p) * wr->max_index);
    1.61 ++				if (wr->max_index) {
    1.62 ++					memcpy(wr->buffer_index, p,
    1.63 ++					       sizeof(*p) * wr->max_index);
    1.64 ++					free(p);
    1.65 ++				}
    1.66 ++				wr->max_index += LZMA_IOBUF_SIZE / sizeof(*p);
    1.67 ++			}
    1.68 ++			wr->buffer_index[wr->next_index++] =
    1.69 ++				(uint8_t *) large_malloc(LZMA_IOBUF_SIZE);
    1.70 ++		}
    1.71 ++		wr->buffer_index[wr->buffer_pos / LZMA_IOBUF_SIZE]
    1.72 ++				[wr->buffer_pos % LZMA_IOBUF_SIZE] =
    1.73 ++			wr->previous_byte = byte;
    1.74 ++		wr->buffer_pos++;
    1.75 ++		return;
    1.76 ++	}
    1.77 + 	wr->buffer[wr->buffer_pos++] = wr->previous_byte = byte;
    1.78 + 	if (wr->flush && wr->buffer_pos == wr->header->dict_size) {
    1.79 + 		wr->buffer_pos = 0;
    1.80 +@@ -339,6 +379,9 @@
    1.81 + 				     int pos_state, uint16_t *prob,
    1.82 + 				     int lc, uint32_t literal_pos_mask) {
    1.83 + 	int mi = 1;
    1.84 ++	static const int state[LZMA_NUM_STATES] = 
    1.85 ++		{ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
    1.86 ++
    1.87 + 	rc_update_bit_0(rc, prob);
    1.88 + 	prob = (p + LZMA_LITERAL +
    1.89 + 		(LZMA_LIT_SIZE
    1.90 +@@ -369,18 +412,13 @@
    1.91 + 		rc_get_bit(rc, prob_lit, &mi);
    1.92 + 	}
    1.93 + 	write_byte(wr, mi);
    1.94 +-	if (cst->state < 4)
    1.95 +-		cst->state = 0;
    1.96 +-	else if (cst->state < 10)
    1.97 +-		cst->state -= 3;
    1.98 +-	else
    1.99 +-		cst->state -= 6;
   1.100 ++	cst->state = state[cst->state];
   1.101 + }
   1.102 + 
   1.103 + static inline void INIT process_bit1(struct writer *wr, struct rc *rc,
   1.104 + 					    struct cstate *cst, uint16_t *p,
   1.105 + 					    int pos_state, uint16_t *prob) {
   1.106 +-  int offset;
   1.107 ++	int offset;
   1.108 + 	uint16_t *prob_len;
   1.109 + 	int num_bits;
   1.110 + 	int len;
   1.111 +@@ -396,7 +434,7 @@
   1.112 + 		prob = p + LZMA_LEN_CODER;
   1.113 + 	} else {
   1.114 + 		rc_update_bit_1(rc, prob);
   1.115 +-		prob = p + LZMA_IS_REP_G0 + cst->state;
   1.116 ++		prob += LZMA_IS_REP_G0 - LZMA_IS_REP;
   1.117 + 		if (rc_is_bit_0(rc, prob)) {
   1.118 + 			rc_update_bit_0(rc, prob);
   1.119 + 			prob = (p + LZMA_IS_REP_0_LONG
   1.120 +@@ -417,13 +455,13 @@
   1.121 + 			uint32_t distance;
   1.122 + 
   1.123 + 			rc_update_bit_1(rc, prob);
   1.124 +-			prob = p + LZMA_IS_REP_G1 + cst->state;
   1.125 ++			prob += LZMA_IS_REP_G1 - LZMA_IS_REP_G0;
   1.126 + 			if (rc_is_bit_0(rc, prob)) {
   1.127 + 				rc_update_bit_0(rc, prob);
   1.128 + 				distance = cst->rep1;
   1.129 + 			} else {
   1.130 + 				rc_update_bit_1(rc, prob);
   1.131 +-				prob = p + LZMA_IS_REP_G2 + cst->state;
   1.132 ++				prob += LZMA_IS_REP_G2 - LZMA_IS_REP_G1;
   1.133 + 				if (rc_is_bit_0(rc, prob)) {
   1.134 + 					rc_update_bit_0(rc, prob);
   1.135 + 					distance = cst->rep2;
   1.136 +@@ -451,7 +489,7 @@
   1.137 + 		num_bits = LZMA_LEN_NUM_LOW_BITS;
   1.138 + 	} else {
   1.139 + 		rc_update_bit_1(rc, prob_len);
   1.140 +-		prob_len = prob + LZMA_LEN_CHOICE_2;
   1.141 ++		prob_len += LZMA_LEN_CHOICE_2 - LZMA_LEN_CHOICE;
   1.142 + 		if (rc_is_bit_0(rc, prob_len)) {
   1.143 + 			rc_update_bit_0(rc, prob_len);
   1.144 + 			prob_len = (prob + LZMA_LEN_MID
   1.145 +@@ -461,7 +499,7 @@
   1.146 + 			num_bits = LZMA_LEN_NUM_MID_BITS;
   1.147 + 		} else {
   1.148 + 			rc_update_bit_1(rc, prob_len);
   1.149 +-			prob_len = prob + LZMA_LEN_HIGH;
   1.150 ++			prob_len += LZMA_LEN_HIGH - LZMA_LEN_CHOICE_2;
   1.151 + 			offset = ((1 << LZMA_LEN_NUM_LOW_BITS)
   1.152 + 				  + (1 << LZMA_LEN_NUM_MID_BITS));
   1.153 + 			num_bits = LZMA_LEN_NUM_HIGH_BITS;
   1.154 +@@ -529,6 +567,7 @@
   1.155 + 			      void(*error_fn)(char *x)
   1.156 + 	)
   1.157 + {
   1.158 ++	extern int cpio_flush_buffer(void*, unsigned int);
   1.159 + 	struct lzma_header header;
   1.160 + 	int lc, pb, lp;
   1.161 + 	uint32_t pos_state_mask;
   1.162 +@@ -563,6 +602,10 @@
   1.163 + 	wr.global_pos = 0;
   1.164 + 	wr.previous_byte = 0;
   1.165 + 	wr.buffer_pos = 0;
   1.166 ++	wr.is_cpio_flush = 0;
   1.167 ++	if (flush == cpio_flush_buffer)
   1.168 ++		wr.is_cpio_flush = 1;
   1.169 ++	wr.buffer_index = NULL;
   1.170 + 
   1.171 + 	rc_init(&rc, fill, inbuf, in_len);
   1.172 + 
   1.173 +@@ -596,13 +639,13 @@
   1.174 + 	if (header.dict_size == 0)
   1.175 + 		header.dict_size = 1;
   1.176 + 
   1.177 +-	if (output)
   1.178 ++	if (output || wr.is_cpio_flush)
   1.179 + 		wr.buffer = output;
   1.180 + 	else {
   1.181 + 		wr.bufsize = MIN(header.dst_size, header.dict_size);
   1.182 + 		wr.buffer = large_malloc(wr.bufsize);
   1.183 + 	}
   1.184 +-	if (wr.buffer == NULL)
   1.185 ++	if (wr.buffer == NULL && !wr.is_cpio_flush)
   1.186 + 		goto exit_1;
   1.187 + 
   1.188 + 	num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp));
   1.189 +@@ -612,7 +655,7 @@
   1.190 + 	num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp));
   1.191 + 	for (i = 0; i < num_probs; i++)
   1.192 + 		p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
   1.193 +-
   1.194 ++	wr.max_index = wr.next_index = 0;
   1.195 + 	rc_init_code(&rc);
   1.196 + 
   1.197 + 	while (get_pos(&wr) < header.dst_size) {
   1.198 +@@ -631,12 +674,25 @@
   1.199 + 
   1.200 + 	if (posp)
   1.201 + 		*posp = rc.ptr-rc.buffer;
   1.202 +-	if (wr.flush)
   1.203 ++	if (wr.is_cpio_flush) {
   1.204 ++		int i;
   1.205 ++		for (i = 0; i < wr.next_index -1; i++) {
   1.206 ++			wr.flush(wr.buffer_index[i], LZMA_IOBUF_SIZE);
   1.207 ++			large_free(wr.buffer_index[i]);
   1.208 ++		}
   1.209 ++		if (i < wr.next_index) {
   1.210 ++			wr.flush(wr.buffer_index[i], 
   1.211 ++				 wr.buffer_pos % LZMA_IOBUF_SIZE);
   1.212 ++			large_free(wr.buffer_index[i]);
   1.213 ++		}
   1.214 ++		large_free(wr.buffer_index);
   1.215 ++	}
   1.216 ++	else if (wr.flush)
   1.217 + 		wr.flush(wr.buffer, wr.buffer_pos);
   1.218 + 	ret = 0;
   1.219 + 	large_free(p);
   1.220 + exit_2:
   1.221 +-	if (!output)
   1.222 ++	if (!output && !wr.is_cpio_flush)
   1.223 + 		large_free(wr.buffer);
   1.224 + exit_1:
   1.225 + 	if (!buf)