[sheepdog] [PATCH 2/2] sheep: cleanup prepare_schedule_oid and oid_in_recovery
MORITA Kazutaka
morita.kazutaka at gmail.com
Fri Aug 30 16:24:32 CEST 2013
From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
This moves all the check of recovering objects from
prepare_schedule_oid() to oid_in_recovery(), and makes the code easier
to read.
This also fixes a problem that sheep doesn't recover an object when
- sys->cinfo.disable_recovery is true,
- rinfo->state is RW_PREPARE_LIST, and
- oid_in_recovery() is called against the object
and fixes an error of tests/functional/010, which happens in rare
cases.
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
include/sheep.h | 5 ++++
sheep/recovery.c | 77 ++++++++++++++++++++++++++++++------------------------
2 files changed, 48 insertions(+), 34 deletions(-)
diff --git a/include/sheep.h b/include/sheep.h
index 68c852f..f9945c6 100644
--- a/include/sheep.h
+++ b/include/sheep.h
@@ -251,6 +251,11 @@ static inline const char *sd_strerror(int err)
return descs[err];
}
+static inline int oid_cmp(const uint64_t *oid1, const uint64_t *oid2)
+{
+ return intcmp(*oid1, *oid2);
+}
+
static inline int node_id_cmp(const struct node_id *node1,
const struct node_id *node2)
{
diff --git a/sheep/recovery.c b/sheep/recovery.c
index 6faaeab..4305e48 100644
--- a/sheep/recovery.c
+++ b/sheep/recovery.c
@@ -331,24 +331,11 @@ bool node_in_recovery(void)
static inline void prepare_schedule_oid(uint64_t oid)
{
struct recovery_info *rinfo = main_thread_get(current_rinfo);
- uint64_t i;
- for (i = 0; i < rinfo->nr_prio_oids; i++)
- if (rinfo->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 < rinfo->done; i++)
- if (rinfo->oids[i] == oid) {
- sd_debug("%"PRIx64" not recovered, don't schedule it",
- oid);
- return;
- }
- /* When recovery is not suspended, oid is currently being recovered */
- if (!rinfo->suspended && rinfo->oids[rinfo->done] == oid)
+ if (xlfind(&oid, rinfo->prio_oids, rinfo->nr_prio_oids, oid_cmp)) {
+ sd_debug("%" PRIx64 " has been already in prio_oids", oid);
return;
+ }
rinfo->nr_prio_oids++;
rinfo->prio_oids = xrealloc(rinfo->prio_oids,
@@ -359,10 +346,9 @@ static inline void prepare_schedule_oid(uint64_t oid)
resume_suspended_recovery();
}
-bool oid_in_recovery(uint64_t oid)
+main_fn bool oid_in_recovery(uint64_t oid)
{
struct recovery_info *rinfo = main_thread_get(current_rinfo);
- uint64_t i;
if (!node_in_recovery())
return false;
@@ -373,27 +359,50 @@ bool oid_in_recovery(uint64_t oid)
}
if (uatomic_read(&next_rinfo))
+ /*
+ * The current recovery_info will be taken over by the next one
+ * soon, so no need to call prepare_schedule_oid() now.
+ */
return true;
- /* If we are in preparation of object list, oid is not recovered yet */
- if (rinfo->state == RW_PREPARE_LIST)
- return true;
+ switch (rinfo->state) {
+ case RW_PREPARE_LIST:
+ /* oid is not recovered yet */
+ break;
+ case RW_RECOVER_OBJ:
+ if (xlfind(&oid, rinfo->oids, rinfo->done, oid_cmp)) {
+ sd_debug("%" PRIx64 " has been already recovered", oid);
+ return false;
+ }
- /*
- * Check if oid is in the list that to be recovered later
- *
- * FIXME: do we need more efficient yet complex data structure?
- */
- for (i = rinfo->done; i < rinfo->count; i++)
- if (rinfo->oids[i] == oid)
+ if (rinfo->oids[rinfo->done] == oid) {
+ if (rinfo->suspended)
+ break;
+ /*
+ * When recovery is not suspended,
+ * rinfo->oids[rinfo->done] is currently being recovered
+ * and no need to call prepare_schedule_oid().
+ */
+ return true;
+ }
+
+ /*
+ * Check if oid is in the list that to be recovered later
+ *
+ * FIXME: do we need more efficient yet complex data structure?
+ */
+ if (xlfind(&oid, rinfo->oids + rinfo->done + 1, rinfo->count,
+ oid_cmp))
break;
- /*
- * Newly created object after prepare_object_list() might not be
- * in the list
- */
- if (i == rinfo->count) {
- sd_err("%"PRIx64" is not in the recovery list", oid);
+ /*
+ * Newly created object after prepare_object_list() might not be
+ * in the list
+ */
+ sd_debug("%"PRIx64" is not in the recovery list", oid);
+ return false;
+ case RW_NOTIFY_COMPLETION:
+ sd_debug("the object %" PRIx64 " is already recoverd", oid);
return false;
}
--
1.7.9.5
More information about the sheepdog
mailing list