From nobody Fri Jul 24 21:53:02 2026 Received: from mail-pl1-f197.google.com (mail-pl1-f197.google.com [209.85.214.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CC5EB3EEACF for ; Thu, 23 Jul 2026 20:29:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.197 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784838577; cv=none; b=HpY+jVumn/tRotlYJsg/uwUgZf1W++nw/xUSvFKd+jkA22MDRazSmbWd+ImNcA/QnSIQ2plJivzuuiqaoUHLaRK07TWplRMmiKzfg/u/VUZtykhIcwZBJC1jYsZ7t9ETXHbnc7pAcxmn5tBj55dYXy2Fh54fVCncYN9meTpTCMU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784838577; c=relaxed/simple; bh=zD3W4aLFvvbOCf0/AblOHmi95hIDXSa/aP7p7XO0uVQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=NIqzRXzqU3z6Jr9Mo4e48kIzrD4mMfTbKKW8mjIkklsOQxXn0cxtJguJQxiwy4/G/ByFCslYMRg468bD8Pz8pnNgzGC6q7jklAb06PwT9FYOdb2yN39pJS67s9WBPm4y+jOv3rlFSfdzJJtomqTFuiE5+n9hkI2Xi2KEU//e9rE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--skhawaja.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=fGaTc5u5; arc=none smtp.client-ip=209.85.214.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--skhawaja.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="fGaTc5u5" Received: by mail-pl1-f197.google.com with SMTP id d9443c01a7336-2ccb6f6a3f4so12151825ad.1 for ; Thu, 23 Jul 2026 13:29:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1784838568; x=1785443368; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=jKy1+xh3t540cHOpDayVgEdD7bHubSTIw9MAGeaiEnQ=; b=fGaTc5u5E9mPaZoE88I1wM/1YB61RtvqkwUnuC4FCn7adsQVdnmJl5s4hEKIqI7YGb tomwQOgwIodvyrwPAt6IebzOfA19KBCp51Ofi4sq0mGeEcG44xu22PzKKiFmRnu+Gu5j UwOob1lpq+VoUhlfsDHLAFYn1MMEuoCjLAQlB4zGP2e3Vt/1gkfAXp1VyPqksjHSFgPz Ezp7VVHSQ2cuZxOBnO3bZsiJZcsZCmIVVMfYqw0T+9uPHP5mHeyjN/BKNly3VGcJxOoJ aa96QVajfO1lPLzYIXsQn8NGcI0BcP6/GkycT5vN79gTqo7GWjo2IpRrWtn9vNPyxqqJ h/XQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784838568; x=1785443368; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=jKy1+xh3t540cHOpDayVgEdD7bHubSTIw9MAGeaiEnQ=; b=jrEM9KdJgun71Stji8enelRjlzf+qJEeBQ9MJlKBqkOTEzoJYqmhWdgI7EqWdxw4l7 oTsOYJKfVt5VDdalcG7lcOrRzhvdjlxVYMAMBwyUX9hkaPbQzaXhON0TAk06MFCBZfCf RCtGItEHInsKtzpW/UjgpRrbLxYdgePfS8r95UdEuzTjXRmknTFYxhAB80mDVioSVKsM Sm47EbaPEwbA3kNme0BXGKJBP8SNyyNbUG+gvrbReWav3vA29reyX7U2H7EFANwmgL4B k/0E0ecUztlUAnuk1o3inAu5GmkqPg0sEF5oVvnlVcFWULsRgsZ8SC2p4eYuH5NSJ81e WMlg== X-Forwarded-Encrypted: i=1; AHgh+RoZS4n7I3BS5tWW3rZXjCj56UM/5FdZXZXlNNSsons674wyCky97MvY5kYjx16KFItSXShgGAdkvjvgJ/o=@vger.kernel.org X-Gm-Message-State: AOJu0YyR16PH6fYOQ0hnCuOWJpXCtQlGynJ/LqK/bRS6kU/467noC0cP 6ZTVRy2I/NfRfjgbdNFZPXfzDXxj+2xUQ3KJQOgGBN9JhxBH5RhHr98WIj9DAU8MGFJ2uhJMyos nUfKSeLKjxMwylg== X-Received: from plbka16.prod.google.com ([2002:a17:903:3350:b0:2cb:ea2b:5286]) (user=skhawaja job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:e84f:b0:2ca:c847:8e41 with SMTP id d9443c01a7336-2cfa94b7aadmr48476855ad.11.1784838567356; Thu, 23 Jul 2026 13:29:27 -0700 (PDT) Date: Thu, 23 Jul 2026 20:29:12 +0000 In-Reply-To: <20260723202912.1467112-1-skhawaja@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20260723202912.1467112-1-skhawaja@google.com> X-Mailer: git-send-email 2.55.0.229.g6434b31f56-goog Message-ID: <20260723202912.1467112-2-skhawaja@google.com> Subject: [PATCH v2 1/1] liveupdate: luo_file: Add internal APIs for file preservation From: Samiullah Khawaja To: Pasha Tatashin , Mike Rapoport , Pratyush Yadav , Alexander Graf Cc: Pranjal Shrivastava , Samiullah Khawaja , David Matlack , tarunsahu@google.com, open list , "open list:KEXEC HANDOVER (KHO)" , "open list:KEXEC HANDOVER (KHO)" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Pasha Tatashin Live update orchestrator file handlers depend on the preservation of other files. To make sure that the dependency is preserved, the file handlers needs to fetch the preservation token of the preserved dependency. Similarly during restore, a file handler wants to fetch the restored file of the dependency. Add APIs that allows fetching token of dependency during preservation, and fetching the restored file dependency during restore. Reviewed-by: Pranjal Shrivastava Signed-off-by: Pasha Tatashin Signed-off-by: Samiullah Khawaja --- include/linux/liveupdate.h | 22 ++++++++++ kernel/liveupdate/luo_file.c | 69 ++++++++++++++++++++++++++++++++ kernel/liveupdate/luo_internal.h | 17 ++++++++ 3 files changed, 108 insertions(+) diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h index 63ea5417de84..6051abc0612c 100644 --- a/include/linux/liveupdate.h +++ b/include/linux/liveupdate.h @@ -25,6 +25,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 b= een * attempted, a positive value means the retrieve was @@ -45,6 +46,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; @@ -247,6 +249,14 @@ void liveupdate_flb_put_incoming(struct liveupdate_flb= *flb); int liveupdate_flb_get_outgoing(struct liveupdate_flb *flb, void **objp); void liveupdate_flb_put_outgoing(struct liveupdate_flb *flb); =20 +/* 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 */ =20 static inline bool liveupdate_enabled(void) @@ -299,5 +309,17 @@ static inline void liveupdate_flb_put_outgoing(struct = liveupdate_flb *flb) { } =20 +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 72f8bb90b66c..542707e8d8c1 100644 --- a/kernel/liveupdate/luo_file.c +++ b/kernel/liveupdate/luo_file.c @@ -293,6 +293,7 @@ int luo_preserve_file(struct luo_file_set *file_set, u6= 4 token, int fd) mutex_init(&luo_file->mutex); =20 args.handler =3D fh; + args.session =3D luo_session_from_file_set(file_set); args.file =3D file; err =3D fh->ops->preserve(&args); if (err) @@ -350,6 +351,7 @@ void luo_file_unpreserve_files(struct luo_file_set *fil= e_set) struct luo_file, list); =20 args.handler =3D luo_file->fh; + args.session =3D luo_session_from_file_set(file_set); args.file =3D luo_file->file; args.serialized_data =3D luo_file->serialized_data; args.private_data =3D luo_file->private_data; @@ -383,6 +385,7 @@ static int luo_file_freeze_one(struct luo_file_set *fil= e_set, struct liveupdate_file_op_args args =3D {0}; =20 args.handler =3D luo_file->fh; + args.session =3D luo_session_from_file_set(file_set); args.file =3D luo_file->file; args.serialized_data =3D luo_file->serialized_data; args.private_data =3D luo_file->private_data; @@ -404,6 +407,7 @@ static void luo_file_unfreeze_one(struct luo_file_set *= file_set, struct liveupdate_file_op_args args =3D {0}; =20 args.handler =3D luo_file->fh; + args.session =3D luo_session_from_file_set(file_set); args.file =3D luo_file->file; args.serialized_data =3D luo_file->serialized_data; args.private_data =3D luo_file->private_data; @@ -596,6 +600,7 @@ int luo_retrieve_file(struct luo_file_set *file_set, u6= 4 token, } =20 args.handler =3D luo_file->fh; + args.session =3D luo_session_from_file_set(file_set); args.serialized_data =3D luo_file->serialized_data; err =3D luo_file->fh->ops->retrieve(&args); if (err) { @@ -629,6 +634,7 @@ static int luo_file_can_finish_one(struct luo_file_set = *file_set, struct liveupdate_file_op_args args =3D {0}; =20 args.handler =3D luo_file->fh; + args.session =3D luo_session_from_file_set(file_set); args.file =3D luo_file->file; args.serialized_data =3D luo_file->serialized_data; args.retrieve_status =3D luo_file->retrieve_status; @@ -646,6 +652,7 @@ static void luo_file_finish_one(struct luo_file_set *fi= le_set, guard(mutex)(&luo_file->mutex); =20 args.handler =3D luo_file->fh; + args.session =3D luo_session_from_file_set(file_set); args.file =3D luo_file->file; args.serialized_data =3D luo_file->serialized_data; args.retrieve_status =3D luo_file->retrieve_status; @@ -935,3 +942,65 @@ void liveupdate_unregister_file_handler(struct liveupd= ate_file_handler *fh) luo_flb_unregister_all(fh); list_del(&ACCESS_PRIVATE(fh, list)); } + +/** + * 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 match= ing + * file object. If found, the corresponding user-provided token is returne= d. + * + * 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 sess= ion. + */ +int liveupdate_get_token_outgoing(struct liveupdate_session *s, + struct file *file, u64 *tokenp) +{ + struct luo_file_set *file_set =3D luo_file_set_from_session_locked(s); + struct luo_file *luo_file; + int err =3D -ENOENT; + + list_for_each_entry(luo_file, &file_set->files_list, list) { + if (luo_file->file =3D=3D file) { + if (tokenp) + *tokenp =3D luo_file->token; + err =3D 0; + break; + } + } + + return err; +} +EXPORT_SYMBOL_GPL(liveupdate_get_token_outgoing); + +/** + * liveupdate_get_file_incoming - Retrieves a preserved file for in-kernel= use. + * @s: The incoming liveupdate session (restored from the previous ke= rnel). + * @token: The unique token identifying the file to retrieve. + * @filep: On success, this will be populated with a pointer to the retri= eved + * '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 toke= n. + * + * The caller receives a new reference to the file and must call fput() wh= en it + * is no longer needed. The file's lifetime is managed by LUO and any user= space + * file descriptors. + * + * Context: It must be called with session mutex acquired of a restored se= ssion. + * Return: 0 on success. Returns -ENOENT if no file with the matching toke= n 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); +} +EXPORT_SYMBOL_GPL(liveupdate_get_file_incoming); diff --git a/kernel/liveupdate/luo_internal.h b/kernel/liveupdate/luo_inter= nal.h index 64879ffe7378..dac6644bfb18 100644 --- a/kernel/liveupdate/luo_internal.h +++ b/kernel/liveupdate/luo_internal.h @@ -77,6 +77,23 @@ struct luo_session { =20 extern struct rw_semaphore luo_register_rwlock; =20 +static inline struct liveupdate_session *luo_session_from_file_set(struct = luo_file_set *file_set) +{ + struct luo_session *session; + + session =3D 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 =3D (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); void __init luo_session_setup_outgoing(u64 *sessions_pa); --=20 2.55.0.229.g6434b31f56-goog