- drv->name);
- return -ENOSYS;
- }
- if (drv->get_info(desc, part, info) == 0) {
- PRINTF("## Valid %s partition found ##\n", drv->name);
- return 0;
+ if (cached && drv->get_info_cached) {
+ if (drv->get_info_cached(desc, part, info) == 0) {
+ PRINTF("## Valid %s partition found ##\n", drv->name);
+ return 0;
+ }
+ } else {
+ if (!drv->get_info) {
+ PRINTF("## Driver %s does not have the get_info() method\n",
+ drv->name);
+ return -ENOSYS;
+ }
+ if (drv->get_info(desc, part, info) == 0) {
+ PRINTF("## Valid %s partition found ##\n", drv->name);
+ return 0;
+ }
}
}
return -ENOENT;
}
+int part_get_info_by_type(struct blk_desc *desc, int part, int part_type,
+ struct disk_partition *info)
+{
+ return _part_get_info_by_type(desc, part, part_type, info, false);
+}
+
+int part_get_info_cached(struct blk_desc *desc, int part,
+ struct disk_partition *info)
+{
+ return _part_get_info_by_type(desc, part, PART_TYPE_UNKNOWN, info, true);
+}
+
int part_get_info(struct blk_desc *desc, int part,
struct disk_partition *info)
{
- return part_get_info_by_type(desc, part, PART_TYPE_UNKNOWN, info);
+ return _part_get_info_by_type(desc, part, PART_TYPE_UNKNOWN, info, false);
+}
+
+void part_get_info_cached_free(struct blk_desc *desc)
+{
+ struct part_driver *drv;
+
+ if (blk_enabled()) {
+ drv = part_driver_lookup_type(desc);
+ if (!drv)
+ return;
+ if (!drv->get_info_cache_free)
+ return;
+ drv->get_info_cache_free(desc);
+ }
}
int part_get_info_whole_disk(struct blk_desc *desc,
diff --git a/include/part.h b/include/part.h
index
fcb3c13dea4de6346ad98d6ce320ef36747dda85..8c98865146306fb66509576068c45de01b9cedb6
100644
--- a/include/part.h
+++ b/include/part.h
@@ -216,6 +216,34 @@ struct blk_desc *mg_disk_get_dev(int dev);
*/
int part_get_info_by_type(struct blk_desc *desc, int part, int part_type,
struct disk_partition *info);
+
+/**
+ * part_get_info_cached() - Get partitions from a block device but save the
+ * disk partition map between different partitions.
+ *
+ * Call to part_get_info_cached_free() is required when scanning of the
+ * block device is finished.
+ *
+ * If the partition driver doesn't support cached part_info, the
+ * normal part_info will be called instead.
+ *
+ * @desc: Block device descriptor
+ * @part: Partition number to read
+ * @info: Returned partition information
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+int part_get_info_cached(struct blk_desc *desc, int part,
+ struct disk_partition *info);
+
+/**
+ * part_get_info_cached_free() - Free the saved disk partition map
+ * from a previous call of part_get_info_cached().
+ *
+ * @desc: Block device descriptor
+ */
+void part_get_info_cached_free(struct blk_desc *desc);
+
int part_get_info(struct blk_desc *desc, int part,
struct disk_partition *info);
/**
@@ -463,6 +491,22 @@ struct part_driver {
int part_type;
/** @max_entries: maximum number of partition table entries */
const int max_entries;
+ /**
+ * @cache_free_cache_free: Free any parsing data stored from
get_info_cached()
+ *
+ * @get_info_cache_free.desc: Block device descriptor
+ */
+ void (*get_info_cache_free)(struct blk_desc *desc);
+ /**
+ * @get_inf_cachedo: Get information about a partition, and save
+ * the resulting parsing data for the next partition.
+ *
+ * @get_info_cached.desc: Block device descriptor
+ * @get_info_cached.part: Partition number (1 = first)
+ * @get_info_cached.info: Returns partition information
+ */
+ int (*get_info_cached)(struct blk_desc *desc, int part,
+ struct disk_partition *info);
/**
* @get_info: Get information about a partition
*