int init_hash(void) { /* * Version check should be the very first call because it makes sure * that important subsystems are intialized. */ if (!gcry_check_version(GCRYPT_VERSION)) return 1; /* Disable secure memory. */ gcry_control(GCRYCTL_DISABLE_SECMEM, 0); /* Tell Libgcrypt that initialization has completed. */ gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); if (gcry_md_test_algo(HASH_FUNC)) return 1; digest_len = gcry_md_get_algo_dlen(HASH_FUNC); if (!digest_len) return 1; abort_on(digest_len == 0 || digest_len > DIGEST_LEN_MAX); return 0; }
int init_csum_module(const char *type) { int ret; struct csum_module *m = modules[0]; int i = 0; while (m) { if (strcasecmp(type, m->name) == 0) break; m = modules[++i]; } if (!m) return EINVAL; csum_mod = m; strncpy(hash_type, csum_mod->hash_type, 8); ret = csum_mod->ops->init(&digest_len); if (ret) return ret; abort_on(digest_len == 0 || digest_len > DIGEST_LEN_MAX); if (csum_mod != &csum_module_sha256) fprintf(stderr, "Warning: %s support is experimental!\n", csum_mod->name); return 0; }
int init_csum_module(const char *type) { int ret; struct csum_module *m = modules[0]; int i = 0; while (m) { if (strcasecmp(type, m->name) == 0) break; m = modules[++i]; } if (!m) return EINVAL; csum_mod = m; strncpy(hash_type, csum_mod->hash_type, 8); ret = csum_mod->ops->init(&digest_len); if (ret) return ret; abort_on(digest_len == 0 || digest_len > DIGEST_LEN_MAX); return 0; }
static unsigned int remove_extent(struct results_tree *res, struct extent *extent) { struct dupe_extents *p = extent->e_parent; struct rb_node *n; unsigned int result; again: p->de_score -= p->de_len; p->de_num_dupes--; result = p->de_num_dupes; list_del_init(&extent->e_list); list_del_init(&extent->e_file_extents); rb_erase(&extent->e_node, &p->de_extents_root); free_extent(extent); if (p->de_num_dupes == 1) { /* It doesn't make sense to have one extent in a dup * list. */ abort_on(RB_EMPTY_ROOT(&p->de_extents_root));/* logic error */ n = rb_first(&p->de_extents_root); extent = rb_entry(n, struct extent, e_node); goto again; }
void debug_print_digest_len(FILE *stream, unsigned char *digest, int len) { uint32_t i; abort_on(len > digest_len); for (i = 0; i < len; i++) fprintf(stream, "%.2x", digest[i]); }
int insert_result(struct results_tree *res, unsigned char *digest, struct filerec *recs[2], uint64_t startoff[2], uint64_t endoff[2]) { struct extent *e0 = alloc_extent(recs[0], startoff[0]); struct extent *e1 = alloc_extent(recs[1], startoff[1]); struct dupe_extents *dext; uint64_t len = endoff[0] - startoff[0]; int add_score = 1; if (!e0 || !e1) return ENOMEM; dext = find_dupe_extents(res, digest, len); if (!dext) { dext = dupe_extents_new(res, digest, len); if (!dext) return ENOMEM; add_score = 0; } abort_on(dext->de_len != len); insert_extent_list_free(dext, &e0); insert_extent_list_free(dext, &e1); if (e0) { if (add_score) dext->de_score += len; e0->e_itnode.start = e0->e_loff; e0->e_itnode.last = extent_end(e0); interval_tree_insert(&e0->e_itnode, &recs[0]->extent_tree); #ifdef ITDEBUG recs[0]->num_extents++; #endif } if (e1) { if (add_score) dext->de_score += len; e1->e_itnode.start = e1->e_loff; e1->e_itnode.last = extent_end(e1); interval_tree_insert(&e1->e_itnode, &recs[1]->extent_tree); #ifdef ITDEBUG recs[1]->num_extents++; #endif } return 0; }
void digest_free(struct rb_root *root) { struct rb_node *n = rb_first(root); struct d_tree *t; while (n) { t = rb_entry(n, struct d_tree, t_node); n = rb_next(n); rb_erase(&t->t_node, root); free(t->digest); free(t); } abort_on(!RB_EMPTY_ROOT(root)); }
int insert_result(struct results_tree *res, unsigned char *digest, struct filerec *recs[2], uint64_t startoff[2], uint64_t endoff[2]) { struct extent *e0 = alloc_extent(recs[0], startoff[0]); struct extent *e1 = alloc_extent(recs[1], startoff[1]); struct dupe_extents *dext; uint64_t len = endoff[0] - startoff[0]; int add_score = 1; if (!e0 || !e1) return ENOMEM; dext = find_dupe_extents(res, digest, len); if (!dext) { dext = dupe_extents_new(res, digest, len); if (!dext) return ENOMEM; add_score = 0; } abort_on(dext->de_len != len); insert_extent_list_free(dext, &e0); insert_extent_list_free(dext, &e1); if (e0) { if (add_score) dext->de_score += len; list_add_tail(&e0->e_file_extents, &recs[0]->extent_list); } if (e1) { if (add_score) dext->de_score += len; list_add_tail(&e1->e_file_extents, &recs[1]->extent_list); } return 0; }
/* * This does not do all the work of insert_result(), just enough for * the dedupe phase of block-dedupe to work properly. */ int insert_one_result(struct results_tree *res, unsigned char *digest, struct filerec *file, uint64_t startoff, uint64_t len) { struct extent *extent = alloc_extent(file, startoff); struct dupe_extents *dext; if (!extent) return ENOMEM; dext = find_dupe_extents(res, digest, len); if (!dext) { dext = dupe_extents_new(res, digest, len); if (!dext) return ENOMEM; } abort_on(dext->de_len != len); insert_extent_list_free(dext, &extent); return 0; }