// SPDX-License-Identifier: GPL-2.0

/*
 * Copyright (c) 2025, Google LLC.
 * Pasha Tatashin <pasha.tatashin@soleen.com>
 */

/**
 * DOC: LUO File Descriptors
 *
 * LUO provides the infrastructure to preserve specific, stateful file
 * descriptors across a kexec-based live update. The primary goal is to allow
 * workloads, such as virtual machines using vfio, memfd, or iommufd, to
 * retain access to their essential resources without interruption.
 *
 * The framework is built around a callback-based handler model and a well-
 * defined lifecycle for each preserved file.
 *
 * Handler Registration:
 * Kernel modules responsible for a specific file type (e.g., memfd, vfio)
 * register a &struct liveupdate_file_handler. This handler provides a set of
 * callbacks that LUO invokes at different stages of the update process, most
 * notably:
 *
 *   - can_preserve(): A lightweight check to determine if the handler is
 *     compatible with a given 'struct file'.
 *   - preserve(): The heavyweight operation that saves the file's state and
 *     returns an opaque u64 handle. This is typically performed while the
 *     workload is still active to minimize the downtime during the
 *     actual reboot transition.
 *   - unpreserve(): Cleans up any resources allocated by .preserve(), called
 *     if the preservation process is aborted before the reboot (i.e. session is
 *     closed).
 *   - freeze(): A final pre-reboot opportunity to prepare the state for kexec.
 *     We are already in reboot syscall, and therefore userspace cannot mutate
 *     the file anymore.
 *   - unfreeze(): Undoes the actions of .freeze(), called if the live update
 *     is aborted after the freeze phase.
 *   - retrieve(): Reconstructs the file in the new kernel from the preserved
 *     handle.
 *   - finish(): Performs final check and cleanup in the new kernel. After
 *     succesul finish call, LUO gives up ownership to this file.
 *
 * File Preservation Lifecycle happy path:
 *
 * 1. Preserve (Normal Operation): A userspace agent preserves files one by one
 *    via an ioctl. For each file, luo_preserve_file() finds a compatible
 *    handler, calls its .preserve() operation, and creates an internal &struct
 *    luo_file to track the live state.
 *
 * 2. Freeze (Pre-Reboot): Just before the kexec, luo_file_freeze() is called.
 *    It iterates through all preserved files, calls their respective .freeze()
 *    operation, and serializes their final metadata (compatible string, token,
 *    and data handle) into a contiguous memory block for KHO.
 *
 * 3. Deserialize: After kexec, luo_file_deserialize() runs when session gets
 *    deserialized (which is when /dev/liveupdate is first opened). It reads the
 *    serialized data from the KHO memory region and reconstructs the in-memory
 *    list of &struct luo_file instances for the new kernel, linking them to
 *    their corresponding handlers.
 *
 * 4. Retrieve (New Kernel - Userspace Ready): The userspace agent can now
 *    restore file descriptors by providing a token. luo_retrieve_file()
 *    searches for the matching token, calls the handler's .retrieve() op to
 *    re-create the 'struct file', and returns a new FD. Files can be
 *    retrieved in ANY order.
 *
 * 5. Finish (New Kernel - Cleanup): Once a session retrival is complete,
 *    luo_file_finish() is called. It iterates through all files, invokes their
 *    .finish() operations for final cleanup, and releases all associated kernel
 *    resources.
 *
 * File Preservation Lifecycle unhappy paths:
 *
 * 1. Abort Before Reboot: If the userspace agent aborts the live update
 *    process before calling reboot (e.g., by closing the session file
 *    descriptor), the session's release handler calls
 *    luo_file_unpreserve_files(). This invokes the .unpreserve() callback on
 *    all preserved files, ensuring all allocated resources are cleaned up and
 *    returning the system to a clean state.
 *
 * 2. Freeze Failure: During the reboot() syscall, if any handler's .freeze()
 *    op fails, the .unfreeze() op is invoked on all previously *successful*
 *    freezes to roll back their state. The reboot() syscall then returns an
 *    error to userspace, canceling the live update.
 *
 * 3. Finish Failure: In the new kernel, if a handler's .finish() op fails,
 *    the luo_file_finish() operation is aborted. LUO retains ownership of
 *    all files within that session, including those that were not yet
 *    processed. The userspace agent can attempt to call the finish operation
 *    again later. If the issue cannot be resolved, these resources will be held
 *    by LUO until the next live update cycle, at which point they will be
 *    discarded.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/cleanup.h>
#include <linux/compiler.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/kexec_handover.h>
#include <linux/kho/abi/luo.h>
#include <linux/list_private.h>
#include <linux/liveupdate.h>
#include <linux/module.h>
#include <linux/sizes.h>
#include <linux/xarray.h>
#include <linux/slab.h>
#include <linux/string.h>
#include "luo_internal.h"

static LIST_HEAD(luo_file_handler_list);

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

/* 2 4K pages, give space for 128 files per file_set */
#define LUO_FILE_PGCNT		2ul
#define LUO_FILE_MAX							\
	((LUO_FILE_PGCNT << PAGE_SHIFT) / sizeof(struct luo_file_ser))

