[PATCH 3/3] liveupdate: initialize incoming FLB state before finish

From: Leo Timmins

Date: Tue Mar 24 2026 - 14:07:40 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.

Fixes: cab056f2aae7 ("liveupdate: luo_flb: introduce File-Lifecycle-Bound global state")

Signed-off-by: Leo Timmins <leotimmins1974@xxxxxxxxx>
---
kernel/liveupdate/luo_flb.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c
index f52e8114837e..49fed585e965 100644
--- a/kernel/liveupdate/luo_flb.c
+++ b/kernel/liveupdate/luo_flb.c
@@ -192,10 +192,24 @@ 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 (WARN_ON(err))
+ return;
+ }
+
+ scoped_guard(mutex, &private->incoming.lock) {
count = --private->incoming.count;
+ }

if (!count) {
struct liveupdate_flb_op_args args = {0};
--
2.53.0