bloblist: Add a new function to add or check size
authorSimon Glass <sjg@chromium.org>
Mon, 27 Jan 2020 15:49:50 +0000 (08:49 -0700)
committerSimon Glass <sjg@chromium.org>
Thu, 6 Feb 2020 02:33:46 +0000 (19:33 -0700)
A common check is to see if a blob is present, create it if not and make
sure that the size is large enough. Add a function to handle this.

Signed-off-by: Simon Glass <sjg@chromium.org>
common/bloblist.c
include/bloblist.h
test/bloblist.c

index ccf5e4b6f64576c028607292e120beb01ddef298..3599ffa75c0d0599bd02806c5ee19e00f4c6fd85 100644 (file)
@@ -85,8 +85,10 @@ static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size)
 
        rec = bloblist_findrec(tag);
        if (rec) {
-               if (size && size != rec->size)
+               if (size && size != rec->size) {
+                       *recp = rec;
                        return -ESPIPE;
+               }
        } else {
                int ret;
 
@@ -145,6 +147,21 @@ void *bloblist_ensure(uint tag, int size)
        return (void *)rec + rec->hdr_size;
 }
 
+int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp)
+{
+       struct bloblist_rec *rec;
+       int ret;
+
+       ret = bloblist_ensurerec(tag, &rec, *sizep);
+       if (ret == -ESPIPE)
+               *sizep = rec->size;
+       else if (ret)
+               return ret;
+       *blobp = (void *)rec + rec->hdr_size;
+
+       return 0;
+}
+
 static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr)
 {
        struct bloblist_rec *rec;
index 85144010abea9e00edf67fddf288373e8f0303fc..8c9ce98a3b68bdc1958d007db63936dcda36909a 100644 (file)
@@ -151,6 +151,19 @@ int bloblist_ensure_size(uint tag, int size, void **blobp);
  */
 void *bloblist_ensure(uint tag, int size);
 
+/**
+ * bloblist_ensure_size_ret() - Find or add a blob
+ *
+ * Find an existing blob, or add a new one if not found
+ *
+ * @tag:       Tag to add (enum bloblist_tag_t)
+ * @sizep:     Size of the blob to create; returns size of actual blob
+ * @blobp:     Returns a pointer to blob on success
+ * @return 0 if OK, -ENOSPC if it is missing and could not be added due to lack
+ *     of space
+ */
+int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp);
+
 /**
  * bloblist_new() - Create a new, empty bloblist of a given size
  *
index d0f7296e0d89c40805f9dcb4d6220c1b038995c1..c78b58ea2936f0e8094ff6a13ebca8a155f23f17 100644 (file)
@@ -24,6 +24,7 @@ enum {
 
        TEST_SIZE               = 10,
        TEST_SIZE2              = 20,
+       TEST_SIZE_LARGE         = 0xe0,
 
        TEST_ADDR               = CONFIG_BLOBLIST_ADDR,
        TEST_BLOBLIST_SIZE      = 0x100,
@@ -97,6 +98,39 @@ static int bloblist_test_blob(struct unit_test_state *uts)
 }
 BLOBLIST_TEST(bloblist_test_blob, 0);
 
+/* Check bloblist_ensure_size_ret() */
+static int bloblist_test_blob_ensure(struct unit_test_state *uts)
+{
+       void *data, *data2;
+       int size;
+
+       /* At the start there should be no records */
+       clear_bloblist();
+       ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
+
+       /* Test with an empty bloblist */
+       size = TEST_SIZE;
+       ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data));
+       ut_asserteq(TEST_SIZE, size);
+
+       /* Check that we get the same thing again */
+       ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data2));
+       ut_asserteq(TEST_SIZE, size);
+       ut_asserteq_ptr(data, data2);
+
+       /* Check that the size remains the same */
+       size = TEST_SIZE2;
+       ut_assertok(bloblist_ensure_size_ret(TEST_TAG, &size, &data));
+       ut_asserteq(TEST_SIZE, size);
+
+       /* Check running out of space */
+       size = TEST_SIZE_LARGE;
+       ut_asserteq(-ENOSPC, bloblist_ensure_size_ret(TEST_TAG2, &size, &data));
+
+       return 0;
+}
+BLOBLIST_TEST(bloblist_test_blob_ensure, 0);
+
 static int bloblist_test_bad_blob(struct unit_test_state *uts)
 {
        struct bloblist_hdr *hdr;