[Skiboot] [PATCH 12/15] libflash/libffs: Allow caller to specifiy header partition

Cyril Bur cyril.bur at au1.ibm.com
Thu Mar 15 16:58:24 AEDT 2018


An FFS TOC is comprised of two parts. A small header which has a magic
and very minimmal information about the TOC which will be common to all
partitions, things like number of patritions, block sizes and the like.
Following this small header are a series of entries. Importantly there
is always an entry which encompases the TOC its self, this is usually
called the 'part' partition.

Currently libffs always assumes that the 'part' partition is at zero.
While there is always a TOC and zero there doesn't actually have to be.
PNORs may have multiple TOCs within them, therefore libffs needs to be
flexible enough to allow callers to specify TOCs not at zero.

The 'part' partition is otherwise a regular partition which may have
flags associated with it. libffs should allow the user to set the flags
for the 'part' partition.

This patch achieves both by allowing the caller to specify the 'part'
partition. The caller can not and libffs will provide a sensible
default.

Signed-off-by: Cyril Bur <cyril.bur at au1.ibm.com>
---
 external/ffspart/ffspart.c |  2 +-
 libflash/ffs.h             |  1 -
 libflash/libffs.c          | 28 ++++++++++++++++++++--------
 libflash/libffs.h          |  2 +-
 4 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/external/ffspart/ffspart.c b/external/ffspart/ffspart.c
index fd5075d5..c3559523 100644
--- a/external/ffspart/ffspart.c
+++ b/external/ffspart/ffspart.c
@@ -131,7 +131,7 @@ int main(int argc, char *argv[])
 		goto out;
 	}
 
-	rc = ffs_hdr_new(block_size, block_count, &new_hdr);
+	rc = ffs_hdr_new(block_size, block_count, NULL, &new_hdr);
 	if (rc) {
 		if (rc == FFS_ERR_BAD_SIZE) {
 			/* Well this check is a tad redudant now */
diff --git a/libflash/ffs.h b/libflash/ffs.h
index 4c757c68..b147396e 100644
--- a/libflash/ffs.h
+++ b/libflash/ffs.h
@@ -212,7 +212,6 @@ struct __ffs_hdr {
  */
 struct ffs_hdr {
 	uint32_t version;
-	uint32_t base;
 	uint32_t size;
 	uint32_t block_size;
 	uint32_t block_count;
diff --git a/libflash/libffs.c b/libflash/libffs.c
index b4a81161..ceaf0fda 100644
--- a/libflash/libffs.c
+++ b/libflash/libffs.c
@@ -684,8 +684,8 @@ int ffs_hdr_finalise(struct blocklevel_device *bl, struct ffs_hdr *hdr)
 	}
 
 	/* Don't really care if this fails */
-	blocklevel_erase(bl, hdr->base, hdr->size);
-	rc = blocklevel_write(bl, hdr->base, real_hdr,
+	blocklevel_erase(bl, hdr->part->base, hdr->size);
+	rc = blocklevel_write(bl, hdr->part->base, real_hdr,
 		ffs_hdr_raw_size(num_entries));
 	if (rc)
 		goto out;
@@ -770,7 +770,8 @@ int ffs_entry_set_act_size(struct ffs_entry *ent, uint32_t actual_size)
 	return 0;
 }
 
-int ffs_hdr_new(uint32_t block_size, uint32_t block_count, struct ffs_hdr **r)
+int ffs_hdr_new(uint32_t block_size, uint32_t block_count,
+		struct ffs_entry **e, struct ffs_hdr **r)
 {
 	struct ffs_hdr *ret;
 	struct ffs_entry *part_table;
@@ -786,12 +787,23 @@ int ffs_hdr_new(uint32_t block_size, uint32_t block_count, struct ffs_hdr **r)
 	ret->entries = calloc(HDR_ENTRIES_NUM, sizeof(struct ffs_entry *));
 	ret->entries_size = HDR_ENTRIES_NUM;
 
-	/* Don't know how big it will be, ffs_hdr_finalise() will fix */
-	rc = ffs_entry_new("part", 0, 0, &part_table);
-	if (rc) {
-		free(ret);
-		return rc;
+	if (!e || !(*e)) {
+		/* Don't know how big it will be, ffs_hdr_finalise() will fix */
+		rc = ffs_entry_new("part", 0, 0, &part_table);
+		if (rc) {
+			free(ret);
+			return rc;
+		}
+		if (e)
+			*e = part_table;
+	} else {
+		part_table = *e;
 	}
+
+	/* If the user still holds a ref to e, then inc the refcount */
+	if (e)
+		part_table->ref++;
+
 	ret->part = part_table;
 
 	part_table->pid = FFS_PID_TOPLEVEL;
diff --git a/libflash/libffs.h b/libflash/libffs.h
index c56574d3..f149fd8f 100644
--- a/libflash/libffs.h
+++ b/libflash/libffs.h
@@ -141,7 +141,7 @@ int ffs_update_act_size(struct ffs_handle *ffs, uint32_t part_idx,
 			uint32_t act_size);
 
 int ffs_hdr_new(uint32_t block_size, uint32_t block_count,
-		struct ffs_hdr **r);
+		struct ffs_entry **e, struct ffs_hdr **r);
 
 int ffs_hdr_add_side(struct ffs_hdr *hdr);
 
-- 
2.16.2



More information about the Skiboot mailing list