static int actual_restore(struct asfd *asfd, struct bu *bu, const char *manifest, regex_t *regex, int srestore, enum action act, struct sdirs *sdirs, enum cntr_status cntr_status, struct conf **cconfs) { int ret=-1; int do_restore_stream=1; // For out-of-sequence directory restoring so that the // timestamps come out right: struct slist *slist=NULL; if(linkhash_init() || !(slist=slist_alloc())) goto end; if(get_protocol(cconfs)==PROTO_2) { switch(maybe_restore_spool(asfd, manifest, sdirs, bu, srestore, regex, cconfs, slist, act, cntr_status)) { case 1: do_restore_stream=0; break; case 0: do_restore_stream=1; break; default: goto end; // Error; } } if(do_restore_stream && restore_stream(asfd, sdirs, slist, bu, manifest, regex, srestore, cconfs, act, cntr_status)) goto end; if(restore_remaining_dirs(asfd, bu, slist, act, sdirs, cntr_status, cconfs)) goto end; // Restore has nearly completed OK. ret=restore_end(asfd, cconfs); cntr_print(get_cntr(cconfs), act); cntr_stats_to_file(get_cntr(cconfs), bu->path, act, cconfs); end: slist_free(&slist); linkhash_free(); return ret; }
static void setup_restore(u32 *ptr, u32 waitbase) { const struct hwctx_reginfo *r; const struct hwctx_reginfo *rend; restore_begin(ptr, waitbase); ptr += RESTORE_BEGIN_SIZE; r = ctxsave_regs_3d; rend = ctxsave_regs_3d + ARRAY_SIZE(ctxsave_regs_3d); for ( ; r != rend; ++r) { u32 offset = r->offset; u32 count = r->count; switch (r->type) { case HWCTX_REGINFO_DIRECT: restore_direct(ptr, offset, count); ptr += RESTORE_DIRECT_SIZE; break; case HWCTX_REGINFO_INDIRECT: restore_indoffset(ptr, offset, 0); ptr += RESTORE_INDOFFSET_SIZE; restore_inddata(ptr, offset + 1, count); ptr += RESTORE_INDDATA_SIZE; break; case HWCTX_REGINFO_INDIRECT_OFFSET: restore_indoffset(ptr, offset, count); ptr += RESTORE_INDOFFSET_SIZE; continue; /* INDIRECT_DATA follows with real count */ case HWCTX_REGINFO_INDIRECT_DATA: restore_inddata(ptr, offset, count); ptr += RESTORE_INDDATA_SIZE; break; } ptr += count; } restore_end(ptr, NVSYNCPT_3D); wmb(); }