Beispiel #1
0
static inline void prepare_schedule_oid(uint64_t oid)
{
	struct recovery_work *rw = recovering_work;
	int i;

	for (i = 0; i < rw->nr_prio_oids; i++)
		if (rw->prio_oids[i] == oid)
			return;
	/*
	 * We need this check because oid might not be recovered.
	 * Very much unlikely though, but it might happen indeed.
	 */
	for (i = 0; i < rw->done; i++)
		if (rw->oids[i] == oid) {
			sd_dprintf("%"PRIx64" not recovered, don't schedule it",
				   oid);
			return;
		}
	/* When auto recovery is enabled, the oid is currently being
	 * recovered */
	if (!sys->disable_recovery && rw->oids[rw->done] == oid)
		return;
	rw->nr_prio_oids++;
	rw->prio_oids = xrealloc(rw->prio_oids,
				 rw->nr_prio_oids * sizeof(uint64_t));
	rw->prio_oids[rw->nr_prio_oids - 1] = oid;
	resume_suspended_recovery();

	sd_dprintf("%"PRIx64" nr_prio_oids %d", oid, rw->nr_prio_oids);
}
Beispiel #2
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;
}