/**
 * struct luo_file - Represents a single preserved file instance.
 * @fh:            Pointer to the &struct liveupdate_file_handler that manages
 *                 this type of file.
 * @file:          Pointer to the kernel's &struct file that is being preserved.
 *                 This is NULL in the new kernel until the file is successfully
 *                 retrieved.
 * @serialized_data: The opaque u64 handle to the serialized state of the file.
 *                 This handle is passed back to the handler's .freeze(),
 *                 .retrieve(), and .finish() callbacks, allowing it to track
 *                 and update its serialized state across phases.
 * @private_data:  Pointer to the private data for the file used to hold runtime
 *                 state that is not preserved. Set by the handler's .preserve()
 *                 callback, and must be freed in the handler's .unpreserve()
 *                 callback.
 * @retrieve_status: Status code indicating whether a user/kernel in the new kernel has
 *                 successfully called retrieve() on this file. This prevents
 *                 multiple retrieval attempts. A value of 0 means a retrieve()
 *                 has not been attempted, a positive value means the retrieve()
 *                 was successful, and a negative value means the retrieve()
 *                 failed, and the value is the error code of the call.
 * @mutex:         A mutex that protects the fields of this specific instance
 *                 (e.g., @retrieved, @file), ensuring that operations like
 *                 retrieving or finishing a file are atomic.
 * @list:          The list_head linking this instance into its parent
 *                 file_set's list of preserved files.
 * @token:         The user-provided unique token used to identify this file.
 *
 * This structure is the core in-kernel representation of a single file being
 * managed through a live update. An instance is created by luo_preserve_file()
 * to link a 'struct file' to its corresponding handler, a user-provided token,
 * and the serialized state handle returned by the handler's .preserve()
 * operation.
 *
 * These instances are tracked in a per-file_set list. The @serialized_data
 * field, which holds a handle to the file's serialized state, may be updated
 * during the .freeze() callback before being serialized for the next kernel.
 * After reboot, these structures are recreated by luo_file_deserialize() and
 * are finally cleaned up by luo_file_finish().
 */
struct luo_file {
	struct liveupdate_file_handler *fh;
	struct file *file;
	u64 serialized_data;
	void *private_data;
	int retrieve_status;
	struct mutex mutex;
	struct list_head list;
	u64 token;
};

static int luo_alloc_files_mem(struct luo_file_set *file_set)
{
	size_t size;
	void *mem;

	if (file_set->files)
		return 0;

	WARN_ON_ONCE(file_set->count);

	size = LUO_FILE_PGCNT << PAGE_SHIFT;
	mem = kho_alloc_preserve(size);
	if (IS_ERR(mem))
		return PTR_ERR(mem);

	file_set->files = mem;

	return 0;
}

