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 }