struct blkid_chain *wipe_chain; /* superblock, partition, ... */
struct list_head buffers; /* list of buffers */
+ struct list_head prunable_buffers; /* list of prunable buffers */
struct list_head hints;
struct blkid_chain chains[BLKID_NCHAINS]; /* array of chains */
uint64_t *offset, const struct blkid_idmag **res)
__attribute__((nonnull(1)));
+extern void blkid_probe_prune_buffers(blkid_probe pr);
+
/* returns superblock according to 'struct blkid_idmag' */
extern const unsigned char *blkid_probe_get_sb_buffer(blkid_probe pr, const struct blkid_idmag *mag, size_t size);
#define blkid_probe_get_sb(_pr, _mag, type) \
pr->chains[i].enabled = chains_drvs[i]->dflt_enabled;
}
INIT_LIST_HEAD(&pr->buffers);
+ INIT_LIST_HEAD(&pr->prunable_buffers);
INIT_LIST_HEAD(&pr->values);
INIT_LIST_HEAD(&pr->hints);
return pr;
return NULL;
}
+/*
+ * Mark smaller buffers that can be satisfied by bf as prunable
+ */
+static void mark_prunable_buffers(blkid_probe pr, const struct blkid_bufinfo *bf)
+{
+ struct list_head *p, *next;
+
+ list_for_each_safe(p, next, &pr->buffers) {
+ struct blkid_bufinfo *x =
+ list_entry(p, struct blkid_bufinfo, bufs);
+
+ if (bf->off <= x->off && bf->off + bf->len >= x->off + x->len) {
+ list_del(&x->bufs);
+ list_add(&x->bufs, &pr->prunable_buffers);
+ }
+ }
+}
+
+/*
+ * Remove buffers that are marked as prunable
+ */
+void blkid_probe_prune_buffers(blkid_probe pr)
+{
+ struct list_head *p, *next;
+
+ list_for_each_safe(p, next, &pr->prunable_buffers) {
+ struct blkid_bufinfo *x =
+ list_entry(p, struct blkid_bufinfo, bufs);
+
+ remove_buffer(x);
+ }
+}
+
/*
* Zeroize in-memory data in already read buffer. The next blkid_probe_get_buffer()
* will return modified buffer. This is usable when you want to call the same probing
if (!bf)
return NULL;
+ mark_prunable_buffers(pr, bf);
list_add_tail(&bf->bufs, &pr->buffers);
}
pr->flags &= ~BLKID_FL_MODIF_BUFF;
+ blkid_probe_prune_buffers(pr);
+
if (list_empty(&pr->buffers))
return 0;
static int topology_probe(blkid_probe pr, struct blkid_chain *chn)
{
size_t i;
+ int rc;
if (chn->idx < -1)
return -1;
if (id->probefunc) {
DBG(LOWPROBE, ul_debug("%s: call probefunc()", id->name));
- if (id->probefunc(pr, NULL) != 0)
+ rc = id->probefunc(pr, NULL);
+ blkid_probe_prune_buffers(pr);
+ if (rc != 0)
continue;
}