From patchwork Sat Oct 18 08:40:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 604 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1760776911; bh=A5zjUKB5jPlKH27wCrDh1Ns/D254Slq9GIJHWvzUusU=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=U1TPzYF7xSvwtTCdZVbZOwPXiXb9APC1q5iCKX8UzkwjWnUTUB2nemPD2wV0WP15K AV6Wd2U9Zwt9ASGJVG1M5bCdnK6rkbfqMX8i+32Kj4/hQEbxAdl028XcuGou4frz7i 5xwku0fIJRhAu8i9qTphHhgxrstU85AMcp/GWmRc8UXES+xWrlO4D7V74dLRLfCy3G f63ePryLmaI0Z3s03kg4D4JZYZvzKPnMDK7X91R/vuCjgNydoCBrD0iazlKGNCneqg DYH/V0UvNBT/BV16ofeCE5Ty2NMWcJHZ5buogu5d2scM5b4cNQy7J2rQtFPopR6w4N gXpCI/vJ+oYeQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 01E4A681CF for ; Sat, 18 Oct 2025 02:41:51 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id QfYQGCM8gsde for ; Sat, 18 Oct 2025 02:41:50 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1760776908; bh=A5zjUKB5jPlKH27wCrDh1Ns/D254Slq9GIJHWvzUusU=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=GNvNqH/iwXTFgmt/q2WsKz7KwKJCwFvDvtznHtQlWslMTxBi13rzApj95GmXv6lXh WZworwAqHnufRVTWTAZLw19TIPt8r/h7vfF3OOHMf72Aj05mt26ah0w+ZOlXt8UCmo xdZPWIEUomoc8xLeIeG1zce9Fn0lWf3WMaa9qJnMS/UkKoh3DiL4TXm2UlaHavjg0q 5vIVtXT41nrqUOaX/7z3VKSvg8Cp+3av6y64UO7K837g7NnH+XNH9SPwvcVkI5xMvu YSimFMoC2+3KATyD9UqfWw0f6rBsV9iOzNR6myjgddIykhIAquDwlr1zXC+eEtOhNz hl0PB4uB6TzPQ== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id EFEA56814E for ; Sat, 18 Oct 2025 02:41:48 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1760776906; bh=KPkModgKK15pSAwYlh3hQolLN6K8pT4JkdR1+DndeJk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GB4AADVlogJMJQhYZrUDnlwBrkQwgR97dPuRlE37E45j4sMQvRrQlQ/YCtx2Nm5KJ ay9CBcSuNmHPFA+JTms/H8TE+crEqr9PqJ6IA6E2pRXcbCnRhjut68abX+Flwy+kmc 0GlybsLdFA5FxD8Oj4c9Ezi1MVm/JWbMyoM7DLLiK9t94W5WCLc/vGDtIVat0Ljr3P Z7rMerABMnxKV+ZM8Lcn9f6PpXIFHt8Uk1zzvvDGCyKzIoUb6NlMhrFDkTfkF9ASnD SVM8+zCTbvW68VSi+iwdZupajE0GM4+UAnLThM78ChaM/itpNwsKopWjr1YSnoI2I8 e/ZScjCZsmPcA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 97EEB6814E; Sat, 18 Oct 2025 02:41:46 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id kh58-OcidMjL; Sat, 18 Oct 2025 02:41:46 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1760776905; bh=ckcDuRaxaWvqolqWzBmZXbeBex6mpBVAhKEsdA/4waQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J1SKTrcHU+qXKfoLoTjZFl2KmPupSVuxluFFJCPoV2bDIcEw5BVVUXpEu87P3x6M2 B2Xru5jEHdTkJiX1qQsQthuI2ITjyasXeyRABwW93c/cXHCNT5e/b8Jnk+/W3OohoR Jn5Amw01/d0wBb046+sI+EafDuhoKvJflJ9ydNxRUzyUXX0WlT51BtIwcaP+cjy538 mv94dbJce6i3mf9PfCOJ4A6tiVRhwScCOTybLhBYCp7rGV9eQ2vb8I1UFuUBJbSbWk 6QIRJPai4BB6iO+80Dhiqp0PxOcsGFC8TH7lturSNgi6GqyvJDG/X3LJjLOT/sdFst 2z5SoNnCfX9cQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id D0DB7681BC; Sat, 18 Oct 2025 02:41:44 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Sat, 18 Oct 2025 02:40:49 -0600 Message-ID: <20251018084117.1798704-5-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251018084117.1798704-1-sjg@u-boot.org> References: <20251018084117.1798704-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: SLIUUG7IN3ATPTCQKMP5ZDQTUVOFHN6A X-Message-ID-Hash: SLIUUG7IN3ATPTCQKMP5ZDQTUVOFHN6A X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass , Claude X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 04/24] bloblist: Provide a way to remove a blob List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add a function to remove a blob of a particular type. Signed-off-by: Simon Glass Co-developed-by: Claude --- common/bloblist.c | 32 +++++++++++++++++++++ include/bloblist.h | 12 ++++++++ test/common/bloblist.c | 64 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) diff --git a/common/bloblist.c b/common/bloblist.c index d1d7ddb956a..e5fa67b0f71 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -356,6 +356,38 @@ int bloblist_resize(uint tag, int new_size) return 0; } +int bloblist_remove(uint tag) +{ + struct bloblist_hdr *hdr = gd->bloblist; + struct bloblist_rec *rec; + ulong rec_start; /* offset where record starts */ + ulong next_ofs; /* offset of the record after @rec */ + ulong removed_size; /* total size to remove, including alignment */ + + rec = bloblist_findrec(tag); + if (!rec) + return log_msg_ret("find", -ENOENT); + + /* Calculate where this record starts and where the next one begins */ + rec_start = (void *)rec - (void *)hdr; + next_ofs = bloblist_blob_end_ofs(hdr, rec); + + /* Calculate total size to remove (record + alignment) */ + removed_size = next_ofs - rec_start; + + /* Move all following blobs backward to fill the gap */ + if (next_ofs < hdr->used_size) { + memmove((void *)hdr + rec_start, + (void *)hdr + next_ofs, + hdr->used_size - next_ofs); + } + + /* Update the used size */ + hdr->used_size -= removed_size; + + return 0; +} + static u32 bloblist_calc_chksum(struct bloblist_hdr *hdr) { u8 chksum; diff --git a/include/bloblist.h b/include/bloblist.h index e55d71110c3..ff88f4c8d5e 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -350,6 +350,18 @@ int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp); */ int bloblist_resize(uint tag, int new_size); +/** + * bloblist_remove() - remove a blob from the bloblist + * + * This removes the blob with the given tag from the bloblist. Any blobs after + * this one are relocated backward to fill the gap. The space is reclaimed and + * used_size is reduced accordingly. + * + * @tag: Tag to remove (enum bloblist_tag_t) + * Return: 0 if OK, -ENOENT if the tag is not found + */ +int bloblist_remove(uint tag); + /** * bloblist_new() - Create a new, empty bloblist of a given size * diff --git a/test/common/bloblist.c b/test/common/bloblist.c index 797bde27025..ad87b104d9c 100644 --- a/test/common/bloblist.c +++ b/test/common/bloblist.c @@ -605,3 +605,67 @@ static int bloblist_test_blob_maxsize(struct unit_test_state *uts) return 0; } BLOBLIST_TEST(bloblist_test_blob_maxsize, UFT_BLOBLIST); + +/* Test removing a blob */ +static int bloblist_test_remove(struct unit_test_state *uts) +{ + const uint small_size = 0x20; + struct bloblist_hdr *hdr; + void *blob1, *blob2, *blob3; + ulong used_before, used_after; + + clear_bloblist(); + ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); + hdr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE); + + /* Create three blobs */ + blob1 = bloblist_add(TEST_TAG, small_size, 0); + ut_assertnonnull(blob1); + strcpy(blob1, test1_str); + + blob2 = bloblist_add(TEST_TAG2, small_size, 0); + ut_assertnonnull(blob2); + strcpy(blob2, test2_str); + + blob3 = bloblist_add(TEST_TAG_MISSING, small_size, 0); + ut_assertnonnull(blob3); + + used_before = hdr->used_size; + + /* Remove the middle blob */ + ut_assertok(bloblist_remove(TEST_TAG2)); + + /* Check that the blob is gone */ + ut_assertnull(bloblist_find(TEST_TAG2, 0)); + + /* Check that the first blob is still there and intact */ + ut_asserteq_ptr(blob1, bloblist_find(TEST_TAG, small_size)); + ut_asserteq_str(test1_str, blob1); + + /* Check that the third blob is still there */ + ut_assertnonnull(bloblist_find(TEST_TAG_MISSING, small_size)); + + /* Check that used_size was reduced */ + used_after = hdr->used_size; + ut_assert(used_after < used_before); + + /* Try to remove a non-existent blob */ + ut_asserteq(-ENOENT, bloblist_remove(TEST_TAG2)); + + /* Remove the first blob */ + ut_assertok(bloblist_remove(TEST_TAG)); + ut_assertnull(bloblist_find(TEST_TAG, 0)); + + /* The third blob should still be accessible */ + ut_assertnonnull(bloblist_find(TEST_TAG_MISSING, small_size)); + + /* Remove the last blob */ + ut_assertok(bloblist_remove(TEST_TAG_MISSING)); + ut_assertnull(bloblist_find(TEST_TAG_MISSING, 0)); + + /* Check that we're back to just the header */ + ut_asserteq(sizeof(struct bloblist_hdr), hdr->used_size); + + return 0; +} +BLOBLIST_TEST(bloblist_test_remove, UFT_BLOBLIST);