static inline void run_next_rw(struct recovery_work *rw) { free_recovery_work(rw); rw = next_rw; next_rw = NULL; recovering_work = rw; flush_wait_obj_requests(); queue_work(sys->recovery_wqueue, &rw->work); sd_dprintf("recovery work is superseded"); }
static inline void finish_recovery(struct recovery_work *rw) { recovering_work = NULL; sys->recovered_epoch = rw->epoch; if (sd_store->end_recover) sd_store->end_recover(sys->epoch - 1, rw->old_vnodes); free_recovery_work(rw); dprintf("recovery complete: new epoch %"PRIu32"\n", sys->recovered_epoch); }
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; }
static void notify_recovery_completion_main(struct work *work) { struct recovery_work *rw = container_of(work, struct recovery_work, work); free_recovery_work(rw); }