int dbfile_read_all_hashes(struct hash_tree *tree) { int ret; sqlite3 *db; sqlite3_stmt *stmt = NULL; char *filename; uint64_t ino, subvolid, size; struct filerec *file; db = dbfile_get_handle(); if (!db) return ENOENT; ret = dbfile_check_version(db); if (ret) return ret; ret = sqlite3_prepare_v2(db, "SELECT ino, subvol, filename, size from files;", -1, &stmt, NULL); if (ret) { perror_sqlite(ret, "preparing statement"); return ret; } while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) { ino = sqlite3_column_int64(stmt, 0); subvolid = sqlite3_column_int64(stmt, 1); filename = (char *)sqlite3_column_text(stmt, 2); size = sqlite3_column_int64(stmt, 3); file = filerec_new(filename, ino, subvolid, size); if (!file) { ret = ENOMEM; goto out_finalize; } ret = dbfile_walk_file_hashes(db, file, load_into_hash_tree_cb, tree); if (ret) goto out_finalize; } if (ret != SQLITE_DONE) { perror_sqlite(ret, "retrieving hashes from table"); ret = EIO; goto out_finalize; } ret = 0; out_finalize: sqlite3_finalize(stmt); return ret; }
int dbfile_sync_config(unsigned int block_size) { sqlite3 *db; int ret; db = dbfile_get_handle(); if (!db) return ENOENT; ret = __dbfile_sync_config(db, block_size); return ret; }
int dbfile_load_hashes_bloom(struct hash_tree *hash_tree, struct rb_root *d_tree) { int ret; struct rb_node *d_hash_node = rb_first(d_tree); struct d_tree *d_hash; sqlite3 *db; sqlite3_stmt *stmt = NULL; uint64_t subvol, ino, loff; int flags; struct filerec *file; db = dbfile_get_handle(); if (!db) return ENOENT; ret = sqlite3_prepare_v2(db, "SELECT ino, subvol, loff, flags FROM hashes WHERE digest = ?1;", -1, &stmt, NULL); if (ret) { perror_sqlite(ret, "preparing statement"); return ret; } for (d_hash_node = rb_first(d_tree); d_hash_node; d_hash_node = rb_next(d_hash_node)) { d_hash = rb_entry(d_hash_node, struct d_tree, t_node); /* * XXX: Using SQLITE_STATIC here because it's probably * faster. If we ever free items from d_tree, we need * to change that. */ ret = sqlite3_bind_blob(stmt, 1, d_hash->digest, digest_len, SQLITE_STATIC); if (ret) { perror_sqlite(ret, "looking up hash (bind)"); goto out; } while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) { ino = sqlite3_column_int64(stmt, 0); subvol = sqlite3_column_int64(stmt, 1); loff = sqlite3_column_int64(stmt, 2); flags = sqlite3_column_int(stmt, 3); file = filerec_find(ino, subvol); if (!file) { ret = ENOENT; fprintf(stderr, "Filerec (%"PRIu64",%"PRIu64" is in db" " but not in hash!\n", ino, subvol); goto out; } ret = insert_hashed_block(hash_tree, d_hash->digest, file, loff, flags); if (ret) return ENOMEM; } if (ret != SQLITE_DONE) { perror_sqlite(ret, "looking up hash"); goto out; } sqlite3_reset(stmt); } ret = 0; out: if (stmt) sqlite3_finalize(stmt); return ret; }
int dbfile_populate_hashes(struct rb_root *d_tree) { int ret; sqlite3 *db; sqlite3_stmt *stmt = NULL; char *filename; uint64_t ino, subvolid; uint64_t num_hashes; struct filerec *file; struct bloom_cb_priv priv; db = dbfile_get_handle(); if (!db) return ENOENT; ret = dbfile_count_rows(db, &num_hashes, NULL); if (ret) return ret; priv.d_tree = d_tree; ret = bloom_init(&priv.bloom, num_hashes, 0.01); if (ret) return ret; ret = sqlite3_prepare_v2(db, "SELECT ino, subvol, filename from files;", -1, &stmt, NULL); if (ret) { perror_sqlite(ret, "preparing statement"); goto out_bloom; } while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) { ino = sqlite3_column_int64(stmt, 0); subvolid = sqlite3_column_int64(stmt, 1); filename = (char *)sqlite3_column_text(stmt, 2); file = filerec_new(filename, ino, subvolid); if (!file) { ret = ENOMEM; goto out_finalize; } ret = dbfile_walk_file_hashes(db, file, load_into_bloom_cb, &priv); if (ret) goto out_finalize; } if (ret != SQLITE_DONE) { perror_sqlite(ret, "retrieving file info from table"); goto out_finalize; } ret = 0; out_finalize: sqlite3_finalize(stmt); out_bloom: bloom_free(&priv.bloom); return ret; }