int start_recovery(struct vnode_info *cur_vinfo, struct vnode_info *old_vinfo) { struct recovery_work *rw; if (node_is_gateway_only()) return 0; rw = zalloc(sizeof(struct recovery_work)); if (!rw) { eprintf("%m\n"); return -1; } rw->state = RW_INIT; rw->oids = xmalloc(1 << 20); /* FIXME */ rw->epoch = sys->epoch; rw->count = 0; rw->cur_vinfo = grab_vnode_info(cur_vinfo); rw->old_vinfo = grab_vnode_info(old_vinfo); rw->work.fn = prepare_object_list; rw->work.done = finish_object_list; if (sd_store->begin_recover) { struct siocb iocb = { 0 }; iocb.epoch = rw->epoch; sd_store->begin_recover(&iocb); } if (recovering_work != NULL) { /* skip the previous epoch recovery */ if (next_rw) free_recovery_work(next_rw); dprintf("recovery skipped\n"); next_rw = rw; } else { recovering_work = rw; queue_work(sys->recovery_wqueue, &rw->work); } resume_wait_epoch_requests(); return 0; }
int start_recovery(struct vnode_info *cur_vinfo, struct vnode_info *old_vinfo) { struct recovery_work *rw; if (node_is_gateway_only()) goto out; rw = xzalloc(sizeof(struct recovery_work)); rw->state = RW_INIT; rw->oids = xmalloc(list_buffer_size); rw->epoch = sys->epoch; rw->count = 0; rw->cur_vinfo = grab_vnode_info(cur_vinfo); rw->old_vinfo = grab_vnode_info(old_vinfo); rw->work.fn = prepare_object_list; rw->work.done = finish_object_list; if (recovering_work != NULL) { /* skip the previous epoch recovery */ if (next_rw) free_recovery_work(next_rw); sd_dprintf("recovery skipped"); next_rw = rw; /* * This is necesary to invoke run_next_rw when * recovery work is suspended. */ resume_suspended_recovery(); } else { recovering_work = rw; queue_work(sys->recovery_wqueue, &rw->work); } out: wakeup_requests_on_epoch(); return 0; }