summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--external/ffspart/ffspart.c2
-rw-r--r--external/pflash/pflash.c2
-rw-r--r--libflash/ffs.h2
-rw-r--r--libflash/libffs.c38
-rw-r--r--libflash/libffs.h4
5 files changed, 39 insertions, 9 deletions
diff --git a/external/ffspart/ffspart.c b/external/ffspart/ffspart.c
index 04de6b6d..fd5075d5 100644
--- a/external/ffspart/ffspart.c
+++ b/external/ffspart/ffspart.c
@@ -344,7 +344,7 @@ out_if:
continue;
out_while:
- free(new_entry);
+ ffs_entry_put(new_entry);
goto out_close_bl;
}
diff --git a/external/pflash/pflash.c b/external/pflash/pflash.c
index 3bc84758..72b90fc8 100644
--- a/external/pflash/pflash.c
+++ b/external/pflash/pflash.c
@@ -116,6 +116,7 @@ static uint32_t print_ffs_info(struct ffs_handle *ffsh, uint32_t toc)
}
user = ffs_entry_user_get(ent);
+ ffs_entry_put(ent);
flags = ffs_entry_user_to_string(&user);
if (!flags)
goto out;
@@ -589,6 +590,7 @@ static void print_partition_detail(struct ffs_handle *ffsh, uint32_t part_id)
"REPROVISION [F]\n" : "",
has_flag(ent, FFS_MISCFLAGS_VOLATILE) ? "VOLATILE [V]\n" : "",
has_flag(ent, FFS_MISCFLAGS_CLEARECC) ? "CLEARECC [C]\n" : "");
+ ffs_entry_put(ent);
if (l < 0) {
fprintf(stderr, "Memory allocation failure printing flags!\n");
goto out;
diff --git a/libflash/ffs.h b/libflash/ffs.h
index 98b2598a..4c757c68 100644
--- a/libflash/ffs.h
+++ b/libflash/ffs.h
@@ -151,6 +151,7 @@ struct __ffs_entry {
* @type: Describe type of partition
* @flags: Partition attributes (optional)
* @user: User data (optional)
+ * @ref: Refcount
*/
struct ffs_entry {
char name[FFS_PART_NAME_MAX + 1];
@@ -161,6 +162,7 @@ struct ffs_entry {
enum ffs_type type;
uint32_t flags;
struct ffs_entry_user user;
+ unsigned int ref;
};
diff --git a/libflash/libffs.c b/libflash/libffs.c
index d2952809..b4a81161 100644
--- a/libflash/libffs.c
+++ b/libflash/libffs.c
@@ -280,13 +280,35 @@ bool has_flag(struct ffs_entry *ent, uint16_t flag)
return ((ent->user.miscflags & flag) != 0);
}
-struct ffs_entry *ffs_entry_get(struct ffs_handle *ffs, uint32_t index)
+static struct ffs_entry *__ffs_entry_get(struct ffs_handle *ffs, uint32_t index)
{
- if (!ffs || index >= ffs->hdr.count)
+ if (index >= ffs->hdr.count)
return NULL;
return ffs->hdr.entries[index];
}
+struct ffs_entry *ffs_entry_get(struct ffs_handle *ffs, uint32_t index)
+{
+ struct ffs_entry *ret = __ffs_entry_get(ffs, index);
+ if (ret)
+ ret->ref++;
+ return ret;
+}
+
+struct ffs_entry *ffs_entry_put(struct ffs_entry *ent)
+{
+ if (!ent)
+ return NULL;
+
+ ent->ref--;
+ if (ent->ref == 0) {
+ free(ent);
+ ent = NULL;
+ }
+
+ return ent;
+}
+
bool has_ecc(struct ffs_entry *ent)
{
return ((ent->user.datainteg & FFS_ENRY_INTEG_ECC) != 0);
@@ -402,6 +424,7 @@ int ffs_init(uint32_t offset, uint32_t max_size, struct blocklevel_device *bl,
}
f->hdr.entries[f->hdr.count++] = ent;
+ ent->ref = 1;
rc = ffs_entry_to_cpu(&f->hdr, ent, &f->cache->entries[i]);
if (rc) {
FL_DBG("FFS: Failed checksum for partition %s\n",
@@ -436,15 +459,14 @@ static void __hdr_free(struct ffs_hdr *hdr)
return;
for (i = 0; i < hdr->count; i++)
- free(hdr->entries[i]);
+ ffs_entry_put(hdr->entries[i]);
free(hdr->entries);
}
-int ffs_hdr_free(struct ffs_hdr *hdr)
+void ffs_hdr_free(struct ffs_hdr *hdr)
{
__hdr_free(hdr);
free(hdr);
- return 0;
}
void ffs_close(struct ffs_handle *ffs)
@@ -483,7 +505,7 @@ int ffs_part_info(struct ffs_handle *ffs, uint32_t part_idx,
struct ffs_entry *ent;
char *n;
- ent = ffs_entry_get(ffs, part_idx);
+ ent = __ffs_entry_get(ffs, part_idx);
if (!ent)
return FFS_ERR_PART_NOT_FOUND;
@@ -609,6 +631,7 @@ int ffs_entry_add(struct ffs_hdr *hdr, struct ffs_entry *entry)
}
hdr->entries_size += HDR_ENTRIES_NUM;
}
+ entry->ref++;
hdr->entries[hdr->count++] = entry;
return 0;
@@ -728,6 +751,7 @@ int ffs_entry_new(const char *name, uint32_t base, uint32_t size, struct ffs_ent
ret->actual = size;
ret->pid = FFS_PID_TOPLEVEL;
ret->type = FFS_TYPE_DATA;
+ ret->ref = 1;
*r = ret;
return 0;
@@ -790,7 +814,7 @@ int ffs_update_act_size(struct ffs_handle *ffs, uint32_t part_idx,
uint32_t offset;
int rc;
- ent = ffs_entry_get(ffs, part_idx);
+ ent = __ffs_entry_get(ffs, part_idx);
if (!ent) {
FL_DBG("FFS: Entry not found\n");
return FFS_ERR_PART_NOT_FOUND;
diff --git a/libflash/libffs.h b/libflash/libffs.h
index 0cf05221..c56574d3 100644
--- a/libflash/libffs.h
+++ b/libflash/libffs.h
@@ -147,6 +147,8 @@ int ffs_hdr_add_side(struct ffs_hdr *hdr);
int ffs_entry_new(const char *name, uint32_t base, uint32_t size, struct ffs_entry **r);
+struct ffs_entry *ffs_entry_put(struct ffs_entry *ent);
+
int ffs_entry_user_set(struct ffs_entry *ent, struct ffs_entry_user *user);
int ffs_entry_set_act_size(struct ffs_entry *ent, uint32_t actual_size);
@@ -158,5 +160,5 @@ int ffs_entry_add(struct ffs_hdr *hdr, struct ffs_entry *entry);
int ffs_hdr_finalise(struct blocklevel_device *bl, struct ffs_hdr *hdr);
-int ffs_hdr_free(struct ffs_hdr *hdr);
+void ffs_hdr_free(struct ffs_hdr *hdr);
#endif /* __LIBFFS_H */
OpenPOWER on IntegriCloud