[sheepdog] [PATCH 4/5] sheep: refactor recovery.c
Liu Yuan
namei.unix at gmail.com
Fri Jun 1 11:31:36 CEST 2012
From: Liu Yuan <tailai.ly at taobao.com>
- split object_list handling from object recovering process
- factor recover_object_main
Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
sheep/recovery.c | 99 +++++++++++++++++++++++++++++++-----------------------
1 file changed, 57 insertions(+), 42 deletions(-)
diff --git a/sheep/recovery.c b/sheep/recovery.c
index 0528019..7c5d442 100644
--- a/sheep/recovery.c
+++ b/sheep/recovery.c
@@ -239,7 +239,7 @@ err:
return ret;
}
-static void recover_object(struct work *work)
+static void recover_object_work(struct work *work)
{
struct recovery_work *rw = container_of(work, struct recovery_work,
work);
@@ -357,63 +357,77 @@ static void free_recovery_work(struct recovery_work *rw)
free(rw);
}
-static void do_recover_main(struct work *work)
+static void recover_object_main(struct work *work)
{
- struct recovery_work *rw = container_of(work, struct recovery_work, work);
- uint64_t oid, recovered_oid = rw->oids[rw->done];
-
- if (rw->state == RW_INIT) {
- rw->state = RW_RUN;
- recovered_oid = 0;
- resume_wait_recovery_requests();
- } else if (!rw->stop){
- rw->done++;
- if (rw->nr_blocking > 0)
- rw->nr_blocking--;
+ struct recovery_work *rw = container_of(work, struct recovery_work,
+ work);
+ if (next_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);
+ dprintf("recovery work is superseded\n");
+ return;
}
- oid = rw->oids[rw->done];
-
- if (recovered_oid)
- resume_wait_obj_requests(recovered_oid);
+ if (rw->stop){
+ /*
+ * Stop this recovery process and wait for epoch to be
+ * lifted and flush wait_obj queue to requeue those
+ * requests
+ */
+ flush_wait_obj_requests();
+ dprintf("recovery is stopped\n");
+ return;
+ }
- if (rw->done < rw->count && !next_rw) {
- rw->work.fn = recover_object;
+ if (rw->nr_blocking > 0)
+ rw->nr_blocking--;
+ resume_wait_obj_requests(rw->done++);
- if (rw->stop) {
- flush_wait_obj_requests();
- return;
- }
+ if (rw->done < rw->count) {
+ uint64_t oid;
+ oid = rw->oids[rw->done];
if (is_access_to_busy_objects(oid)) {
suspended_recovery_work = rw;
return;
}
+ /* Requeue the work */
queue_work(sys->recovery_wqueue, &rw->work);
return;
}
- dprintf("recovery complete: new epoch %"PRIu32"\n", rw->epoch);
recovering_work = NULL;
-
sys->recovered_epoch = rw->epoch;
free_recovery_work(rw);
- if (next_rw) {
- rw = next_rw;
- next_rw = NULL;
-
- recovering_work = rw;
- flush_wait_obj_requests();
-
- queue_work(sys->recovery_wqueue, &rw->work);
- } else {
- if (sd_store->end_recover) {
- struct siocb iocb = { 0 };
- iocb.epoch = sys->epoch;
- sd_store->end_recover(&iocb);
- }
+ if (sd_store->end_recover) {
+ struct siocb iocb = { 0 };
+ iocb.epoch = sys->epoch;
+ sd_store->end_recover(&iocb);
}
+ dprintf("recovery complete: new epoch %"PRIu32"\n", sys->recovered_epoch);
+}
+
+static void finish_object_list(struct work *work)
+{
+ struct recovery_work *rw = container_of(work, struct recovery_work,
+ work);
+ rw->state = RW_RUN;
+ /*
+ * We have got the object list to be recovered locally, most of
+ * objects are actually already being there, so let's resume
+ * requests in the hope that most requests will be processed
+ * without any problem.
+ */
+ resume_wait_recovery_requests();
+ rw->work.fn = recover_object_work;
+ rw->work.done = recover_object_main;
+ queue_work(sys->recovery_wqueue, &rw->work);
+ return;
}
static int request_obj_list(struct sd_node *e, uint32_t epoch,
@@ -550,7 +564,7 @@ again:
return 0;
}
-static void do_recovery_work(struct work *work)
+static void prepare_object_list(struct work *work)
{
struct recovery_work *rw = container_of(work, struct recovery_work, work);
@@ -582,8 +596,8 @@ int start_recovery(struct vnode_info *cur_vnodes, struct vnode_info *old_vnodes)
rw->cur_vnodes = grab_vnode_info(cur_vnodes);
rw->old_vnodes = grab_vnode_info(old_vnodes);
- rw->work.fn = do_recovery_work;
- rw->work.done = do_recover_main;
+ rw->work.fn = prepare_object_list;
+ rw->work.done = finish_object_list;
if (sd_store->begin_recover) {
struct siocb iocb = { 0 };
@@ -595,6 +609,7 @@ int start_recovery(struct vnode_info *cur_vnodes, struct vnode_info *old_vnodes)
/* skip the previous epoch recovery */
if (next_rw)
free_recovery_work(next_rw);
+ dprintf("recovery skipped\n");
next_rw = rw;
} else {
recovering_work = rw;
--
1.7.10.2
More information about the sheepdog
mailing list