void *slice_read(const unsigned char *sha1, size_t *outsize) { struct slice_file *file = slice_file_read(sha1); struct strbuf buf = STRBUF_INIT; void *object; if (!file) goto err; *outsize = 0; for (uint32_t i = 0; i < file->nr_slices; i++) { size_t size; void *sbuf; sbuf = sha1_file_read(file->slices[i].sha1, &size); if (!sbuf) goto err; strbuf_add(&buf, sbuf, size); free(sbuf); *outsize += size; } object = xmalloc(*outsize); strbuf_copyout(&buf, object, *outsize); free(file); strbuf_release(&buf); return object; err: free(file); strbuf_release(&buf); return NULL; }
static void *retrieve_object_from_snap(uint64_t oid, int epoch) { struct sha1_file_hdr hdr; struct trunk_entry *trunk_buf, *trunk_free = NULL; unsigned char trunk_sha1[SHA1_LEN]; uint64_t nr_trunks, i; void *buffer = NULL; if (get_trunk_sha1(epoch, trunk_sha1, 0) < 0) goto out; trunk_free = trunk_buf = trunk_file_read(trunk_sha1, &hdr); if (!trunk_buf) goto out; nr_trunks = hdr.priv; for (i = 0; i < nr_trunks; i++, trunk_buf++) { struct sha1_file_hdr h; if (trunk_buf->oid != oid) continue; buffer = sha1_file_read(trunk_buf->sha1, &h); break; } out: dprintf("oid %"PRIx64", epoch %d, %s\n", oid, epoch, buffer ? "succeed" : "fail"); free(trunk_free); return buffer; }
static struct slice_file *slice_file_read(const unsigned char *sha1) { size_t size; struct slice_file *slice_file = NULL; void *buf = sha1_file_read(sha1, &size); if (!buf) return NULL; slice_file = xmalloc(sizeof(struct slice_file)); slice_file->nr_slices = size / SHA1_DIGEST_SIZE; slice_file->slices = buf; return slice_file; }
void *snap_file_read(unsigned char *sha1, struct sha1_file_hdr *outhdr) { void *buffer = NULL; dprintf("%s\n", sha1_to_hex(sha1)); buffer = sha1_file_read(sha1, outhdr); if (!buffer) return NULL; if (strcmp(outhdr->tag, TAG_SNAP) != 0) { free(buffer); return NULL; } return buffer; }
static int restore_objects_from_snap(uint32_t epoch) { struct sha1_file_hdr hdr; struct trunk_entry *trunk_buf, *trunk_free = NULL; unsigned char trunk_sha1[SHA1_LEN]; uint64_t nr_trunks, i; int ret = SD_RES_EIO; if (get_trunk_sha1(epoch, trunk_sha1) < 0) goto out; trunk_free = trunk_buf = trunk_file_read(trunk_sha1, &hdr); if (!trunk_buf) goto out; nr_trunks = hdr.priv; ret = SD_RES_SUCCESS; for (i = 0; i < nr_trunks; i++, trunk_buf++) { struct sha1_file_hdr h; struct siocb io = { 0 }; uint64_t oid; void *buffer = NULL; oid = trunk_buf->oid; buffer = sha1_file_read(trunk_buf->sha1, &h); if (!buffer) { sd_eprintf("oid %"PRIx64" not restored", oid); goto out; } io.length = h.size; io.buf = buffer; ret = default_create_and_write(oid, &io); if (ret != SD_RES_SUCCESS) { sd_eprintf("oid %"PRIx64" not restored", oid); goto out; } else sd_dprintf("oid %"PRIx64" restored", oid); free(buffer); } out: free(trunk_free); return ret; }
struct snap_file *snap_file_read(unsigned char *sha1) { size_t size; return sha1_file_read(sha1, &size); }