fs/debugfs/file.c
Source file repositories/reference/linux-study-clean/fs/debugfs/file.c
File Facts
- System
- Linux kernel
- Corpus path
fs/debugfs/file.c- Extension
.c- Size
- 44274 bytes
- Lines
- 1436
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/fs.hlinux/seq_file.hlinux/pagemap.hlinux/debugfs.hlinux/io.hlinux/slab.hlinux/atomic.hlinux/device.hlinux/pm_runtime.hlinux/poll.hlinux/security.hinternal.h
Detected Declarations
struct poll_table_structstruct debugfs_devm_entryenum dbgfs_get_modefunction default_read_filefunction default_write_filefunction __debugfs_file_getfunction debugfs_file_putfunction debugfs_file_getfunction debugfs_leave_cancellationfunction debugfs_enter_cancellationfunction debugfs_locked_downfunction open_proxy_openfunction full_proxy_pollfunction full_proxy_releasefunction full_proxy_open_regularfunction full_proxy_open_shortfunction debugfs_attr_readfunction debugfs_attr_write_xsignedfunction debugfs_attr_writefunction debugfs_attr_write_signedfunction debugfs_u8_setfunction debugfs_u8_getfunction debugfs_create_u8function debugfs_u16_setfunction debugfs_u16_getfunction debugfs_create_u16function debugfs_u32_setfunction debugfs_u32_getfunction debugfs_create_u32function debugfs_u64_setfunction debugfs_u64_getfunction debugfs_create_u64function debugfs_ulong_setfunction debugfs_ulong_getfunction debugfs_create_ulongfunction functionsfunction debugfs_create_x16function debugfs_create_x32function debugfs_create_x64function debugfs_size_t_setfunction debugfs_size_t_getfunction debugfs_create_size_tfunction debugfs_atomic_t_setfunction debugfs_atomic_t_getfunction debugfs_create_atomic_tfunction debugfs_read_file_boolfunction debugfs_write_file_boolfunction debugfs_create_bool
Annotated Snippet
const struct file_operations debugfs_noop_file_operations = {
.read = default_read_file,
.write = default_write_file,
.open = simple_open,
.llseek = noop_llseek,
};
#define F_DENTRY(filp) ((filp)->f_path.dentry)
void *debugfs_get_aux(const struct file *file)
{
return DEBUGFS_I(file_inode(file))->aux;
}
EXPORT_SYMBOL_GPL(debugfs_get_aux);
enum dbgfs_get_mode {
DBGFS_GET_ALREADY,
DBGFS_GET_REGULAR,
DBGFS_GET_SHORT,
};
static int __debugfs_file_get(struct dentry *dentry, enum dbgfs_get_mode mode)
{
struct debugfs_fsdata *fsd;
void *d_fsd;
/*
* This could only happen if some debugfs user erroneously calls
* debugfs_file_get() on a dentry that isn't even a file, let
* them know about it.
*/
if (WARN_ON(!d_is_reg(dentry)))
return -EINVAL;
d_fsd = READ_ONCE(dentry->d_fsdata);
if (d_fsd) {
fsd = d_fsd;
} else {
struct inode *inode = dentry->d_inode;
unsigned int methods = 0;
if (WARN_ON(mode == DBGFS_GET_ALREADY))
return -EINVAL;
fsd = kmalloc_obj(*fsd);
if (!fsd)
return -ENOMEM;
if (mode == DBGFS_GET_SHORT) {
const struct debugfs_short_fops *ops;
ops = fsd->short_fops = DEBUGFS_I(inode)->short_fops;
if (ops->llseek)
methods |= HAS_LSEEK;
if (ops->read)
methods |= HAS_READ;
if (ops->write)
methods |= HAS_WRITE;
fsd->real_fops = NULL;
} else {
const struct file_operations *ops;
ops = fsd->real_fops = DEBUGFS_I(inode)->real_fops;
if (ops->llseek)
methods |= HAS_LSEEK;
if (ops->read)
methods |= HAS_READ;
if (ops->write)
methods |= HAS_WRITE;
if (ops->unlocked_ioctl)
methods |= HAS_IOCTL;
if (ops->poll)
methods |= HAS_POLL;
fsd->short_fops = NULL;
}
fsd->methods = methods;
refcount_set(&fsd->active_users, 1);
init_completion(&fsd->active_users_drained);
INIT_LIST_HEAD(&fsd->cancellations);
mutex_init(&fsd->cancellations_mtx);
d_fsd = cmpxchg(&dentry->d_fsdata, NULL, fsd);
if (d_fsd) {
mutex_destroy(&fsd->cancellations_mtx);
kfree(fsd);
fsd = d_fsd;
}
}
/*
* In case of a successful cmpxchg() above, this check is
* strictly necessary and must follow it, see the comment in
Annotation
- Immediate include surface: `linux/module.h`, `linux/fs.h`, `linux/seq_file.h`, `linux/pagemap.h`, `linux/debugfs.h`, `linux/io.h`, `linux/slab.h`, `linux/atomic.h`.
- Detected declarations: `struct poll_table_struct`, `struct debugfs_devm_entry`, `enum dbgfs_get_mode`, `function default_read_file`, `function default_write_file`, `function __debugfs_file_get`, `function debugfs_file_put`, `function debugfs_file_get`, `function debugfs_leave_cancellation`, `function debugfs_enter_cancellation`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.