ibcompress.c - dedup - deduplicating backup program Err bitreich.org 70 hgit clone git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/ URL:git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/ bitreich.org 70 1Log /scm/dedup/log.gph bitreich.org 70 1Files /scm/dedup/files.gph bitreich.org 70 1Refs /scm/dedup/refs.gph bitreich.org 70 1Tags /scm/dedup/tag bitreich.org 70 1README /scm/dedup/file/README.gph bitreich.org 70 1LICENSE /scm/dedup/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 ibcompress.c (6415B) Err bitreich.org 70 i--- Err bitreich.org 70 i 1 /* Compression layer implementation */ Err bitreich.org 70 i 2 #include Err bitreich.org 70 i 3 #include Err bitreich.org 70 i 4 Err bitreich.org 70 i 5 #include Err bitreich.org 70 i 6 #include Err bitreich.org 70 i 7 #include Err bitreich.org 70 i 8 #include Err bitreich.org 70 i 9 #include Err bitreich.org 70 i 10 #include Err bitreich.org 70 i 11 #include Err bitreich.org 70 i 12 #include Err bitreich.org 70 i 13 Err bitreich.org 70 i 14 #include Err bitreich.org 70 i 15 #include Err bitreich.org 70 i 16 Err bitreich.org 70 i 17 #include "block.h" Err bitreich.org 70 i 18 #include "config.h" Err bitreich.org 70 i 19 #include "misc.h" Err bitreich.org 70 i 20 #include "state.h" Err bitreich.org 70 i 21 Err bitreich.org 70 i 22 #define CDNONETYPE 0x200 Err bitreich.org 70 i 23 #define CDSNAPPYTYPE 0x201 Err bitreich.org 70 i 24 #define CDLZ4TYPE 0x202 Err bitreich.org 70 i 25 #define CDSIZE (8 + 8) Err bitreich.org 70 i 26 Err bitreich.org 70 i 27 extern struct param param; Err bitreich.org 70 i 28 Err bitreich.org 70 i 29 extern int pack(unsigned char *, char *, ...); Err bitreich.org 70 i 30 extern int unpack(unsigned char *, char *, ...); Err bitreich.org 70 i 31 Err bitreich.org 70 i 32 static int bccreat(struct bctx *bctx, char *path, int mode); Err bitreich.org 70 i 33 static int bcopen(struct bctx *bctx, char *path, int flags, int mode); Err bitreich.org 70 i 34 static int bcput(struct bctx *bctx, void *buf, size_t n, unsigned char *md); Err bitreich.org 70 i 35 static int bcget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n); Err bitreich.org 70 i 36 static int bcrm(struct bctx *bctx, unsigned char *md); Err bitreich.org 70 i 37 static int bcgc(struct bctx *bctx); Err bitreich.org 70 i 38 static int bcsync(struct bctx *bctx); Err bitreich.org 70 i 39 static int bcclose(struct bctx *bctx); Err bitreich.org 70 i 40 Err bitreich.org 70 i 41 static struct bops bops = { Err bitreich.org 70 i 42 .creat = bccreat, Err bitreich.org 70 i 43 .open = bcopen, Err bitreich.org 70 i 44 .put = bcput, Err bitreich.org 70 i 45 .get = bcget, Err bitreich.org 70 i 46 .rm = bcrm, Err bitreich.org 70 i 47 .gc = bcgc, Err bitreich.org 70 i 48 .sync = bcsync, Err bitreich.org 70 i 49 .close = bcclose, Err bitreich.org 70 i 50 }; Err bitreich.org 70 i 51 Err bitreich.org 70 i 52 /* Compression layer context */ Err bitreich.org 70 i 53 struct cctx { Err bitreich.org 70 i 54 int type; /* compression algorithm type for new blocks */ Err bitreich.org 70 i 55 }; Err bitreich.org 70 i 56 Err bitreich.org 70 i 57 /* Compression descriptor */ Err bitreich.org 70 i 58 struct cd { Err bitreich.org 70 i 59 uint16_t type; /* compression algorithm type */ Err bitreich.org 70 i 60 unsigned char reserved[6]; /* should be set to 0 when writing */ Err bitreich.org 70 i 61 uint64_t size; /* size of compressed block */ Err bitreich.org 70 i 62 }; Err bitreich.org 70 i 63 Err bitreich.org 70 i 64 /* Unpack compression descriptor */ Err bitreich.org 70 i 65 static int Err bitreich.org 70 i 66 unpackcd(void *buf, struct cd *cd) Err bitreich.org 70 i 67 { Err bitreich.org 70 i 68 int n; Err bitreich.org 70 i 69 Err bitreich.org 70 i 70 n = unpack(buf, "s'6q", Err bitreich.org 70 i 71 &cd->type, Err bitreich.org 70 i 72 cd->reserved, Err bitreich.org 70 i 73 &cd->size); Err bitreich.org 70 i 74 Err bitreich.org 70 i 75 assert(n == CDSIZE); Err bitreich.org 70 i 76 return n; Err bitreich.org 70 i 77 } Err bitreich.org 70 i 78 Err bitreich.org 70 i 79 /* Pack compression descriptor */ Err bitreich.org 70 i 80 static int Err bitreich.org 70 i 81 packcd(void *buf, struct cd *cd) Err bitreich.org 70 i 82 { Err bitreich.org 70 i 83 int n; Err bitreich.org 70 i 84 Err bitreich.org 70 i 85 n = pack(buf, "s'6q", Err bitreich.org 70 i 86 cd->type, Err bitreich.org 70 i 87 cd->reserved, Err bitreich.org 70 i 88 cd->size); Err bitreich.org 70 i 89 Err bitreich.org 70 i 90 assert(n == CDSIZE); Err bitreich.org 70 i 91 return n; Err bitreich.org 70 i 92 } Err bitreich.org 70 i 93 Err bitreich.org 70 i 94 static int Err bitreich.org 70 i 95 bccreat(struct bctx *bctx, char *path, int mode) Err bitreich.org 70 i 96 { Err bitreich.org 70 i 97 struct cctx *cctx; Err bitreich.org 70 i 98 int type; Err bitreich.org 70 i 99 Err bitreich.org 70 i 100 if (strcasecmp(param.calgo, "none") == 0) { Err bitreich.org 70 i 101 type = CDNONETYPE; Err bitreich.org 70 i 102 } else if (strcasecmp(param.calgo, "snappy") == 0) { Err bitreich.org 70 i 103 type = CDSNAPPYTYPE; Err bitreich.org 70 i 104 } else if (strcasecmp(param.calgo, "lz4") == 0) { Err bitreich.org 70 i 105 type = CDLZ4TYPE; Err bitreich.org 70 i 106 } else { Err bitreich.org 70 i 107 seterr("invalid compression type: %s", param.calgo); Err bitreich.org 70 i 108 return -1; Err bitreich.org 70 i 109 } Err bitreich.org 70 i 110 Err bitreich.org 70 i 111 bctx->cctx = calloc(1, sizeof(struct cctx)); Err bitreich.org 70 i 112 if (bctx->cctx == NULL) { Err bitreich.org 70 i 113 seterr("calloc: out of memory"); Err bitreich.org 70 i 114 return -1; Err bitreich.org 70 i 115 } Err bitreich.org 70 i 116 cctx = bctx->cctx; Err bitreich.org 70 i 117 cctx->type = type; Err bitreich.org 70 i 118 Err bitreich.org 70 i 119 if (bencryptops()->creat(bctx, path, mode) < 0) { Err bitreich.org 70 i 120 free(cctx); Err bitreich.org 70 i 121 return -1; Err bitreich.org 70 i 122 } Err bitreich.org 70 i 123 return 0; Err bitreich.org 70 i 124 } Err bitreich.org 70 i 125 Err bitreich.org 70 i 126 static int Err bitreich.org 70 i 127 bcopen(struct bctx *bctx, char *path, int flags, int mode) Err bitreich.org 70 i 128 { Err bitreich.org 70 i 129 struct cctx *cctx; Err bitreich.org 70 i 130 int type; Err bitreich.org 70 i 131 Err bitreich.org 70 i 132 if (strcasecmp(param.calgo, "none") == 0) { Err bitreich.org 70 i 133 type = CDNONETYPE; Err bitreich.org 70 i 134 } else if (strcasecmp(param.calgo, "snappy") == 0) { Err bitreich.org 70 i 135 type = CDSNAPPYTYPE; Err bitreich.org 70 i 136 } else if (strcasecmp(param.calgo, "lz4") == 0) { Err bitreich.org 70 i 137 type = CDLZ4TYPE; Err bitreich.org 70 i 138 } else { Err bitreich.org 70 i 139 seterr("invalid compression type: %s", param.calgo); Err bitreich.org 70 i 140 return -1; Err bitreich.org 70 i 141 } Err bitreich.org 70 i 142 Err bitreich.org 70 i 143 bctx->cctx = calloc(1, sizeof(struct cctx)); Err bitreich.org 70 i 144 if (bctx->cctx == NULL) { Err bitreich.org 70 i 145 seterr("calloc: out of memory"); Err bitreich.org 70 i 146 return -1; Err bitreich.org 70 i 147 } Err bitreich.org 70 i 148 cctx = bctx->cctx; Err bitreich.org 70 i 149 cctx->type = type; Err bitreich.org 70 i 150 Err bitreich.org 70 i 151 if (bencryptops()->open(bctx, path, flags, mode) < 0) { Err bitreich.org 70 i 152 free(cctx); Err bitreich.org 70 i 153 return -1; Err bitreich.org 70 i 154 } Err bitreich.org 70 i 155 return 0; Err bitreich.org 70 i 156 } Err bitreich.org 70 i 157 Err bitreich.org 70 i 158 static int Err bitreich.org 70 i 159 bcput(struct bctx *bctx, void *buf, size_t n, unsigned char *md) Err bitreich.org 70 i 160 { Err bitreich.org 70 i 161 struct cctx *cctx; Err bitreich.org 70 i 162 struct cd cd; Err bitreich.org 70 i 163 char *cbuf; Err bitreich.org 70 i 164 size_t cn; Err bitreich.org 70 i 165 int r; Err bitreich.org 70 i 166 Err bitreich.org 70 i 167 /* Calculate compressed block size */ Err bitreich.org 70 i 168 cctx = bctx->cctx; Err bitreich.org 70 i 169 switch (cctx->type) { Err bitreich.org 70 i 170 case CDNONETYPE: Err bitreich.org 70 i 171 cn = n; Err bitreich.org 70 i 172 break; Err bitreich.org 70 i 173 case CDSNAPPYTYPE: Err bitreich.org 70 i 174 cn = snappy_max_compressed_length(n); Err bitreich.org 70 i 175 break; Err bitreich.org 70 i 176 case CDLZ4TYPE: Err bitreich.org 70 i 177 cn = LZ4_compressBound(n); Err bitreich.org 70 i 178 break; Err bitreich.org 70 i 179 } Err bitreich.org 70 i 180 Err bitreich.org 70 i 181 cbuf = malloc(CDSIZE + cn); Err bitreich.org 70 i 182 if (cbuf == NULL) { Err bitreich.org 70 i 183 seterr("malloc: out of memory"); Err bitreich.org 70 i 184 return -1; Err bitreich.org 70 i 185 } Err bitreich.org 70 i 186 Err bitreich.org 70 i 187 /* Compress block */ Err bitreich.org 70 i 188 switch (cctx->type) { Err bitreich.org 70 i 189 case CDNONETYPE: Err bitreich.org 70 i 190 memcpy(&cbuf[CDSIZE], buf, cn); Err bitreich.org 70 i 191 break; Err bitreich.org 70 i 192 case CDSNAPPYTYPE: Err bitreich.org 70 i 193 if (snappy_compress(buf, n, &cbuf[CDSIZE], &cn) != SNAPPY_OK) { Err bitreich.org 70 i 194 free(cbuf); Err bitreich.org 70 i 195 seterr("snappy_compress: failed"); Err bitreich.org 70 i 196 return -1; Err bitreich.org 70 i 197 } Err bitreich.org 70 i 198 break; Err bitreich.org 70 i 199 case CDLZ4TYPE: Err bitreich.org 70 i 200 r = LZ4_compress_default(buf, &cbuf[CDSIZE], n, cn); Err bitreich.org 70 i 201 if (r < 0) { Err bitreich.org 70 i 202 free(cbuf); Err bitreich.org 70 i 203 seterr("LZ4_compress_default: failed"); Err bitreich.org 70 i 204 return -1; Err bitreich.org 70 i 205 } Err bitreich.org 70 i 206 cn = r; Err bitreich.org 70 i 207 break; Err bitreich.org 70 i 208 } Err bitreich.org 70 i 209 Err bitreich.org 70 i 210 /* Prepare compression descriptor */ Err bitreich.org 70 i 211 cd.type = cctx->type; Err bitreich.org 70 i 212 memset(cd.reserved, 0, sizeof(cd.reserved)); Err bitreich.org 70 i 213 cd.size = cn; Err bitreich.org 70 i 214 /* Prepend compression descriptor */ Err bitreich.org 70 i 215 packcd(cbuf, &cd); Err bitreich.org 70 i 216 Err bitreich.org 70 i 217 if (bencryptops()->put(bctx, cbuf, CDSIZE + cn, md) < 0) { Err bitreich.org 70 i 218 free(cbuf); Err bitreich.org 70 i 219 return -1; Err bitreich.org 70 i 220 } Err bitreich.org 70 i 221 Err bitreich.org 70 i 222 free(cbuf); Err bitreich.org 70 i 223 return cd.size; Err bitreich.org 70 i 224 } Err bitreich.org 70 i 225 Err bitreich.org 70 i 226 static int Err bitreich.org 70 i 227 bcget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n) Err bitreich.org 70 i 228 { Err bitreich.org 70 i 229 struct cd cd; Err bitreich.org 70 i 230 char *cbuf; Err bitreich.org 70 i 231 size_t cn, un, size; Err bitreich.org 70 i 232 int r; Err bitreich.org 70 i 233 Err bitreich.org 70 i 234 /* Calculate maximum compressed block size */ Err bitreich.org 70 i 235 size = *n; Err bitreich.org 70 i 236 cn = snappy_max_compressed_length(*n); Err bitreich.org 70 i 237 if (cn > size) Err bitreich.org 70 i 238 size = cn; Err bitreich.org 70 i 239 cn = LZ4_compressBound(*n); Err bitreich.org 70 i 240 if (cn > size) Err bitreich.org 70 i 241 size = cn; Err bitreich.org 70 i 242 size += CDSIZE; Err bitreich.org 70 i 243 Err bitreich.org 70 i 244 cbuf = malloc(size); Err bitreich.org 70 i 245 if (cbuf == NULL) { Err bitreich.org 70 i 246 seterr("malloc: out of memory"); Err bitreich.org 70 i 247 return -1; Err bitreich.org 70 i 248 } Err bitreich.org 70 i 249 Err bitreich.org 70 i 250 if (bencryptops()->get(bctx, md, cbuf, &size) < 0) { Err bitreich.org 70 i 251 free(cbuf); Err bitreich.org 70 i 252 return -1; Err bitreich.org 70 i 253 } Err bitreich.org 70 i 254 Err bitreich.org 70 i 255 unpackcd(cbuf, &cd); Err bitreich.org 70 i 256 Err bitreich.org 70 i 257 /* Decompress block */ Err bitreich.org 70 i 258 switch (cd.type) { Err bitreich.org 70 i 259 case CDNONETYPE: Err bitreich.org 70 i 260 un = cd.size; Err bitreich.org 70 i 261 if (*n < un) { Err bitreich.org 70 i 262 free(cbuf); Err bitreich.org 70 i 263 seterr("buffer too small"); Err bitreich.org 70 i 264 return -1; Err bitreich.org 70 i 265 } Err bitreich.org 70 i 266 memcpy(buf, &cbuf[CDSIZE], un); Err bitreich.org 70 i 267 break; Err bitreich.org 70 i 268 case CDSNAPPYTYPE: Err bitreich.org 70 i 269 if (snappy_uncompressed_length(&cbuf[CDSIZE], cd.size, Err bitreich.org 70 i 270 &un) != SNAPPY_OK) { Err bitreich.org 70 i 271 free(cbuf); Err bitreich.org 70 i 272 seterr("snappy_uncompressed_length: failed"); Err bitreich.org 70 i 273 return -1; Err bitreich.org 70 i 274 } Err bitreich.org 70 i 275 Err bitreich.org 70 i 276 if (*n < un) { Err bitreich.org 70 i 277 free(cbuf); Err bitreich.org 70 i 278 seterr("buffer too small"); Err bitreich.org 70 i 279 return -1; Err bitreich.org 70 i 280 } Err bitreich.org 70 i 281 Err bitreich.org 70 i 282 if (snappy_uncompress(&cbuf[CDSIZE], cd.size, buf, Err bitreich.org 70 i 283 &un) != SNAPPY_OK) { Err bitreich.org 70 i 284 free(cbuf); Err bitreich.org 70 i 285 seterr("snappy_uncompress: failed"); Err bitreich.org 70 i 286 return -1; Err bitreich.org 70 i 287 } Err bitreich.org 70 i 288 break; Err bitreich.org 70 i 289 case CDLZ4TYPE: Err bitreich.org 70 i 290 r = LZ4_decompress_safe(&cbuf[CDSIZE], buf, cd.size, *n); Err bitreich.org 70 i 291 if (r < 0) { Err bitreich.org 70 i 292 free(cbuf); Err bitreich.org 70 i 293 seterr("LZ4_decompress_safe: failed"); Err bitreich.org 70 i 294 return -1; Err bitreich.org 70 i 295 } Err bitreich.org 70 i 296 un = r; Err bitreich.org 70 i 297 break; Err bitreich.org 70 i 298 } Err bitreich.org 70 i 299 Err bitreich.org 70 i 300 free(cbuf); Err bitreich.org 70 i 301 *n = un; Err bitreich.org 70 i 302 return 0; Err bitreich.org 70 i 303 } Err bitreich.org 70 i 304 Err bitreich.org 70 i 305 static int Err bitreich.org 70 i 306 bcrm(struct bctx *bctx, unsigned char *md) Err bitreich.org 70 i 307 { Err bitreich.org 70 i 308 return bencryptops()->rm(bctx, md); Err bitreich.org 70 i 309 } Err bitreich.org 70 i 310 Err bitreich.org 70 i 311 static int Err bitreich.org 70 i 312 bcgc(struct bctx *bctx) Err bitreich.org 70 i 313 { Err bitreich.org 70 i 314 return bencryptops()->gc(bctx); Err bitreich.org 70 i 315 } Err bitreich.org 70 i 316 Err bitreich.org 70 i 317 static int Err bitreich.org 70 i 318 bcsync(struct bctx *bctx) Err bitreich.org 70 i 319 { Err bitreich.org 70 i 320 return bencryptops()->sync(bctx); Err bitreich.org 70 i 321 } Err bitreich.org 70 i 322 Err bitreich.org 70 i 323 static int Err bitreich.org 70 i 324 bcclose(struct bctx *bctx) Err bitreich.org 70 i 325 { Err bitreich.org 70 i 326 struct cctx *cctx = bctx->cctx; Err bitreich.org 70 i 327 Err bitreich.org 70 i 328 free(cctx); Err bitreich.org 70 i 329 return bencryptops()->close(bctx); Err bitreich.org 70 i 330 } Err bitreich.org 70 i 331 Err bitreich.org 70 i 332 struct bops * Err bitreich.org 70 i 333 bcompressops(void) Err bitreich.org 70 i 334 { Err bitreich.org 70 i 335 return &bops; Err bitreich.org 70 i 336 } Err bitreich.org 70 .