static void luo_free_files_mem(struct luo_file_set *file_set)
{
	/* If file_set has files, no need to free preservation memory */
	if (file_set->count)
		return;

	if (!file_set->files)
		return;

	kho_unpreserve_free(file_set->files);
	file_set->files = NULL;
}

static unsigned long luo_get_id(struct liveupdate_file_handler *fh,
				struct file *file)
{
	return fh->ops->get_id ? fh->ops->get_id(file) : (unsigned long)file;
}

static bool luo_token_is_used(struct luo_file_set *file_set, u64 token)
{
	struct luo_file *iter;

	list_for_each_entry(iter, &file_set->files_list, list) {
		if (iter->token == token)
			return true;
	}

	return false;
}

/**
 * luo_preserve_file - Initiate the preservation of a file descriptor.
 * @file_set: The file_set to which the preserved file will be added.
 * @token:    A unique, user-provided identifier for the file.
 * @fd:       The file descriptor to be preserved.
 *
 * This function orchestrates the first phase of preserving a file. Upon entry,
 * it takes a reference to the 'struct file' via fget(), effectively making LUO
 * a co-owner of the file. This reference is held until the file is either
 * unpreserved or successfully finished in the next kernel, preventing the file
 * from being prematurely destroyed.
 *
 * This function orchestrates the first phase of preserving a file. It performs
 * the following steps:
 *
 * 1. Validates that the @token is not already in use within the file_set.
 * 2. Ensures the file_set's memory for files serialization is allocated
 *    (allocates if needed).
 * 3. Iterates through registered handlers, calling can_preserve() to find one
 *    compatible with the given @fd.
 * 4. Calls the handler's .preserve() operation, which saves the file's state
 *    and returns an opaque private data handle.
 * 5. Adds the new instance to the file_set's internal list.
 *
 * On success, LUO takes a reference to the 'struct file' and considers it
 * under its management until it is unpreserved or finished.
 *
 * In case of any failure, all intermediate allocations (file reference, memory
 * for the 'luo_file' struct, etc.) are cleaned up before returning an error.
 *
 * Context: Can be called from an ioctl handler during normal system operation.
 * Return: 0 on success. Returns a negative errno on failure:
 *         -EEXIST if the token is already used.
 *         -EBUSY if the file descriptor is already preserved by another session.
 *         -EBADF if the file descriptor is invalid.
 *         -ENOSPC if the file_set is full.
 *         -ENOENT if no compatible handler is found.
 *         -ENOMEM on memory allocation failure.
 *         Other erros might be returned by .preserve().
 */
int luo_preserve_file(struct luo_file_set *file_set, u64 token, int fd)
{
	struct liveupdate_file_op_args args = {0};
	struct liveupdate_file_handler *fh;
	struct luo_file *luo_file;
	struct file *file;
	int err;

	if (luo_token_is_used(file_set, token))
		return -EEXIST;

	if (file_set->count == LUO_FILE_MAX)
		return -ENOSPC;

	file = fget(fd);
	if (!file)
		return -EBADF;

	err = luo_alloc_files_mem(file_set);
	if (err)
		goto  err_fput;

	err = -ENOENT;
	down_read(&luo_register_rwlock);
	list_private_for_each_entry(fh, &luo_file_handler_list, list) {
		if (fh->ops->can_preserve(fh, file)) {
			if (try_module_get(fh->ops->owner))
				err = 0;
			break;
		}
	}
	up_read(&luo_register_rwlock);

	/* err is still -ENOENT if no handler was found */
	if (err)
		goto err_free_files_mem;

	err = xa_insert(&luo_preserved_files, luo_get_id(fh, file),
			file, GFP_KERNEL);
	if (err)
		goto err_module_put;

	err = luo_flb_file_preserve(fh);
	if (err)
		goto err_erase_xa;

	luo_file = kzalloc_obj(*luo_file);
	if (!luo_file) {
		err = -ENOMEM;
		goto err_flb_unpreserve;
	}

	luo_file->file = file;
	luo_file->fh = fh;
	luo_file->token = token;
	mutex_init(&luo_file->mutex);

	args.handler = fh;
	args.file = file;
	err = fh->ops->preserve(&args);
	if (err)
		goto err_kfree;

	luo_file->serialized_data = args.serialized_data;
	luo_file->private_data = args.private_data;
	list_add_tail(&luo_file->list, &file_set->files_list);
	file_set->count++;

	return 0;

err_kfree:
	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_module_put:
	module_put(fh->ops->owner);
err_free_files_mem:
	luo_free_files_mem(file_set);
err_fput:
	fput(file);

	return err;
}

