[05/13] gard: Add iterators

Message ID 20171108085918.12590-6-oohall@gmail.com
State New
Headers show
Series
  • [01/13] gard: show: Remove "Res Recovery" field
Related show

Commit Message

Oliver O'Halloran Nov. 8, 2017, 8:59 a.m.
Add a `for_each_gard` iterator rather than using do_iterate. Callbacks
are banned under the Genoa convention and we need to apply a
zero-tolerance policy.

Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
 external/gard/gard.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

Patch

diff --git a/external/gard/gard.c b/external/gard/gard.c
index 0c8ac47e74f1..c43b8594df25 100644
--- a/external/gard/gard.c
+++ b/external/gard/gard.c
@@ -212,6 +212,37 @@  static int do_iterate(struct gard_ctx *ctx,
 	return rc;
 }
 
+/*
+ * read the next guard record into the supplied buffer (gard)
+ *
+ * returns the record id (nb: 1 based not zero)
+ *
+ */
+static int __gard_next(struct gard_ctx *ctx, int pos, struct gard_record *gard, int *rc)
+{
+	uint32_t offset = pos * sizeof_gard(ctx);
+
+	if (offset > ctx->gard_data_len) /* too big */
+		return -1;
+
+	/* you lose error handling information, *gruble* */
+	memset(gard, 0, sizeof(*gard));
+	*rc = blocklevel_read(ctx->bl, ctx->gard_data_pos + offset,
+				gard, sizeof(*gard));
+
+	if (!is_valid_record(gard))
+		return -1;
+
+	if (*rc)
+		return -1;
+
+	return pos;
+}
+
+#define for_each_gard(ctx, pos, gard, rc) \
+	for (pos = __gard_next(ctx, 0, gard, rc); \
+		pos >= 0; pos = __gard_next(ctx, ++pos, gard, rc))
+
 static int get_largest_pos_i(struct gard_ctx *ctx, int pos, struct gard_record *gard, void *priv)
 {
 	(void)ctx;