Re: [PATCH v3 0/2] liveupdate: prevent double preservation

Andrew Morton
2026-03-25T23:14:09Z

On Wed, 25 Mar 2026 18:20:24 +0000 Pasha Tatashin <pasha.tatashin@soleen.com> wrote:

> Currently, LUO does not prevent the same file from being preserved twice
> across different active sessions.
>
> Because LUO preserves files of absolutely different types: memfd, and
> upcoming vfiofd [1], iommufd [2], guestmefd (and possible kvmfd/cpufd).
> There is no common private data or guarantee on how to prevent that the
> same file is not preserved twice beside using inode or some slower and
> expensive method like hashtables.
>

I updated mm.git's mm-new branch to this version.

> Changelog:
> v3:
> - Renamed luo_preserved_files_xa to luo_preserved_files (Mike)
> - Added xa inserts during restoration, so a file that is not yet finished is
> not preserved at the same time. (Sashiko)

Below is how v3 altered mm.git.

It appears that some significant changes are in the works. Please lmk
if there's actually value in keeping v3 under test, or should I just
drop it?

kernel/liveupdate/luo_file.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)

--- a/kernel/liveupdate/luo_file.c~b
+++ a/kernel/liveupdate/luo_file.c
@@ -117,7 +117,7 @@ static DECLARE_RWSEM(luo_file_handler_lo
static LIST_HEAD(luo_file_handler_list);

/* Keep track of files being preserved by LUO */
-static DEFINE_XARRAY(luo_preserved_files_xa);
+static DEFINE_XARRAY(luo_preserved_files);

/* 2 4K pages, give space for 128 files per file_set */
#define LUO_FILE_PGCNT 2ul
@@ -282,7 +282,7 @@ int luo_preserve_file(struct luo_file_se
if (err)
goto err_fput;

- err = xa_insert(&luo_preserved_files_xa, (unsigned long)file,
+ err = xa_insert(&luo_preserved_files, (unsigned long)file,
file, GFP_KERNEL);
if (err)
goto err_free_files_mem;
@@ -334,7 +334,7 @@ err_kfree:
err_flb_unpreserve:
luo_flb_file_unpreserve(fh);
err_erase_xa:
- xa_erase(&luo_preserved_files_xa, (unsigned long)file);
+ xa_erase(&luo_preserved_files, (unsigned long)file);
err_free_files_mem:
luo_free_files_mem(file_set);
err_fput:
@@ -378,7 +378,7 @@ void luo_file_unpreserve_files(struct lu
luo_file->fh->ops->unpreserve(&args);
luo_flb_file_unpreserve(luo_file->fh);

- xa_erase(&luo_preserved_files_xa, (unsigned long)luo_file->file);
+ xa_erase(&luo_preserved_files, (unsigned long)luo_file->file);
list_del(&luo_file->list);
file_set->count--;

@@ -622,6 +622,10 @@ int luo_retrieve_file(struct luo_file_se
luo_file->file = args.file;
/* Get reference so we can keep this file in LUO until finish */
get_file(luo_file->file);
+
+ WARN_ON(xa_insert(&luo_preserved_files, (unsigned long)luo_file->file,
+ luo_file->file, GFP_KERNEL));
+
*filep = luo_file->file;
luo_file->retrieve_status = 1;

@@ -717,8 +721,11 @@ int luo_file_finish(struct luo_file_set

luo_file_finish_one(file_set, luo_file);

- if (luo_file->file)
+ if (luo_file->file) {
+ xa_erase(&luo_preserved_files,
+ (unsigned long)luo_file->file);
fput(luo_file->file);
+ }
list_del(&luo_file->list);
file_set->count--;
mutex_destroy(&luo_file->mutex);
_