/** @file safe_kobject.h @brief Safe kobject interop with sysfs @details Copyright (c) 2025 Acronis International GmbH @author Denis Kopyrin ([email protected]) @since $Id: $ */ #pragma once #include <linux/completion.h> #include <linux/kobject.h> #ifdef KERNEL_MOCK #include <mock/mock_types.h> #endif // The problem with kobject is that it is embedded in sysfs system. // For regular monolith design it is not an issue but for unload code we do not want our callback to triggered. // The common solution for this is to use waitable 'completion' that is invoked from 'release' instead of 'kfree'. typedef struct safe_kobject_s { struct kobject kobj; struct completion complete; } safe_kobject_t; #define to_safe_kobject(_at) container_of(_at, safe_kobject_t, kobj) static inline void safe_kobject_sysfs_release(struct kobject* obj) { // TODO: Figure out why container_of does not work here safe_kobject_t* skobj = (safe_kobject_t*) obj; complete(&skobj->complete); } static inline void safe_kobject_init(safe_kobject_t* skobj) { skobj->kobj = (struct kobject){}; init_completion(&skobj->complete); } static inline void safe_kobject_del(safe_kobject_t* skobj) { kobject_del(&skobj->kobj); kobject_put(&skobj->kobj); wait_for_completion(&skobj->complete); }