diff options
| author | Steven Rostedt <rostedt@goodmis.org> | 2026-09-02 09:55:01 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2026-09-02 11:08:21 -0400 |
| commit | 4617721c502b2ddaa4e324e86da4997edf738fa5 (patch) | |
| tree | 350aa83b47da0b574a814795392b20b0bed83cbc /fs/befs/befs.h | |
| download | linux-stable-4617721c502b2ddaa4e324e86da4997edf738fa5.tar.gz linux-stable-4617721c502b2ddaa4e324e86da4997edf738fa5.zip | |
ftrace: Synchronize the initialization of ftrace_opsgrafted
There's some internal state that ftrace_ops needs to have set, but since
it can be declared outside of the ftrace.c code, it calls
ftrace_ops_init() on the ops in every global function. The issue is that
if two tasks call it on the same ops at the same time it is possible to
have the initialization of one corrupt the initialization of the other
call.
Create a ops_mutex to use to synchronize every initialization of the
ftrace_ops. The mutex is taken within checking the ftrace_ops flag that
states it was initializied but the flag is checked again after the mutex
has been taken. Checking first outside the mutex allows it to shortcut
having to take the mutex. But then the check needs to be done again after
the mute is taken in case of races.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260902095501.6b59af20@gandalf.local.home
Fixes: f04f24fb7e48d ("ftrace, kprobes: Fix a deadlock on ftrace_regex_lock")
Reported-by: sashiko-bot@kernel.org
Close: https://lore.kernel.org/all/20260829025528.49A831F000E9@smtp.kernel.org/
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'fs/befs/befs.h')
| -rw-r--r-- | fs/befs/befs.h | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/fs/befs/befs.h b/fs/befs/befs.h new file mode 100644 index 000000000..7cd472456 --- /dev/null +++ b/fs/befs/befs.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * befs.h + * + * Copyright (C) 2001-2002 Will Dyson <will_dyson@pobox.com> + * Copyright (C) 1999 Makoto Kato (m_kato@ga2.so-net.ne.jp) + */ + +#ifndef _LINUX_BEFS_H +#define _LINUX_BEFS_H + +#include "befs_fs_types.h" + +/* used in debug.c */ +#define BEFS_VERSION "0.9.3" + + +typedef u64 befs_blocknr_t; +/* + * BeFS in memory structures + */ + +struct befs_mount_options { + kgid_t gid; + kuid_t uid; + int use_gid; + int use_uid; + int debug; + char *iocharset; +}; + +struct befs_sb_info { + u32 magic1; + u32 block_size; + u32 block_shift; + int byte_order; + befs_off_t num_blocks; + befs_off_t used_blocks; + u32 inode_size; + u32 magic2; + + /* Allocation group information */ + u32 blocks_per_ag; + u32 ag_shift; + u32 num_ags; + + /* State of the superblock */ + u32 flags; + + /* Journal log entry */ + befs_block_run log_blocks; + befs_off_t log_start; + befs_off_t log_end; + + befs_inode_addr root_dir; + befs_inode_addr indices; + u32 magic3; + + struct befs_mount_options mount_opts; + struct nls_table *nls; +}; + +struct befs_inode_info { + u32 i_flags; + u32 i_type; + + befs_inode_addr i_inode_num; + befs_inode_addr i_parent; + befs_inode_addr i_attribute; + + union { + befs_data_stream ds; + char symlink[BEFS_SYMLINK_LEN]; + } i_data; + + struct inode vfs_inode; +}; + +enum befs_err { + BEFS_OK, + BEFS_ERR, + BEFS_BAD_INODE, + BEFS_BT_END, + BEFS_BT_EMPTY, + BEFS_BT_MATCH, + BEFS_BT_OVERFLOW, + BEFS_BT_NOT_FOUND +}; + + +/****************************/ +/* debug.c */ +__printf(2, 3) +void befs_error(const struct super_block *sb, const char *fmt, ...); +__printf(2, 3) +void befs_warning(const struct super_block *sb, const char *fmt, ...); +__printf(2, 3) +void befs_debug(const struct super_block *sb, const char *fmt, ...); + +void befs_dump_super_block(const struct super_block *sb, befs_super_block *); +void befs_dump_inode(const struct super_block *sb, befs_inode *); +void befs_dump_index_entry(const struct super_block *sb, befs_disk_btree_super *); +void befs_dump_index_node(const struct super_block *sb, befs_btree_nodehead *); +/****************************/ + + +/* Gets a pointer to the private portion of the super_block + * structure from the public part + */ +static inline struct befs_sb_info * +BEFS_SB(const struct super_block *super) +{ + return (struct befs_sb_info *) super->s_fs_info; +} + +static inline struct befs_inode_info * +BEFS_I(const struct inode *inode) +{ + return container_of(inode, struct befs_inode_info, vfs_inode); +} + +static inline befs_blocknr_t +iaddr2blockno(struct super_block *sb, const befs_inode_addr *iaddr) +{ + return ((iaddr->allocation_group << BEFS_SB(sb)->ag_shift) + + iaddr->start); +} + +static inline befs_inode_addr +blockno2iaddr(struct super_block *sb, befs_blocknr_t blockno) +{ + befs_inode_addr iaddr; + + iaddr.allocation_group = blockno >> BEFS_SB(sb)->ag_shift; + iaddr.start = + blockno - (iaddr.allocation_group << BEFS_SB(sb)->ag_shift); + iaddr.len = 1; + + return iaddr; +} + +static inline unsigned int +befs_iaddrs_per_block(struct super_block *sb) +{ + return BEFS_SB(sb)->block_size / sizeof(befs_disk_inode_addr); +} + +#include "endian.h" + +#endif /* _LINUX_BEFS_H */ |
