Hi,

I am sorry for incorrect layout of this series. After copy-pasting
I forgot to change the message id in header and the cover letter is not
attached to the same thread.

Please find the V2 cover letter here:
https://lore.kernel.org/all/[email protected]/

Also for latest discussion related to scope:
https://lore.kernel.org/all/[email protected]/

Thankyou

Tarun Sahu <[email protected]> writes:

> From: Pasha Tatashin <[email protected]>
>
> The core liveupdate mechanism allows userspace to preserve file
> descriptors. However, kernel subsystems often manage struct file
> objects directly and need to participate in the preservation process
> programmatically without relying solely on userspace interaction.
>
> Signed-off-by: Pasha Tatashin <[email protected]>
> Signed-off-by: Samiullah Khawaja <[email protected]>
> Signed-off-by: Tarun Sahu <[email protected]>
> ---
>  include/linux/liveupdate.h       | 21 ++++++++++
>  kernel/liveupdate/luo_file.c     | 69 ++++++++++++++++++++++++++++++++
>  kernel/liveupdate/luo_internal.h | 17 ++++++++
>  3 files changed, 107 insertions(+)
>
> diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h
> index 30c5a39ff9e9..de052438eaac 100644
> --- a/include/linux/liveupdate.h
> +++ b/include/linux/liveupdate.h
> @@ -24,6 +24,7 @@ struct file;
>  /**
>   * struct liveupdate_file_op_args - Arguments for file operation callbacks.
>   * @handler:          The file handler being called.
> + * @session:          The session this file belongs to.
>   * @retrieve_status:  The retrieve status for the 'can_finish / finish'
>   *                    operation. A value of 0 means the retrieve has not been
>   *                    attempted, a positive value means the retrieve was
> @@ -44,6 +45,7 @@ struct file;
>   */
>  struct liveupdate_file_op_args {
>       struct liveupdate_file_handler *handler;
> +     struct liveupdate_session *session;
>       int retrieve_status;
>       struct file *file;
>       u64 serialized_data;
> @@ -240,6 +242,13 @@ void liveupdate_unregister_flb(struct 
> liveupdate_file_handler *fh,
>  
>  int liveupdate_flb_get_incoming(struct liveupdate_flb *flb, void **objp);
>  int liveupdate_flb_get_outgoing(struct liveupdate_flb *flb, void **objp);
> +/* kernel can internally retrieve files */
> +int liveupdate_get_file_incoming(struct liveupdate_session *s, u64 token,
> +                              struct file **filep);
> +
> +/* Get a token for an outgoing file, or -ENOENT if file is not preserved */
> +int liveupdate_get_token_outgoing(struct liveupdate_session *s,
> +                               struct file *file, u64 *tokenp);
>  
>  #else /* CONFIG_LIVEUPDATE */
>  
> @@ -285,5 +294,17 @@ static inline int liveupdate_flb_get_outgoing(struct 
> liveupdate_flb *flb,
>       return -EOPNOTSUPP;
>  }
>  
> +static inline int liveupdate_get_file_incoming(struct liveupdate_session *s,
> +                                            u64 token, struct file **filep)
> +{
> +     return -EOPNOTSUPP;
> +}
> +
> +static inline int liveupdate_get_token_outgoing(struct liveupdate_session *s,
> +                                             struct file *file, u64 *tokenp)
> +{
> +     return -EOPNOTSUPP;
> +}
> +
>  #endif /* CONFIG_LIVEUPDATE */
>  #endif /* _LINUX_LIVEUPDATE_H */
> diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c
> index a0a419085e28..0aa0b4e5339f 100644
> --- a/kernel/liveupdate/luo_file.c
> +++ b/kernel/liveupdate/luo_file.c
> @@ -323,6 +323,7 @@ int luo_preserve_file(struct luo_file_set *file_set, u64 
> token, int fd)
>       mutex_init(&luo_file->mutex);
>  
>       args.handler = fh;
> +     args.session = luo_session_from_file_set(file_set);
>       args.file = file;
>       err = fh->ops->preserve(&args);
>       if (err)
> @@ -380,6 +381,7 @@ void luo_file_unpreserve_files(struct luo_file_set 
> *file_set)
>                                          struct luo_file, list);
>  
>               args.handler = luo_file->fh;
> +             args.session = luo_session_from_file_set(file_set);
>               args.file = luo_file->file;
>               args.serialized_data = luo_file->serialized_data;
>               args.private_data = luo_file->private_data;
> @@ -411,6 +413,7 @@ static int luo_file_freeze_one(struct luo_file_set 
> *file_set,
>               struct liveupdate_file_op_args args = {0};
>  
>               args.handler = luo_file->fh;
> +             args.session = luo_session_from_file_set(file_set);
>               args.file = luo_file->file;
>               args.serialized_data = luo_file->serialized_data;
>               args.private_data = luo_file->private_data;
> @@ -432,6 +435,7 @@ static void luo_file_unfreeze_one(struct luo_file_set 
> *file_set,
>               struct liveupdate_file_op_args args = {0};
>  
>               args.handler = luo_file->fh;
> +             args.session = luo_session_from_file_set(file_set);
>               args.file = luo_file->file;
>               args.serialized_data = luo_file->serialized_data;
>               args.private_data = luo_file->private_data;
> @@ -621,6 +625,7 @@ int luo_retrieve_file(struct luo_file_set *file_set, u64 
> token,
>       }
>  
>       args.handler = luo_file->fh;
> +     args.session = luo_session_from_file_set(file_set);
>       args.serialized_data = luo_file->serialized_data;
>       err = luo_file->fh->ops->retrieve(&args);
>       if (err) {
> @@ -654,6 +659,7 @@ static int luo_file_can_finish_one(struct luo_file_set 
> *file_set,
>               struct liveupdate_file_op_args args = {0};
>  
>               args.handler = luo_file->fh;
> +             args.session = luo_session_from_file_set(file_set);
>               args.file = luo_file->file;
>               args.serialized_data = luo_file->serialized_data;
>               args.retrieve_status = luo_file->retrieve_status;
> @@ -671,6 +677,7 @@ static void luo_file_finish_one(struct luo_file_set 
> *file_set,
>       guard(mutex)(&luo_file->mutex);
>  
>       args.handler = luo_file->fh;
> +     args.session = luo_session_from_file_set(file_set);
>       args.file = luo_file->file;
>       args.serialized_data = luo_file->serialized_data;
>       args.retrieve_status = luo_file->retrieve_status;
> @@ -924,3 +931,65 @@ void liveupdate_unregister_file_handler(struct 
> liveupdate_file_handler *fh)
>       luo_flb_unregister_all(fh);
>       list_del(&ACCESS_PRIVATE(fh, list));
>  }
> +EXPORT_SYMBOL_GPL(liveupdate_unregister_file_handler);
> +
> +/**
> + * liveupdate_get_token_outgoing - Get the token for a preserved file.
> + * @s:      The outgoing liveupdate session.
> + * @file:   The file object to search for.
> + * @tokenp: Output parameter for the found token.
> + *
> + * Searches the list of preserved files in an outgoing session for a matching
> + * file object. If found, the corresponding user-provided token is returned.
> + *
> + * This function is intended for in-kernel callers that need to correlate a
> + * file with its liveupdate token.
> + *
> + * Context: It must be called with session mutex acquired.
> + * Return: 0 on success, -ENOENT if the file is not preserved in this 
> session.
> + */
> +int liveupdate_get_token_outgoing(struct liveupdate_session *s,
> +                               struct file *file, u64 *tokenp)
> +{
> +     struct luo_file_set *file_set = luo_file_set_from_session_locked(s);
> +     struct luo_file *luo_file;
> +     int err = -ENOENT;
> +
> +     list_for_each_entry(luo_file, &file_set->files_list, list) {
> +             if (luo_file->file == file) {
> +                     if (tokenp)
> +                             *tokenp = luo_file->token;
> +                     err = 0;
> +                     break;
> +             }
> +     }
> +
> +     return err;
> +}
> +
> +/**
> + * liveupdate_get_file_incoming - Retrieves a preserved file for in-kernel 
> use.
> + * @s:      The incoming liveupdate session (restored from the previous 
> kernel).
> + * @token:  The unique token identifying the file to retrieve.
> + * @filep:  On success, this will be populated with a pointer to the 
> retrieved
> + *          'struct file'.
> + *
> + * Provides a kernel-internal API for other subsystems to retrieve their
> + * preserved files after a live update. This function is a simple wrapper
> + * around luo_retrieve_file(), allowing callers to find a file by its token.
> + *
> + * The caller receives a new reference to the file and must call fput() when 
> it
> + * is no longer needed. The file's lifetime is managed by LUO and any 
> userspace
> + * file descriptors. If the caller needs to hold a reference to the file 
> beyond
> + * the immediate scope, it must call get_file() itself.
> + *
> + * Context: It must be called with session mutex acquired of a restored 
> session.
> + * Return: 0 on success. Returns -ENOENT if no file with the matching token 
> is
> + *         found, or any other negative errno on failure.
> + */
> +int liveupdate_get_file_incoming(struct liveupdate_session *s, u64 token,
> +                              struct file **filep)
> +{
> +     return luo_retrieve_file(luo_file_set_from_session_locked(s),
> +                              token, filep);
> +}
> diff --git a/kernel/liveupdate/luo_internal.h 
> b/kernel/liveupdate/luo_internal.h
> index 875844d7a41d..08b198802e7f 100644
> --- a/kernel/liveupdate/luo_internal.h
> +++ b/kernel/liveupdate/luo_internal.h
> @@ -79,6 +79,23 @@ struct luo_session {
>  
>  extern struct rw_semaphore luo_register_rwlock;
>  
> +static inline struct liveupdate_session *luo_session_from_file_set(struct 
> luo_file_set *file_set)
> +{
> +     struct luo_session *session;
> +
> +     session = container_of(file_set, struct luo_session, file_set);
> +
> +     return (struct liveupdate_session *)session;
> +}
> +
> +static inline struct luo_file_set *luo_file_set_from_session_locked(struct 
> liveupdate_session *s)
> +{
> +     struct luo_session *session = (struct luo_session *)s;
> +
> +     lockdep_assert_held(&session->mutex);
> +     return &session->file_set;
> +}
> +
>  int luo_session_create(const char *name, struct file **filep);
>  int luo_session_retrieve(const char *name, struct file **filep);
>  int __init luo_session_setup_outgoing(void *fdt);
> -- 
> 2.54.0.1032.g2f8565e1d1-goog

Reply via email to