Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later 2 : /* 3 : * Copyright (C) 2022-2023 Oracle. All Rights Reserved. 4 : * Author: Darrick J. Wong <djwong@kernel.org> 5 : */ 6 : #ifndef XFS_HOOKS_H_ 7 : #define XFS_HOOKS_H_ 8 : 9 : #if defined(CONFIG_XFS_LIVE_HOOKS_SRCU) 10 : struct xfs_hooks { 11 : struct srcu_notifier_head head; 12 : }; 13 : #elif defined(CONFIG_XFS_LIVE_HOOKS_BLOCKING) 14 : struct xfs_hooks { 15 : struct blocking_notifier_head head; 16 : }; 17 : #else 18 : struct xfs_hooks { /* empty */ }; 19 : #endif 20 : 21 : /* 22 : * If hooks and jump labels are enabled, we use jump labels (aka patching of 23 : * the code segment) to avoid the minute overhead of calling an empty notifier 24 : * chain when we know there are no callers. If hooks are enabled without jump 25 : * labels, hardwire the predicate to true because calling an empty srcu 26 : * notifier chain isn't so expensive. 27 : */ 28 : #if defined(CONFIG_JUMP_LABEL) && defined(CONFIG_XFS_LIVE_HOOKS) 29 : # define DEFINE_STATIC_XFS_HOOK_SWITCH(name) \ 30 : static DEFINE_STATIC_KEY_FALSE(name) 31 : # define xfs_hooks_switch_on(name) static_branch_inc(name) 32 : # define xfs_hooks_switch_off(name) static_branch_dec(name) 33 : # define xfs_hooks_switched_on(name) static_branch_unlikely(name) 34 : #elif defined(CONFIG_XFS_LIVE_HOOKS) 35 : # define DEFINE_STATIC_XFS_HOOK_SWITCH(name) 36 : # define xfs_hooks_switch_on(name) ((void)0) 37 : # define xfs_hooks_switch_off(name) ((void)0) 38 : # define xfs_hooks_switched_on(name) (true) 39 : #else 40 : # define DEFINE_STATIC_XFS_HOOK_SWITCH(name) 41 : # define xfs_hooks_switch_on(name) ((void)0) 42 : # define xfs_hooks_switch_off(name) ((void)0) 43 : # define xfs_hooks_switched_on(name) (false) 44 : #endif /* JUMP_LABEL && XFS_LIVE_HOOKS */ 45 : 46 : #ifdef CONFIG_XFS_LIVE_HOOKS 47 : struct xfs_hook { 48 : /* This must come at the start of the structure. */ 49 : struct notifier_block nb; 50 : }; 51 : 52 : typedef int (*xfs_hook_fn_t)(struct xfs_hook *hook, unsigned long action, 53 : void *data); 54 : 55 : void xfs_hooks_init(struct xfs_hooks *chain); 56 : int xfs_hooks_add(struct xfs_hooks *chain, struct xfs_hook *hook); 57 : void xfs_hooks_del(struct xfs_hooks *chain, struct xfs_hook *hook); 58 : int xfs_hooks_call(struct xfs_hooks *chain, unsigned long action, 59 : void *priv); 60 : 61 : static inline void xfs_hook_setup(struct xfs_hook *hook, notifier_fn_t fn) 62 : { 63 11831608 : hook->nb.notifier_call = fn; 64 11831608 : hook->nb.priority = 0; 65 : } 66 : 67 : #else 68 : # define xfs_hooks_init(chain) ((void)0) 69 : # define xfs_hooks_call(chain, val, priv) (NOTIFY_DONE) 70 : #endif 71 : 72 : #endif /* XFS_HOOKS_H_ */