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

