dedup

deduplicating backup program
git clone git://git.2f30.org/dedup
Log | Files | Refs | README | LICENSE

block.c (3126B)


      1 /* Top-level block layer implementation */
      2 #include <sys/types.h>
      3 #include <sys/stat.h>
      4 
      5 #include <fcntl.h>
      6 #include <stdint.h>
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <string.h>
     10 
     11 #include <sodium.h>
     12 
     13 #include "block.h"
     14 #include "config.h"
     15 #include "misc.h"
     16 
     17 static int
     18 bhash(void *buf, size_t n, unsigned char *md)
     19 {
     20 	return crypto_generichash(md, MDSIZE, buf, n, NULL, 0);
     21 }
     22 
     23 int
     24 bcreat(char *path, int mode, struct bctx **bctx)
     25 {
     26 	if (path == NULL || bctx == NULL) {
     27 		seterr("invalid params");
     28 		return -1;
     29 	}
     30 
     31 	if (sodium_init() < 0) {
     32 		seterr("sodium_init: failed");
     33 		return -1;
     34 	}
     35 
     36 	*bctx = calloc(1, sizeof(**bctx));
     37 	if (*bctx == NULL) {
     38 		seterr("calloc: out of memory");
     39 		return -1;
     40 	}
     41 
     42 	if (bcompressops()->creat(*bctx, path, mode) < 0) {
     43 		free(*bctx);
     44 		return -1;
     45 	}
     46 	return 0;
     47 }
     48 
     49 int
     50 bopen(char *path, int flags, int mode, struct bctx **bctx)
     51 {
     52 	if (path == NULL || bctx == NULL) {
     53 		seterr("invalid params");
     54 		return -1;
     55 	}
     56 
     57 	if (sodium_init() < 0) {
     58 		seterr("sodium_init: failed");
     59 		return -1;
     60 	}
     61 
     62 	*bctx = calloc(1, sizeof(**bctx));
     63 	if (*bctx == NULL) {
     64 		seterr("calloc: out of memory");
     65 		return -1;
     66 	}
     67 
     68 	if (bcompressops()->open(*bctx, path, flags, mode) < 0) {
     69 		free(*bctx);
     70 		return -1;
     71 	}
     72 	return 0;
     73 }
     74 
     75 int
     76 bput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
     77 {
     78 	if (bctx == NULL || buf == NULL || n == 0 || md == NULL) {
     79 		seterr("invalid params");
     80 		return -1;
     81 	}
     82 
     83 	if (bhash(buf, n, md) < 0) {
     84 		seterr("bhash: failed");
     85 		return -1;
     86 	}
     87 
     88 	return bcompressops()->put(bctx, buf, n, md);
     89 }
     90 
     91 int
     92 bget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n)
     93 {
     94 	if (bctx == NULL || md == NULL || buf == NULL || n == NULL) {
     95 		seterr("invalid params");
     96 		return -1;
     97 	}
     98 
     99 	return bcompressops()->get(bctx, md, buf, n);
    100 }
    101 
    102 int
    103 brm(struct bctx *bctx, unsigned char *md)
    104 {
    105 	if (bctx == NULL || md == NULL) {
    106 		seterr("invalid params");
    107 		return -1;
    108 	}
    109 
    110 	return bcompressops()->rm(bctx, md);
    111 }
    112 
    113 int
    114 bgc(struct bctx *bctx)
    115 {
    116 	if (bctx == NULL) {
    117 		seterr("invalid params");
    118 		return -1;
    119 	}
    120 
    121 	return bcompressops()->gc(bctx);
    122 }
    123 
    124 /*
    125  * Lookup the block given the hash and rehash it.
    126  * Check that the hashes match.  It returns -1
    127  * on error, 0 on success and 1 if a block hash
    128  * mismatch is detected.
    129  */
    130 int
    131 bcheck(struct bctx *bctx, unsigned char *md)
    132 {
    133 	unsigned char tmp[MDSIZE];
    134 	void *buf;
    135 	size_t n;
    136 
    137 	if (bctx == NULL || md == NULL) {
    138 		seterr("invalid params");
    139 		return -1;
    140 	}
    141 
    142 	buf = malloc(BSIZEMAX);
    143 	if (buf == NULL) {
    144 		seterr("malloc: out of memory");
    145 		return -1;
    146 	}
    147 	n = BSIZEMAX;
    148 
    149 	if (bcompressops()->get(bctx, md, buf, &n) < 0) {
    150 		free(buf);
    151 		return -1;
    152 	}
    153 
    154 	if (bhash(buf, n, tmp) < 0) {
    155 		free(buf);
    156 		seterr("bhash: failed");
    157 		return -1;
    158 	}
    159 
    160 	free(buf);
    161 
    162 	if (memcmp(tmp, md, MDSIZE) != 0)
    163 		return 1;
    164 	return 0;
    165 }
    166 
    167 int
    168 bsync(struct bctx *bctx)
    169 {
    170 	if (bctx == NULL) {
    171 		seterr("invalid params");
    172 		return -1;
    173 	}
    174 
    175 	return bcompressops()->sync(bctx);
    176 }
    177 
    178 int
    179 bclose(struct bctx *bctx)
    180 {
    181 	int r;
    182 
    183 	if (bctx == NULL) {
    184 		seterr("invalid params");
    185 		return -1;
    186 	}
    187 
    188 	if (bsync(bctx) < 0)
    189 		return -1;
    190 	r = bcompressops()->close(bctx);
    191 	free(bctx);
    192 	return r;
    193 }