/**
 * luo_file_unpreserve_files - Unpreserves all files from a file_set.
 * @file_set: The files to be cleaned up.
 *
 * This function serves as the primary cleanup path for a file_set. It is
 * invoked when the userspace agent closes the file_set's file descriptor.
 *
 * For each file, it performs the following cleanup actions:
 *   1. Calls the handler's .unpreserve() callback to allow the handler to
 *      release any resources it allocated.
 *   2. Removes the file from the file_set's internal tracking list.
 *   3. Releases the reference to the 'struct file' that was taken by
 *      luo_preserve_file() via fput(), returning ownership.
 *   4. Frees the memory associated with the internal 'struct luo_file'.
 *
 * After all individual files are unpreserved, it frees the contiguous memory
 * block that was allocated to hold their serialization data.
 */
void luo_file_unpreserve_files(struct luo_file_set *file_set)
{
	struct luo_file *luo_file;

	while (!list_empty(&file_set->files_list)) {
		struct liveupdate_file_op_args args = {0};

		luo_file = list_last_entry(&file_set->files_list,
					   struct luo_file, list);

		args.handler = luo_file->fh;
		args.file = luo_file->file;
		args.serialized_data = luo_file->serialized_data;
		args.private_data = luo_file->private_data;
		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));
		module_put(luo_file->fh->ops->owner);

		list_del(&luo_file->list);
		file_set->count--;

		fput(luo_file->file);
		mutex_destroy(&luo_file->mutex);
		kfree(luo_file);
	}

	luo_free_files_mem(file_set);
}

static int luo_file_freeze_one(struct luo_file_set *file_set,
			       struct luo_file *luo_file)
{
	int err = 0;

	guard(mutex)(&luo_file->mutex);

	if (luo_file->fh->ops->freeze) {
		struct liveupdate_file_op_args args = {0};

		args.handler = luo_file->fh;
		args.file = luo_file->file;
		args.serialized_data = luo_file->serialized_data;
		args.private_data = luo_file->private_data;

		err = luo_file->fh->ops->freeze(&args);
		if (!err)
			luo_file->serialized_data = args.serialized_data;
	}

	return err;
}

static void luo_file_unfreeze_one(struct luo_file_set *file_set,
				  struct luo_file *luo_file)
{
	guard(mutex)(&luo_file->mutex);

	if (luo_file->fh->ops->unfreeze) {
		struct liveupdate_file_op_args args = {0};

		args.handler = luo_file->fh;
		args.file = luo_file->file;
		args.serialized_data = luo_file->serialized_data;
		args.private_data = luo_file->private_data;

		luo_file->fh->ops->unfreeze(&args);
	}
}

static void __luo_file_unfreeze(struct luo_file_set *file_set,
				struct luo_file *failed_entry)
{
	struct list_head *files_list = &file_set->files_list;
	struct luo_file *luo_file;

	list_for_each_entry(luo_file, files_list, list) {
		if (luo_file == failed_entry)
			break;

		luo_file_unfreeze_one(file_set, luo_file);
	}

	memset(file_set->files, 0, LUO_FILE_PGCNT << PAGE_SHIFT);
}

