// 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);
		module_put(luo_file->fh->ops->owner);

		xa_erase(&luo_preserved_files,
			 luo_get_id(luo_file->fh, luo_file->file));
		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);
	module_put(luo_file->fh->ops->owner);
}

/**
 * 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);
		}
		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));
}
