summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStewart Smith <stewart@linux.vnet.ibm.com>2017-11-30 16:37:10 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-11-30 16:37:10 +1100
commitaa0ee75d8ab126cd46aa6f586995423e396e7341 (patch)
tree600bd6a4046f323cc6d3fec4a30271da86c19c53
parentdbe1e476ae008d4509ee9b97fa93c7c797d90059 (diff)
parentd0e98fa613106a2dac13aec7e37d473e89802680 (diff)
downloadffs-aa0ee75d8ab126cd46aa6f586995423e396e7341.tar.gz
ffs-aa0ee75d8ab126cd46aa6f586995423e396e7341.zip
Merge fix for TOC > 4k
https://github.com/open-power/ffs/pull/14
-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 83a7df0..7e20bef 100644
--- a/ffs/src/libffs.c
+++ b/ffs/src/libffs.c
@@ -1020,6 +1020,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