/**
 * luo_file_freeze - Freezes all preserved files and serializes their metadata.
 * @file_set:     The file_set whose files are to be frozen.
 * @file_set_ser: Where to put the serialized file_set.
 *
 * This function is called from the reboot() syscall path, just before the
 * kernel transitions to the new image via kexec. Its purpose is to perform the
 * final preparation and serialization of all preserved files in the file_set.
 *
 * It iterates through each preserved file in FIFO order (the order of
 * preservation) and performs two main actions:
 *
 * 1. Freezes the File: It calls the handler's .freeze() callback for each
 *    file. This gives the handler a final opportunity to quiesce the device or
 *    prepare its state for the upcoming reboot. The handler may update its
 *    private data handle during this step.
 *
 * 2. Serializes Metadata: After a successful freeze, it copies the final file
 *    metadata—the handler's compatible string, the user token, and the final
 *    private data handle—into the pre-allocated contiguous memory buffer
 *    (file_set->files) that will be handed over to the next kernel via KHO.
 *
 * Error Handling (Rollback):
 * This function is atomic. If any handler's .freeze() operation fails, the
 * entire live update is aborted. The __luo_file_unfreeze() helper is
 * immediately called to invoke the .unfreeze() op on all files that were
 * successfully frozen before the point of failure, rolling them back to a
 * running state. The function then returns an error, causing the reboot()
 * syscall to fail.
 *
 * Context: Called only from the liveupdate_reboot() path.
 * Return: 0 on success, or a negative errno on failure.
 */
int luo_file_freeze(struct luo_file_set *file_set,
		    struct luo_file_set_ser *file_set_ser)
{
	struct luo_file_ser *file_ser = file_set->files;
	struct luo_file *luo_file;
	int err;
	int i;

	if (!file_set->count)
		return 0;

	if (WARN_ON(!file_ser))
		return -EINVAL;

	i = 0;
	list_for_each_entry(luo_file, &file_set->files_list, list) {
		err = luo_file_freeze_one(file_set, luo_file);
		if (err < 0) {
			pr_warn("Freeze failed for token[%#0llx] handler[%s] err[%pe]\n",
				luo_file->token, luo_file->fh->compatible,
				ERR_PTR(err));
			goto err_unfreeze;
		}

		strscpy(file_ser[i].compatible, luo_file->fh->compatible,
			sizeof(file_ser[i].compatible));
		file_ser[i].data = luo_file->serialized_data;
		file_ser[i].token = luo_file->token;
		i++;
	}

	file_set_ser->count = file_set->count;
	if (file_set->files)
		file_set_ser->files = virt_to_phys(file_set->files);

	return 0;

err_unfreeze:
	__luo_file_unfreeze(file_set, luo_file);

	return err;
}

/**
 * luo_file_unfreeze - Unfreezes all files in a file_set and clear serialization
 * @file_set:     The file_set whose files are to be unfrozen.
 * @file_set_ser: Serialized file_set.
 *
 * This function rolls back the state of all files in a file_set after the
 * freeze phase has begun but must be aborted. It is the counterpart to
 * luo_file_freeze().
 *
 * It invokes the __luo_file_unfreeze() helper with a NULL argument, which
 * signals the helper to iterate through all files in the file_set and call
 * their respective .unfreeze() handler callbacks.
 *
 * Context: This is called when the live update is aborted during
 *          the reboot() syscall, after luo_file_freeze() has been called.
 */
void luo_file_unfreeze(struct luo_file_set *file_set,
		       struct luo_file_set_ser *file_set_ser)
{
	if (!file_set->count)
		return;

	__luo_file_unfreeze(file_set, NULL);
	memset(file_set_ser, 0, sizeof(*file_set_ser));
}

