wok-6.x rev 18894
fusecloop/create_compressed_fs: deduplicate
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sat Feb 13 18:33:57 2016 +0100 (2016-02-13) |
parents | 8fafe6486d97 |
children | 624197d091b7 |
files | fusecloop/stuff/fusecloop.u |
line diff
1.1 --- a/fusecloop/stuff/fusecloop.u Sat Feb 13 10:39:15 2016 +0100 1.2 +++ b/fusecloop/stuff/fusecloop.u Sat Feb 13 18:33:57 2016 +0100 1.3 @@ -176,7 +176,7 @@ 1.4 if (handle < 0) { 1.5 perror("Opening compressed file\n"); 1.6 exit(1); 1.7 -@@ -24,44 +28,100 @@ 1.8 +@@ -24,66 +28,100 @@ 1.9 exit(1); 1.10 } 1.11 1.12 @@ -214,7 +214,7 @@ 1.13 + table_size = ntohl(tail.table_size); 1.14 + table = malloc(table_size); 1.15 + len = i = num_blocks * (ntohl(tail.index_size) & 255); 1.16 -+ lastlen = ntohl(tail.index_size) & ~0x1FF; 1.17 ++ lastlen = ntohl(tail.index_size) / 256; 1.18 + offsets = malloc(num_blocks * sizeof(*offsets)); 1.19 + if (!table || !offsets || 1.20 + read(handle, table, table_size) != table_size || 1.21 @@ -298,19 +298,42 @@ 1.22 1.23 - fprintf(stderr, "Block %u length %u => %lu\n", 1.24 - i, size, destlen); 1.25 -+ fprintf(stderr, "Block %u at %llu length %u => %lu\n", 1.26 -+ i, offsets[i].offset, size, destlen); 1.27 - if (i == 3) { 1.28 - fprintf(stderr, 1.29 - "Block head:%02X%02X%02X%02X%02X%02X%02X%02X\n", 1.30 -@@ -105,12 +165,12 @@ 1.31 +- if (i == 3) { 1.32 +- fprintf(stderr, 1.33 +- "Block head:%02X%02X%02X%02X%02X%02X%02X%02X\n", 1.34 +- buffer[0], 1.35 +- buffer[1], 1.36 +- buffer[2], 1.37 +- buffer[3], 1.38 +- buffer[4], 1.39 +- buffer[5], 1.40 +- buffer[6], 1.41 +- buffer[7]); 1.42 +- fprintf(stderr, 1.43 +- "Block tail:%02X%02X%02X%02X%02X%02X%02X%02X\n", 1.44 +- buffer[3063], 1.45 +- buffer[3064], 1.46 +- buffer[3065], 1.47 +- buffer[3066], 1.48 +- buffer[3067], 1.49 +- buffer[3068], 1.50 +- buffer[3069], 1.51 +- buffer[3070]); 1.52 +- } 1.53 ++ fprintf(stderr, "Block %u at %llu length %u", 1.54 ++ i, offsets[i].offset, size); 1.55 + switch (uncompress(clear_buffer, &destlen, 1.56 + buffer, size)) { 1.57 + case Z_OK: 1.58 +@@ -105,12 +143,13 @@ 1.59 fprintf(stderr, "Uncomp: unknown error %u\n", i); 1.60 exit(1); 1.61 } 1.62 - if (destlen != ntohl(head.block_size)) { 1.63 - fprintf(stderr, "Uncomp: bad len %u (%lu not %u)\n", i, 1.64 - destlen, ntohl(head.block_size)); 1.65 -+ if (destlen != block_size) { 1.66 ++ fprintf(stderr, " => %lu\n", destlen); 1.67 ++ if (destlen != block_size && i != num_blocks - 1) { 1.68 + fprintf(stderr, "Uncomp: bad len %u (%lu not %lu)\n", i, 1.69 + destlen, block_size); 1.70 exit(1); 1.71 @@ -320,7 +343,6 @@ 1.72 } 1.73 return 0; 1.74 } 1.75 - 1.76 --- Makefile 1.77 +++ Makefile 1.78 @@ -1,16 +1,19 @@ 1.79 @@ -339,7 +361,7 @@ 1.80 extract_compressed_fs: extract_compressed_fs.c 1.81 ${CC} ${CFLAGS} ${LDFLAGS} -lz extract_compressed_fs.c -o extract_compressed_fs 1.82 1.83 -+create_compressed_fs: create_compressed_fs.c 1.84 ++create_compressed_fs: create_compressed_fs.c md5sum.c 1.85 + ${CC} ${CFLAGS} ${LDFLAGS} -lz create_compressed_fs.c -o create_compressed_fs 1.86 + 1.87 fusecloop: fusecloop.c cloopreader.o strver debug.o 1.88 @@ -347,9 +369,258 @@ 1.89 1.90 1.91 1.92 +--- md5sum.c 1.93 ++++ md5sum.c 1.94 +@@ -0,0 +1,246 @@ 1.95 ++/* 1.96 ++ * Based on busybox code. 1.97 ++ * 1.98 ++ * Compute MD5 checksum of strings according to the 1.99 ++ * definition of MD5 in RFC 1321 from April 1992. 1.100 ++ * 1.101 ++ * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. 1.102 ++ * 1.103 ++ * Copyright (C) 1995-1999 Free Software Foundation, Inc. 1.104 ++ * Copyright (C) 2001 Manuel Novoa III 1.105 ++ * Copyright (C) 2003 Glenn L. McGrath 1.106 ++ * Copyright (C) 2003 Erik Andersen 1.107 ++ * Copyright (C) 2010 Denys Vlasenko 1.108 ++ * Copyright (C) 2012 Pascal Bellard 1.109 ++ * 1.110 ++ * Licensed under GPLv2 or later 1.111 ++ */ 1.112 ++ 1.113 ++#define ALIGN1 1.114 ++ 1.115 ++static uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ 1.116 ++static uint64_t total64; /* must be directly before hash[] */ 1.117 ++static uint32_t hash[8]; /* 4 elements for md5, 5 for sha1, 8 for sha256 */ 1.118 ++ 1.119 ++/* Emit a string of hex representation of bytes */ 1.120 ++static char* bin2hex(char *p) 1.121 ++{ 1.122 ++ static const char bb_hexdigits_upcase[] ALIGN1 = "0123456789abcdef"; 1.123 ++ int count = 16; 1.124 ++ const char *cp = (const char *) hash; 1.125 ++ while (count) { 1.126 ++ unsigned char c = *cp++; 1.127 ++ /* put lowercase hex digits */ 1.128 ++ *p++ = bb_hexdigits_upcase[c >> 4]; 1.129 ++ *p++ = bb_hexdigits_upcase[c & 0xf]; 1.130 ++ count--; 1.131 ++ } 1.132 ++ return p; 1.133 ++} 1.134 ++ 1.135 ++//#define rotl32(x,n) (((x) << (n)) | ((x) >> (32 - (n)))) 1.136 ++static uint32_t rotl32(uint32_t x, unsigned n) 1.137 ++{ 1.138 ++ return (x << n) | (x >> (32 - n)); 1.139 ++} 1.140 ++ 1.141 ++static void md5_process_block64(void); 1.142 ++ 1.143 ++/* Feed data through a temporary buffer. 1.144 ++ * The internal buffer remembers previous data until it has 64 1.145 ++ * bytes worth to pass on. 1.146 ++ */ 1.147 ++static void common64_hash(const void *buffer, size_t len) 1.148 ++{ 1.149 ++ unsigned bufpos = total64 & 63; 1.150 ++ 1.151 ++ total64 += len; 1.152 ++ 1.153 ++ while (1) { 1.154 ++ unsigned remaining = 64 - bufpos; 1.155 ++ if (remaining > len) 1.156 ++ remaining = len; 1.157 ++ /* Copy data into aligned buffer */ 1.158 ++ memcpy(wbuffer + bufpos, buffer, remaining); 1.159 ++ len -= remaining; 1.160 ++ buffer = (const char *)buffer + remaining; 1.161 ++ bufpos += remaining; 1.162 ++ /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */ 1.163 ++ bufpos -= 64; 1.164 ++ if (bufpos != 0) 1.165 ++ break; 1.166 ++ /* Buffer is filled up, process it */ 1.167 ++ md5_process_block64(); 1.168 ++ /*bufpos = 0; - already is */ 1.169 ++ } 1.170 ++} 1.171 ++ 1.172 ++/* Process the remaining bytes in the buffer */ 1.173 ++static void common64_end(void) 1.174 ++{ 1.175 ++ unsigned bufpos = total64 & 63; 1.176 ++ /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ 1.177 ++ wbuffer[bufpos++] = 0x80; 1.178 ++ 1.179 ++ /* This loop iterates either once or twice, no more, no less */ 1.180 ++ while (1) { 1.181 ++ unsigned remaining = 64 - bufpos; 1.182 ++ memset(wbuffer + bufpos, 0, remaining); 1.183 ++ /* Do we have enough space for the length count? */ 1.184 ++ if (remaining >= 8) { 1.185 ++ /* Store the 64-bit counter of bits in the buffer */ 1.186 ++ uint64_t t = total64 << 3; 1.187 ++ /* wbuffer is suitably aligned for this */ 1.188 ++ *(uint64_t *) (&wbuffer[64 - 8]) = t; 1.189 ++ } 1.190 ++ md5_process_block64(); 1.191 ++ if (remaining >= 8) 1.192 ++ break; 1.193 ++ bufpos = 0; 1.194 ++ } 1.195 ++} 1.196 ++ 1.197 ++/* These are the four functions used in the four steps of the MD5 algorithm 1.198 ++ * and defined in the RFC 1321. The first function is a little bit optimized 1.199 ++ * (as found in Colin Plumbs public domain implementation). 1.200 ++ * #define FF(b, c, d) ((b & c) | (~b & d)) 1.201 ++ */ 1.202 ++#undef FF 1.203 ++#undef FG 1.204 ++#undef FH 1.205 ++#undef FI 1.206 ++#define FF(b, c, d) (d ^ (b & (c ^ d))) 1.207 ++#define FG(b, c, d) FF(d, b, c) 1.208 ++#define FH(b, c, d) (b ^ c ^ d) 1.209 ++#define FI(b, c, d) (c ^ (b | ~d)) 1.210 ++ 1.211 ++/* Hash a single block, 64 bytes long and 4-byte aligned */ 1.212 ++static void md5_process_block64(void) 1.213 ++{ 1.214 ++ /* Before we start, one word to the strange constants. 1.215 ++ They are defined in RFC 1321 as 1.216 ++ T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64 1.217 ++ */ 1.218 ++ static const uint32_t C_array[] = { 1.219 ++ /* round 1 */ 1.220 ++ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 1.221 ++ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 1.222 ++ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 1.223 ++ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 1.224 ++ /* round 2 */ 1.225 ++ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 1.226 ++ 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 1.227 ++ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 1.228 ++ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 1.229 ++ /* round 3 */ 1.230 ++ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 1.231 ++ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 1.232 ++ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, 1.233 ++ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 1.234 ++ /* round 4 */ 1.235 ++ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 1.236 ++ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 1.237 ++ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 1.238 ++ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 1.239 ++ }; 1.240 ++ static const char P_array[] ALIGN1 = { 1.241 ++ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ 1.242 ++ 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ 1.243 ++ 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */ 1.244 ++ 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ 1.245 ++ }; 1.246 ++ uint32_t *words = (void*) wbuffer; 1.247 ++ uint32_t A = hash[0]; 1.248 ++ uint32_t B = hash[1]; 1.249 ++ uint32_t C = hash[2]; 1.250 ++ uint32_t D = hash[3]; 1.251 ++ 1.252 ++ static const char S_array[] ALIGN1 = { 1.253 ++ 7, 12, 17, 22, 1.254 ++ 5, 9, 14, 20, 1.255 ++ 4, 11, 16, 23, 1.256 ++ 6, 10, 15, 21 1.257 ++ }; 1.258 ++ const uint32_t *pc; 1.259 ++ const char *pp; 1.260 ++ const char *ps; 1.261 ++ int i; 1.262 ++ uint32_t temp; 1.263 ++ 1.264 ++ 1.265 ++ pc = C_array; 1.266 ++ pp = P_array; 1.267 ++ ps = S_array - 4; 1.268 ++ 1.269 ++ for (i = 0; i < 64; i++) { 1.270 ++ if ((i & 0x0f) == 0) 1.271 ++ ps += 4; 1.272 ++ temp = A; 1.273 ++ switch (i >> 4) { 1.274 ++ case 0: 1.275 ++ temp += FF(B, C, D); 1.276 ++ break; 1.277 ++ case 1: 1.278 ++ temp += FG(B, C, D); 1.279 ++ break; 1.280 ++ case 2: 1.281 ++ temp += FH(B, C, D); 1.282 ++ break; 1.283 ++ case 3: 1.284 ++ temp += FI(B, C, D); 1.285 ++ } 1.286 ++ temp += words[(int) (*pp++)] + *pc++; 1.287 ++ temp = rotl32(temp, ps[i & 3]); 1.288 ++ temp += B; 1.289 ++ A = D; 1.290 ++ D = C; 1.291 ++ C = B; 1.292 ++ B = temp; 1.293 ++ } 1.294 ++ /* Add checksum to the starting values */ 1.295 ++ hash[0] += A; 1.296 ++ hash[1] += B; 1.297 ++ hash[2] += C; 1.298 ++ hash[3] += D; 1.299 ++ 1.300 ++} 1.301 ++#undef FF 1.302 ++#undef FG 1.303 ++#undef FH 1.304 ++#undef FI 1.305 ++ 1.306 ++/* Initialize structure containing state of computation. 1.307 ++ * (RFC 1321, 3.3: Step 3) 1.308 ++ */ 1.309 ++static void md5_begin(void) 1.310 ++{ 1.311 ++ hash[0] = 0x67452301; 1.312 ++ hash[1] = 0xefcdab89; 1.313 ++ hash[2] = 0x98badcfe; 1.314 ++ hash[3] = 0x10325476; 1.315 ++ total64 = 0; 1.316 ++} 1.317 ++ 1.318 ++/* Used also for sha1 and sha256 */ 1.319 ++#define md5_hash common64_hash 1.320 ++ 1.321 ++/* Process the remaining bytes in the buffer and put result from CTX 1.322 ++ * in first 16 bytes following RESBUF. The result is always in little 1.323 ++ * endian byte order, so that a byte-wise output yields to the wanted 1.324 ++ * ASCII representation of the message digest. 1.325 ++ */ 1.326 ++#define md5_end common64_end 1.327 ++ 1.328 ++typedef struct { char hash[16]; } md5hash; 1.329 ++ 1.330 ++static md5hash md5sum(uint8_t *buffer, int len) 1.331 ++{ 1.332 ++ md5hash val; 1.333 ++ 1.334 ++ md5_begin(); 1.335 ++ md5_hash(buffer, len); 1.336 ++ md5_end(); 1.337 ++ memcpy(&val, hash, 16); 1.338 ++ 1.339 ++ return val; 1.340 ++} 1.341 --- create_compressed_fs.c 1.342 +++ create_compressed_fs.c 1.343 -@@ -0,0 +1,148 @@ 1.344 +@@ -0,0 +1,203 @@ 1.345 +#ifdef FIND_BEST_COMPRESSION 1.346 +#include <compress.h> 1.347 +extern "C" { 1.348 @@ -400,6 +671,8 @@ 1.349 +#define compress2(a,b,c,d,e) best_compress(a,b,c,d) 1.350 +#endif 1.351 + 1.352 ++#include <signal.h> 1.353 ++ 1.354 +/* Creates a compressed file */ 1.355 +#include "common_header.h" 1.356 + 1.357 @@ -427,16 +700,49 @@ 1.358 + return i; 1.359 +} 1.360 + 1.361 ++#ifdef FIND_BEST_COMPRESSION 1.362 ++#include "md5sum.c" 1.363 ++#endif 1.364 ++ 1.365 ++static unsigned n; 1.366 ++static unsigned long lastlen, pos, *block_index; 1.367 ++static unsigned char *compressed; 1.368 ++static unsigned long block_size = 0; 1.369 ++static void flush_index(int sig) 1.370 ++{ 1.371 ++ static char padding[512]; 1.372 ++ struct cloop_tail tail; 1.373 ++ unsigned long len; 1.374 ++ 1.375 ++ fprintf(stderr, "Write index for %lu blocks\n", n); 1.376 ++ if (block_size >= 0x1000000) lastlen = 0; 1.377 ++ tail.index_size = ntohl(sizeof(*block_index) + 256*(lastlen % 0xFFffFF)); 1.378 ++ tail.num_blocks = ntohl(n); 1.379 ++ n *= sizeof(*block_index); 1.380 ++ len = n + n/1000 + 12; 1.381 ++ compressed = (unsigned char *) realloc(compressed, len); 1.382 ++ if (!compressed || compress2(compressed, &len, (unsigned char *) block_index, 1.383 ++ n, Z_BEST_SPEED) != Z_OK) 1.384 ++ quit("Index compression failed"); 1.385 ++ tail.table_size = ntohl(len); 1.386 ++ pos += len + sizeof(tail); 1.387 ++ n = pos & 511; 1.388 ++ if (n) write(STDOUT_FILENO, padding, 512 - n); 1.389 ++ write(STDOUT_FILENO, compressed, len); 1.390 ++ write(STDOUT_FILENO, &tail, sizeof(tail)); 1.391 ++ exit(sig != 0); 1.392 ++} 1.393 ++ 1.394 +int main(int argc, char *argv[]) 1.395 +{ 1.396 + struct cloop_head head; 1.397 -+ struct cloop_tail tail; 1.398 -+ unsigned long block_size = 0; 1.399 -+ unsigned char *compressed, *uncompressed; 1.400 -+ unsigned long *index; 1.401 -+ int n, indexmax, zlenmax; 1.402 -+ unsigned long lastlen, len, pos; 1.403 -+ static char padding[512]; 1.404 ++ unsigned char *uncompressed; 1.405 ++ unsigned long len; 1.406 ++ unsigned indexmax, zlenmax; 1.407 ++#ifdef FIND_BEST_COMPRESSION 1.408 ++ unsigned i, j, hashmax; 1.409 ++ md5hash *hash; 1.410 ++#endif 1.411 + 1.412 + if (argc > 1) { 1.413 + if (argv[1][0] < '0' || argv[1][0] > '9') 1.414 @@ -457,48 +763,67 @@ 1.415 + 1.416 + compressed = (unsigned char *) malloc(zlenmax); 1.417 + uncompressed = (unsigned char *) malloc(block_size); 1.418 -+ index = (unsigned long *) malloc(indexmax = CHUNK); 1.419 -+ if (!compressed || !uncompressed || !index) 1.420 ++ block_index = (unsigned long *) malloc(indexmax = CHUNK); 1.421 ++#ifdef FIND_BEST_COMPRESSION 1.422 ++ hash = (md5hash *) malloc(hashmax = CHUNK); 1.423 ++ if (!compressed || !uncompressed || !block_index || !hash) 1.424 ++#else 1.425 ++ if (!compressed || !uncompressed || !block_index) 1.426 ++#endif 1.427 + quit("Malloc failed"); 1.428 + 1.429 ++ signal(SIGINT,flush_index); 1.430 ++ signal(SIGQUIT,flush_index); 1.431 ++ signal(SIGTERM,flush_index); 1.432 ++ 1.433 + for (n = 0; (len = readblock(uncompressed, block_size)) != 0; n++) { 1.434 + lastlen = len; 1.435 -+ len = zlenmax; 1.436 -+ if (compress2(compressed, &len, uncompressed, block_size, 1.437 -+ Z_BEST_COMPRESSION) != Z_OK) 1.438 -+ quit("Compression failed"); 1.439 -+ fprintf(stderr, "Block %u length %lu => %lu\n", 1.440 -+ n, block_size, len); 1.441 -+ write(STDOUT_FILENO, compressed, len); 1.442 -+ pos += len; 1.443 -+ if (n * sizeof(*index) >= indexmax) { 1.444 -+ index = (unsigned long *) realloc(index, 1.445 ++ if (n * sizeof(*block_index) >= indexmax) { 1.446 ++ block_index = (unsigned long *) realloc(block_index, 1.447 + indexmax += CHUNK); 1.448 -+ if (!index) 1.449 ++ if (!block_index) 1.450 + quit("Realloc"); 1.451 + } 1.452 -+ index[n] = ntohl(len); 1.453 ++#ifdef FIND_BEST_COMPRESSION 1.454 ++ if (n * sizeof(*hash) >= hashmax) { 1.455 ++ hash = (md5hash *) realloc(hash, hashmax += CHUNK); 1.456 ++ if (!ihash) 1.457 ++ quit("Realloc hash"); 1.458 ++ } 1.459 ++ hash[n] = md5sum(uncompressed, len); 1.460 ++ j = 0x7FFFFFFF; 1.461 ++ if (n < j) 1.462 ++ j = n; 1.463 ++ for (i = 0; i < j; i++) { 1.464 ++ if (* (uint32_t *) &hash[i] == * (uint32_t *) &hash[n] 1.465 ++ && !memcmp(&hash[i],&hash[n],sizeof(*hash))) 1.466 ++ break; 1.467 ++ } 1.468 ++ if (i != j) { 1.469 ++ block_index[n] = ntohl(0x80000000 | i); 1.470 ++ fprintf(stderr, "Block %u length %lu => duplicate %lu\n", 1.471 ++ n, block_size, i); 1.472 ++ } 1.473 ++ else 1.474 ++#endif 1.475 ++ { 1.476 ++ len = zlenmax; 1.477 ++ if (compress2(compressed, &len, uncompressed, lastlen, 1.478 ++ Z_BEST_SPEED) != Z_OK) 1.479 ++ quit("Compression failed"); 1.480 ++ fprintf(stderr, "Block %u length %lu => %lu\n", 1.481 ++ n, block_size, len); 1.482 ++ write(STDOUT_FILENO, compressed, len); 1.483 ++ pos += len; 1.484 ++ block_index[n] = ntohl(len); 1.485 ++ } 1.486 + } 1.487 -+ tail.index_size = ntohl(sizeof(*index) + (lastlen & ~0x1FF)); 1.488 -+ tail.num_blocks = ntohl(n); 1.489 -+ n *= sizeof(*index); 1.490 -+ len = n + n/1000 + 12; 1.491 -+ compressed = (unsigned char *) realloc(compressed, len); 1.492 -+ if (!compressed || compress2(compressed, &len, (unsigned char *) index, 1.493 -+ n, Z_BEST_COMPRESSION) != Z_OK) 1.494 -+ quit("Index compression failed"); 1.495 -+ tail.table_size = ntohl(len); 1.496 -+ pos += len + sizeof(tail); 1.497 -+ n = pos & 511; 1.498 -+ if (n) write(STDOUT_FILENO, padding, 512 - n); 1.499 -+ write(STDOUT_FILENO, compressed, len); 1.500 -+ write(STDOUT_FILENO, &tail, sizeof(tail)); 1.501 ++ flush_index(0); 1.502 + return 0; 1.503 +} 1.504 +#ifdef FIND_BEST_COMPRESSION 1.505 +} 1.506 +#endif 1.507 - 1.508 --- fusecloop.c 1.509 +++ fusecloop.c 1.510 @@ -65,7 +65,7 @@