mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
liveupdate: Reference count outgoing FLB data
Increment the outgoing FLB refcount in liveupdate_flb_get_outgoing() so
that the FLB structure cannot be freed while the caller is actively
using it. Add an additional liveupdate_flb_put_outgoing() function so
the caller can explicitly indicate when it is done using the outgoing
FLB.
During a Live Update, the kernel may need to fetch the outgoing FLB
outside of the scope of a file handler's preserve() and unpreserve()
callbacks. In that situation there is no way for the caller to protect
itself against the outgoing FLB from being freed while it is using it.
Incrementing the reference count in liveupdate_flb_get_outgoing()
ensures it cannot be freed.
This change also aligns the outgoing FLB lifecycle management with the
incoming FLB, since the latter uses the same get/put semantics.
Fixes: cab056f2aa ("liveupdate: luo_flb: introduce File-Lifecycle-Bound global state")
Assisted-by: Gemini:gemini-3-pro-preview
Signed-off-by: David Matlack <dmatlack@google.com>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Link: https://patch.msgid.link/20260528174140.1921129-2-dmatlack@google.com
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
This commit is contained in:
parent
05cf3d87a0
commit
36882f3392
|
|
@ -243,6 +243,7 @@ int liveupdate_flb_get_incoming(struct liveupdate_flb *flb, void **objp);
|
|||
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);
|
||||
|
||||
#else /* CONFIG_LIVEUPDATE */
|
||||
|
||||
|
|
@ -292,5 +293,9 @@ static inline int liveupdate_flb_get_outgoing(struct liveupdate_flb *flb,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void liveupdate_flb_put_outgoing(struct liveupdate_flb *flb)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_LIVEUPDATE */
|
||||
#endif /* _LINUX_LIVEUPDATE_H */
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ static int luo_flb_file_preserve_one(struct liveupdate_flb *flb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void luo_flb_file_unpreserve_one(struct liveupdate_flb *flb)
|
||||
void liveupdate_flb_put_outgoing(struct liveupdate_flb *flb)
|
||||
{
|
||||
struct luo_flb_private *private = luo_flb_get_private(flb);
|
||||
|
||||
|
|
@ -264,7 +264,7 @@ int luo_flb_file_preserve(struct liveupdate_file_handler *fh)
|
|||
|
||||
exit_err:
|
||||
list_for_each_entry_continue_reverse(iter, flb_list, list)
|
||||
luo_flb_file_unpreserve_one(iter->flb);
|
||||
liveupdate_flb_put_outgoing(iter->flb);
|
||||
up_read(&luo_register_rwlock);
|
||||
|
||||
return err;
|
||||
|
|
@ -289,7 +289,7 @@ void luo_flb_file_unpreserve(struct liveupdate_file_handler *fh)
|
|||
|
||||
guard(rwsem_read)(&luo_register_rwlock);
|
||||
list_for_each_entry_reverse(iter, flb_list, list)
|
||||
luo_flb_file_unpreserve_one(iter->flb);
|
||||
liveupdate_flb_put_outgoing(iter->flb);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -544,6 +544,10 @@ int liveupdate_flb_get_outgoing(struct liveupdate_flb *flb, void **objp)
|
|||
return -EOPNOTSUPP;
|
||||
|
||||
guard(mutex)(&private->outgoing.lock);
|
||||
if (!private->outgoing.obj)
|
||||
return -ENOENT;
|
||||
|
||||
refcount_inc(&private->outgoing.count);
|
||||
*objp = private->outgoing.obj;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user