/**
 * luo_retrieve_file - Restores a preserved file from a file_set by its token.
 * @file_set: The file_set from which to retrieve the file.
 * @token:    The unique token identifying the file to be restored.
 * @filep:    Output parameter; on success, this is populated with a pointer
 *            to the newly retrieved 'struct file'.
 *
 * This function is the primary mechanism for recreating a file in the new
 * kernel after a live update. It searches the file_set's list of deserialized
 * files for an entry matching the provided @token.
 *
 * The operation is idempotent: if a file has already been successfully
 * retrieved, this function will simply return a pointer to the existing
 * 'struct file' and report success without re-executing the retrieve
 * operation. This is handled by checking the 'retrieved' flag under a lock.
 *
 * File retrieval can happen in any order; it is not bound by the order of
 * preservation.
 *
 * Context: Can be called from an ioctl or other in-kernel code in the new
 *          kernel.
 * Return: 0 on success. Returns a negative errno on failure:
 *         -ENOENT if no file with the matching token is found.
 *         Any error code returned by the handler's .retrieve() op.
 */
int luo_retrieve_file(struct luo_file_set *file_set, u64 token,
		      struct file **filep)
{
	struct liveupdate_file_op_args args = {0};
	struct luo_file *luo_file;
	bool found = false;
	int err;

	if (list_empty(&file_set->files_list))
		return -ENOENT;

	list_for_each_entry(luo_file, &file_set->files_list, list) {
		if (luo_file->token == token) {
			found = true;
			break;
		}
	}

	if (!found)
		return -ENOENT;

	guard(mutex)(&luo_file->mutex);
	if (luo_file->retrieve_status < 0) {
		/* Retrieve was attempted and it failed. Return the error code. */
		return luo_file->retrieve_status;
	}

	if (luo_file->retrieve_status > 0) {
		/*
		 * Someone is asking for this file again, so get a reference
		 * for them.
		 */
		get_file(luo_file->file);
		*filep = luo_file->file;
		return 0;
	}

	args.handler = luo_file->fh;
	args.serialized_data = luo_file->serialized_data;
	err = luo_file->fh->ops->retrieve(&args);
	if (err) {
		/* Keep the error code for later use. */
		luo_file->retrieve_status = err;
		return err;
	}

	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,
			  luo_get_id(luo_file->fh, luo_file->file),
			  luo_file->file, GFP_KERNEL));

	*filep = luo_file->file;
	luo_file->retrieve_status = 1;

	return 0;
}

static int luo_file_can_finish_one(struct luo_file_set *file_set,
				   struct luo_file *luo_file)
{
	bool can_finish = true;

	guard(mutex)(&luo_file->mutex);

	if (luo_file->fh->ops->can_finish) {
		struct liveupdate_file_op_args args = {0};

		args.handler = luo_file->fh;
		args.file = luo_file->file;
		args.serialized_data = luo_file->serialized_data;
		args.retrieve_status = luo_file->retrieve_status;
		can_finish = luo_file->fh->ops->can_finish(&args);
	}

	return can_finish ? 0 : -EBUSY;
}

static void luo_file_finish_one(struct luo_file_set *file_set,
				struct luo_file *luo_file)
{
	struct liveupdate_file_op_args args = {0};

	guard(mutex)(&luo_file->mutex);

	args.handler = luo_file->fh;
	args.file = luo_file->file;
	args.serialized_data = luo_file->serialized_data;
	args.retrieve_status = luo_file->retrieve_status;

	luo_file->fh->ops->finish(&args);
	luo_flb_file_finish(luo_file->fh);
}

