[PATCH v4 07/19] liveupdate: Add helpers to track the files that LUO manages

From: David Matlack

Date: Tue Nov 10 2026 - 19:26:40 EST


Add luo_track_file() and luo_untrack_file(), which add a file to and
remove it from luo_preserved_files, and use them instead of open-coding
xa_insert() and xa_erase() with luo_get_id() for preserved and retrieved
files.

The next commit lets file handlers make LUO track the file they retrieve
into, which adds more users. The helpers keep the key and the -EBUSY
behavior in one place.

No functional change intended.

Signed-off-by: David Matlack <dmatlack@xxxxxxxxxx>
---
kernel/liveupdate/luo_file.c | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c
index e5d333649f76..91a2b74f71cb 100644
--- a/kernel/liveupdate/luo_file.c
+++ b/kernel/liveupdate/luo_file.c
@@ -192,6 +192,19 @@ static unsigned long luo_get_id(struct liveupdate_file_handler *fh,
return fh->ops->get_id ? fh->ops->get_id(file) : (unsigned long)file;
}

+/* Make LUO manage @file, or fail with -EBUSY if it already does. */
+static int luo_track_file(struct liveupdate_file_handler *fh, struct file *file)
+{
+ return xa_insert(&luo_preserved_files, luo_get_id(fh, file), file,
+ GFP_KERNEL);
+}
+
+static void luo_untrack_file(struct liveupdate_file_handler *fh,
+ struct file *file)
+{
+ xa_erase(&luo_preserved_files, luo_get_id(fh, file));
+}
+
static bool luo_token_is_used(struct luo_file_set *file_set, u64 token)
{
struct luo_file *iter;
@@ -306,14 +319,13 @@ int luo_preserve_file(struct luo_file_set *file_set, u64 token, int fd,
if (err)
goto err_module_put;

- err = xa_insert(&luo_preserved_files, luo_get_id(fh, file),
- file, GFP_KERNEL);
+ err = luo_track_file(fh, file);
if (err)
goto err_free_arg;

err = luo_flb_file_preserve(fh);
if (err)
- goto err_erase_xa;
+ goto err_untrack;

luo_file = kzalloc_obj(*luo_file);
if (!luo_file) {
@@ -345,8 +357,8 @@ int luo_preserve_file(struct luo_file_set *file_set, u64 token, int fd,
kfree(luo_file);
err_flb_unpreserve:
luo_flb_file_unpreserve(fh);
-err_erase_xa:
- xa_erase(&luo_preserved_files, luo_get_id(fh, file));
+err_untrack:
+ luo_untrack_file(fh, file);
err_free_arg:
kfree(args.arg);
err_module_put:
@@ -395,8 +407,7 @@ void luo_file_unpreserve_files(struct luo_file_set *file_set)
luo_file->fh->ops->unpreserve(&args);
luo_flb_file_unpreserve(luo_file->fh);

- xa_erase(&luo_preserved_files,
- luo_get_id(luo_file->fh, luo_file->file));
+ luo_untrack_file(luo_file->fh, luo_file->file);
module_put(luo_file->fh->ops->owner);

list_del(&luo_file->list);
@@ -668,9 +679,7 @@ int luo_retrieve_file(struct luo_file_set *file_set, u64 token,
return err;
}

- err = xa_insert(&luo_preserved_files,
- luo_get_id(luo_file->fh, args.file), args.file,
- GFP_KERNEL);
+ err = luo_track_file(luo_file->fh, args.file);
if (err) {
/* A retrieved file is new, so it can't be tracked already. */
WARN_ON_ONCE(err == -EBUSY);
@@ -788,8 +797,7 @@ int luo_file_finish(struct luo_file_set *file_set)
luo_file_finish_one(file_set, luo_file);

if (luo_file->file) {
- xa_erase(&luo_preserved_files,
- luo_get_id(luo_file->fh, luo_file->file));
+ luo_untrack_file(luo_file->fh, luo_file->file);
fput(luo_file->file);
}
module_put(luo_file->fh->ops->owner);
--
2.56.0.542.g3ef89b7020-goog