struct list_head bufs; /* list of buffers */
};
+/*
+ * Probing hint
+ */
+struct blkid_hint {
+ char *name;
+ uint64_t value;
+ struct list_head hints;
+};
+
/*
* Low-level probing control struct
*/
struct blkid_chain *wipe_chain; /* superblock, partition, ... */
struct list_head buffers; /* list of buffers */
+ struct list_head hints;
struct blkid_chain chains[BLKID_NCHAINS]; /* array of chains */
struct blkid_chain *cur_chain; /* current chain */
extern void blkid_probe_use_wiper(blkid_probe pr, uint64_t off, uint64_t size)
__attribute__((nonnull));
+extern int blkid_probe_get_hint(blkid_probe pr, const char *name, uint64_t *value)
+ __attribute__((nonnull(1,2)))
+ __attribute__((warn_unused_result));
+
/* filter bitmap macros */
#define blkid_bmp_wordsize (8 * sizeof(unsigned long))
#define blkid_bmp_idx_bit(item) (1UL << ((item) % blkid_bmp_wordsize))
};
static void blkid_probe_reset_values(blkid_probe pr);
+static void blkid_probe_reset_hints(blkid_probe pr);
/**
* blkid_new_probe:
}
INIT_LIST_HEAD(&pr->buffers);
INIT_LIST_HEAD(&pr->values);
+ INIT_LIST_HEAD(&pr->hints);
return pr;
}
close(pr->fd);
blkid_probe_reset_buffers(pr);
blkid_probe_reset_values(pr);
+ blkid_probe_reset_hints(pr);
blkid_free_probe(pr->disk_probe);
DBG(LOWPROBE, ul_debug("free probe"));
int i;
blkid_probe_reset_values(pr);
+ blkid_probe_reset_hints(pr);
blkid_probe_set_wiper(pr, 0, 0);
pr->cur_chain = NULL;
return rc;
}
+
static void blkid_probe_reset_values(blkid_probe pr)
{
if (list_empty(&pr->values))
blkid_probe_chain_reset_values(pr, chn);
}
}
+
+/**
+ * blkid_probe_set_hint
+ * @pr: probe
+ * @name: hint name or NAME=value
+ * @value: offset or another number
+ *
+ * Sets extra hint for low-level prober. If the hint is set by NAME=value
+ * notation than @value is ignored. The functions blkid_probe_set_device()
+ * and blkid_reset_probe() resets all hints.
+ *
+ * The hints are optional way how to force libblkid probing functions to check
+ * for example another location.
+ *
+ * Returns: 0 on success, or -1 in case of error.
+ */
+int blkid_probe_set_hint(blkid_probe pr, const char *name, uint64_t value)
+{
+ struct blkid_hint *hint = NULL;
+ char *n = NULL, *v = NULL;
+
+ if (strchr(name, '=')) {
+ char *end = NULL;
+
+ if (blkid_parse_tag_string(name, &n, &v) != 0)
+ goto done;
+
+ errno = 0;
+ value = strtoumax(v, &end, 10);
+
+ if (errno || v == end || (end && *end))
+ goto done;
+ } else {
+ n = strdup(name);
+ if (!n)
+ goto done;
+ }
+
+ /* allocate info and space for data by one malloc call */
+ hint = malloc(sizeof(*hint));
+ if (!hint)
+ goto done;
+
+ INIT_LIST_HEAD(&hint->hints);
+ hint->name = n;
+ hint->value = value;
+ n = NULL;
+ list_add_tail(&hint->hints, &pr->hints);
+
+ DBG(LOWPROBE,
+ ul_debug("new hint '%s' is %"PRIu64"", hint->name, hint->value));
+done:
+ free(n);
+ free(v);
+ if (!hint)
+ return errno ? -errno : -EINVAL;
+ return 0;
+}
+
+int blkid_probe_get_hint(blkid_probe pr, const char *name, uint64_t *value)
+{
+ struct list_head *p;
+
+ if (list_empty(&pr->hints))
+ return -EINVAL;
+
+ list_for_each(p, &pr->hints) {
+ struct blkid_hint *h = list_entry(p, struct blkid_hint, hints);
+
+ if (h->name && strcmp(name, h->name) == 0) {
+ if (value)
+ *value = h->value;
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+static void blkid_probe_reset_hints(blkid_probe pr)
+{
+ if (list_empty(&pr->hints))
+ return;
+
+ DBG(LOWPROBE, ul_debug("resetting hints"));
+
+ while (!list_empty(&pr->hints)) {
+ struct blkid_hint *h = list_entry(pr->hints.next,
+ struct blkid_hint, hints);
+ list_del(&h->hints);
+ free(h->name);
+ free(h);
+ }
+
+ INIT_LIST_HEAD(&pr->hints);
+}