[PATCH v2 2/2] liveupdate: initialize incoming FLB state before finish
From: Leo Timmins
Date: Wed Mar 25 2026 - 00:47:20 EST
luo_flb_file_finish_one() decremented incoming.count before making sure
that the incoming FLB state had been materialized. If no earlier incoming
retrieval had populated that state, the first decrement ran from zero and
skipped the last-user finish path.
Initialize the incoming FLB state before the first decrement so finish
uses the serialized refcount instead of an uninitialized value.
v2 - now uses pr_warn instead of WARN_ON
Fixes: cab056f2aae7 ("liveupdate: luo_flb: introduce File-Lifecycle-Bound global state")
Signed-off-by: Leo Timmins <leotimmins1974@xxxxxxxxx>
---
kernel/liveupdate/luo_flb.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c
index f52e8114837e..855af655b09b 100644
--- a/kernel/liveupdate/luo_flb.c
+++ b/kernel/liveupdate/luo_flb.c
@@ -192,10 +192,27 @@ static int luo_flb_retrieve_one(struct liveupdate_flb *flb)
static void luo_flb_file_finish_one(struct liveupdate_flb *flb)
{
struct luo_flb_private *private = luo_flb_get_private(flb);
+ bool needs_retrieve = false;
u64 count;
- scoped_guard(mutex, &private->incoming.lock)
+ scoped_guard(mutex, &private->incoming.lock) {
+ if (!private->incoming.count && !private->incoming.finished)
+ needs_retrieve = true;
+ }
+
+ if (needs_retrieve) {
+ int err = luo_flb_retrieve_one(flb);
+
+ if (err) {
+ pr_warn("Failed to retrieve FLB '%s' during finish: %pe\n",
+ flb->compatible, ERR_PTR(err));
+ return;
+ }
+ }
+
+ scoped_guard(mutex, &private->incoming.lock) {
count = --private->incoming.count;
+ }
if (!count) {
struct liveupdate_flb_op_args args = {0};
--
2.53.0