/**
 * luo_file_finish - Completes the lifecycle for all files in a file_set.
 * @file_set: The file_set to be finalized.
 *
 * This function orchestrates the final teardown of a live update file_set in
 * the new kernel. It should be called after all necessary files have been
 * retrieved and the userspace agent is ready to release the preserved state.
 *
 * The function iterates through all tracked files. For each file, it performs
 * the following sequence of cleanup actions:
 *
 * 1. If file is not yet retrieved, retrieves it, and calls can_finish() on
 *    every file in the file_set. If all can_finish return true, continue to
 *    finish.
 * 2. Calls the handler's .finish() callback (via luo_file_finish_one) to
 *    allow for final resource cleanup within the handler.
 * 3. Releases LUO's ownership reference on the 'struct file' via fput(). This
 *    is the counterpart to the get_file() call in luo_retrieve_file().
 * 4. Removes the 'struct luo_file' from the file_set's internal list.
 * 5. Frees the memory for the 'struct luo_file' instance itself.
 *
 * After successfully finishing all individual files, it frees the
 * contiguous memory block that was used to transfer the serialized metadata
 * from the previous kernel.
 *
 * Error Handling (Atomic Failure):
 * This operation is atomic. If any handler's .can_finish() op fails, the entire
 * function aborts immediately and returns an error.
 *
 * Context: Can be called from an ioctl handler in the new kernel.
 * Return: 0 on success, or a negative errno on failure.
 */
int luo_file_finish(struct luo_file_set *file_set)
{
	struct list_head *files_list = &file_set->files_list;
	struct luo_file *luo_file;
	int err;

	if (!file_set->count)
		return 0;

	list_for_each_entry(luo_file, files_list, list) {
		err = luo_file_can_finish_one(file_set, luo_file);
		if (err)
			return err;
	}

	while (!list_empty(&file_set->files_list)) {
		luo_file = list_last_entry(&file_set->files_list,
					   struct luo_file, list);

		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));
			fput(luo_file->file);
		}
		module_put(luo_file->fh->ops->owner);
		list_del(&luo_file->list);
		file_set->count--;
		mutex_destroy(&luo_file->mutex);
		kfree(luo_file);
	}

	if (file_set->files) {
		kho_restore_free(file_set->files);
		file_set->files = NULL;
	}

	return 0;
}

/**
 * luo_file_deserialize - Reconstructs the list of preserved files in the new kernel.
 * @file_set:     The incoming file_set to fill with deserialized data.
 * @file_set_ser: Serialized KHO file_set data from the previous kernel.
 *
 * This function is called during the early boot process of the new kernel. It
 * takes the raw, contiguous memory block of 'struct luo_file_ser' entries,
 * provided by the previous kernel, and transforms it back into a live,
 * in-memory linked list of 'struct luo_file' instances.
 *
 * For each serialized entry, it performs the following steps:
 *   1. Reads the 'compatible' string.
 *   2. Searches the global list of registered file handlers for one that
 *      matches the compatible string.
 *   3. Allocates a new 'struct luo_file'.
 *   4. Populates the new structure with the deserialized data (token, private
 *      data handle) and links it to the found handler. The 'file' pointer is
 *      initialized to NULL, as the file has not been retrieved yet.
 *   5. Adds the new 'struct luo_file' to the file_set's files_list.
 *
 * This prepares the file_set for userspace, which can later call
 * luo_retrieve_file() to restore the actual file descriptors.
 *
 * Context: Called from session deserialization.
 */
int luo_file_deserialize(struct luo_file_set *file_set,
			 struct luo_file_set_ser *file_set_ser)
{
	struct luo_file_ser *file_ser;
	u64 i;

	if (!file_set_ser->files) {
		WARN_ON(file_set_ser->count);
		return 0;
	}

	file_set->count = file_set_ser->count;
	file_set->files = phys_to_virt(file_set_ser->files);

