summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Geddes <crgeddes@us.ibm.com>2017-11-20 17:16:55 -0600
committerChristian Geddes <crgeddes@us.ibm.com>2017-11-20 17:16:55 -0600
commitd0e98fa613106a2dac13aec7e37d473e89802680 (patch)
tree85972e76ef98183735dff8e935c6d0c3c4b19070
parent2e790b8409071ca15767d822dabfa8e60f12c6e2 (diff)
downloadffs-d0e98fa613106a2dac13aec7e37d473e89802680.zip
ffs-d0e98fa613106a2dac13aec7e37d473e89802680.tar.gz
Update libffs to increment part entry and TOC size info
Without this commit , the size of the Table of Contents noted by ffs_hdr->size was getting defaulted to 4kb (1 hostboot pagesize) There should be no limitation on the size of the toc, but this size was not getting incremented if there were enough entries to push the size of the toc over 4kb. This commit adds logic to increate the ffs_hdr->size as well as the "part" ffs_entries's size as we add entries to the ffs_hdr
-rw-r--r--ffs/ffs.h5
-rw-r--r--ffs/src/libffs.c28
2 files changed, 33 insertions, 0 deletions
diff --git a/ffs/ffs.h b/ffs/ffs.h
index 3ca09ea..38284b5 100644
--- a/ffs/ffs.h
+++ b/ffs/ffs.h
@@ -48,6 +48,11 @@
#define FFS_ENTRY_SIZE sizeof(struct ffs_entry)
/*
+* Size of FFS_HDR w/o entry struct in bytes
+*/
+#define FFS_HDR_SIZE_NO_ENTRY 0x48
+
+/*
* Sizes of the data structures w/o checksum
*/
#define FFS_HDR_SIZE_CSUM (FFS_HDR_SIZE - sizeof(uint32_t))
diff --git a/ffs/src/libffs.c b/ffs/src/libffs.c
index e8f1933..55e33bf 100644
--- a/ffs/src/libffs.c
+++ b/ffs/src/libffs.c
@@ -1021,6 +1021,34 @@ int __ffs_entry_add(ffs_t * self, const char *path, off_t offset, uint32_t size,
hdr->entry_count++;
+ // Need to update 'part' entry as well as ffs hdr
+ // if the required number of blocks changes
+ uint32_t blocksNeeded = (hdr->entry_count * hdr->entry_size + FFS_HDR_SIZE_NO_ENTRY) / hdr->block_size;
+ if(hdr->entry_count * hdr->entry_size + FFS_HDR_SIZE_NO_ENTRY % hdr->block_size)
+ {
+ blocksNeeded++;
+ }
+
+ if(hdr->size != blocksNeeded)
+ {
+ ffs_entry_t entry;
+ if (__ffs_entry_find(self, "part", &entry) == false) {
+ UNEXPECTED("entry '%s' not found in table at offset '%llx'",
+ "part", (long long)self->offset);
+ return -1;
+ }
+
+ int find_entry_id(ffs_entry_t * __entry) {
+ return entry.id == __entry->id;
+ }
+
+ ffs_entry_t *entry_p = __iterate_entries(hdr, find_entry_id);
+ assert(entry_p != NULL);
+
+ hdr->size = blocksNeeded;
+ entry_p->size = blocksNeeded;
+ entry_p->actual = blocksNeeded * hdr->block_size;
+ }
self->dirty = true;
return 0;
OpenPOWER on IntegriCloud