	/*
	 * Note on error handling:
	 *
	 * If deserialization fails (e.g., allocation failure or corrupt data),
	 * we intentionally skip cleanup of files that were already restored.
	 *
	 * A partial failure leaves the preserved state inconsistent.
	 * Implementing a safe "undo" to unwind complex dependencies (sessions,
	 * files, hardware state) is error-prone and provides little value, as
	 * the system is effectively in a broken state.
	 *
	 * We treat these resources as leaked. The expected recovery path is for
	 * userspace to detect the failure and trigger a reboot, which will
	 * reliably reset devices and reclaim memory.
	 */
	file_ser = file_set->files;
	for (i = 0; i < file_set->count; i++) {
		struct liveupdate_file_handler *fh;
		bool handler_found = false;
		struct luo_file *luo_file;

		down_read(&luo_register_rwlock);
		list_private_for_each_entry(fh, &luo_file_handler_list, list) {
			if (!strcmp(fh->compatible, file_ser[i].compatible)) {
				if (try_module_get(fh->ops->owner))
					handler_found = true;
				break;
			}
		}
		up_read(&luo_register_rwlock);

		if (!handler_found) {
			pr_warn("No registered handler for compatible '%.*s'\n",
				(int)sizeof(file_ser[i].compatible),
				file_ser[i].compatible);
			return -ENOENT;
		}

		luo_file = kzalloc_obj(*luo_file);
		if (!luo_file) {
			module_put(fh->ops->owner);
			return -ENOMEM;
		}

		luo_file->fh = fh;
		luo_file->file = NULL;
		luo_file->serialized_data = file_ser[i].data;
		luo_file->token = file_ser[i].token;
		mutex_init(&luo_file->mutex);
		list_add_tail(&luo_file->list, &file_set->files_list);
	}

	return 0;
}

void luo_file_set_init(struct luo_file_set *file_set)
{
	INIT_LIST_HEAD(&file_set->files_list);
}

void luo_file_set_destroy(struct luo_file_set *file_set)
{
	WARN_ON(file_set->count);
	WARN_ON(!list_empty(&file_set->files_list));
}

/**
 * liveupdate_register_file_handler - Register a file handler with LUO.
 * @fh: Pointer to a caller-allocated &struct liveupdate_file_handler.
 * The caller must initialize this structure, including a unique
 * 'compatible' string and a valid 'fh' callbacks. This function adds the
 * handler to the global list of supported file handlers.
 *
 * Context: Typically called during module initialization for file types that
 * support live update preservation.
 *
 * Return: 0 on success. Negative errno on failure.
 */
int liveupdate_register_file_handler(struct liveupdate_file_handler *fh)
{
	struct liveupdate_file_handler *fh_iter;
	int err;

	if (!liveupdate_enabled())
		return -EOPNOTSUPP;

	/* Sanity check that all required callbacks are set */
	if (!fh->ops->preserve || !fh->ops->unpreserve || !fh->ops->retrieve ||
	    !fh->ops->finish || !fh->ops->can_preserve) {
		return -EINVAL;
	}

	down_write(&luo_register_rwlock);
	/* Check for duplicate compatible strings */
	list_private_for_each_entry(fh_iter, &luo_file_handler_list, list) {
		if (!strcmp(fh_iter->compatible, fh->compatible)) {
			pr_err("File handler registration failed: Compatible string '%s' already registered.\n",
			       fh->compatible);
			err = -EEXIST;
			goto err_unlock;
		}
	}

	INIT_LIST_HEAD(&ACCESS_PRIVATE(fh, flb_list));
	INIT_LIST_HEAD(&ACCESS_PRIVATE(fh, list));
	list_add_tail(&ACCESS_PRIVATE(fh, list), &luo_file_handler_list);
	up_write(&luo_register_rwlock);

	liveupdate_test_register(fh);

	return 0;

err_unlock:
	up_write(&luo_register_rwlock);
	return err;
}

/**
 * liveupdate_unregister_file_handler - Unregister a liveupdate file handler
 * @fh: The file handler to unregister
 *
 * Unregisters the file handler from the liveupdate core. This function
 * reverses the operations of liveupdate_register_file_handler().
 */
void liveupdate_unregister_file_handler(struct liveupdate_file_handler *fh)
{
	if (!liveupdate_enabled())
		return;

	guard(rwsem_write)(&luo_register_rwlock);
	luo_flb_unregister_all(fh);
	list_del(&ACCESS_PRIVATE(fh, list));
}
