fs/pidfs.c
Source file repositories/reference/linux-study-clean/fs/pidfs.c
File Facts
- System
- Linux kernel
- Corpus path
fs/pidfs.c- Extension
.c- Size
- 30244 bytes
- Lines
- 1157
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/anon_inodes.hlinux/exportfs.hlinux/file.hlinux/fs.hlinux/cgroup.hlinux/magic.hlinux/mount.hlinux/pid.hlinux/pidfs.hlinux/sched/signal.hlinux/signal.hlinux/pid_namespace.hlinux/poll.hlinux/proc_fs.hlinux/proc_ns.hlinux/pseudo_fs.hlinux/ptrace.hlinux/seq_file.huapi/linux/pidfd.hlinux/ipc_namespace.hlinux/time_namespace.hlinux/utsname.hnet/net_namespace.hlinux/coredump.hlinux/rhashtable.hlinux/llist.hlinux/xattr.hlinux/cookie.hinternal.hmount.h
Detected Declarations
struct pidfs_anon_attrstruct pidfs_attrstruct pidfs_anon_attrenum pidfs_attr_mask_bitsfunction pidfs_get_rootfunction pidfs_inofunction pidfs_genfunction pidfs_alloc_inofunction pidfs_inofunction pidfs_genfunction pidfs_alloc_inofunction pidfs_prepare_pidfunction pidfs_add_pidfunction pidfs_remove_pidfunction pidfs_free_attr_workfunction pidfs_free_pidfunction getppidfunction pidfd_pollfunction pid_in_current_pidnsfunction pidfs_coredump_maskfunction pidfd_infofunction pidfs_ioctl_validfunction pidfd_ioctlfunction scoped_guardfunction scoped_guardfunction scoped_guardfunction pidfs_file_releasefunction release_taskfunction pidfs_coredumpfunction simple_setattrfunction pidfs_getattrfunction pidfs_listxattrfunction pidfs_evict_inodefunction pidfs_encode_fhfunction open_by_handle_atfunction pidfs_init_inodefunction pidfs_put_datafunction pidfs_register_pid_gfpfunction pidfs_xattr_getfunction pidfs_xattr_setfunction pidfs_init_fs_contextfunction pidfs_init
Annotated Snippet
static const struct file_operations pidfs_file_operations = {
.release = pidfs_file_release,
.poll = pidfd_poll,
#ifdef CONFIG_PROC_FS
.show_fdinfo = pidfd_show_fdinfo,
#endif
.unlocked_ioctl = pidfd_ioctl,
.compat_ioctl = compat_ptr_ioctl,
};
struct pid *pidfd_pid(const struct file *file)
{
if (file->f_op != &pidfs_file_operations)
return ERR_PTR(-EBADF);
return file_inode(file)->i_private;
}
/*
* We're called from release_task(). We know there's at least one
* reference to struct pid being held that won't be released until the
* task has been reaped which cannot happen until we're out of
* release_task().
*
* If this struct pid has at least once been referred to by a pidfd then
* pid->attr will be allocated. If not we mark the struct pid as dead so
* anyone who is trying to register it with pidfs will fail to do so.
* Otherwise we would hand out pidfs for reaped tasks without having
* exit information available.
*
* Worst case is that we've filled in the info and the pid gets freed
* right away in free_pid() when no one holds a pidfd anymore. Since
* pidfs_exit() currently is placed after exit_task_work() we know that
* it cannot be us aka the exiting task holding a pidfd to itself.
*/
void pidfs_exit(struct task_struct *tsk)
{
struct pid *pid = task_pid(tsk);
struct pidfs_attr *attr;
#ifdef CONFIG_CGROUPS
struct cgroup *cgrp;
#endif
might_sleep();
/* Synchronize with pidfs_register_pid(). */
scoped_guard(spinlock_irq, &pid->wait_pidfd.lock) {
attr = pid->attr;
if (!attr) {
/*
* No one ever held a pidfd for this struct pid.
* Mark it as dead so no one can add a pidfs
* entry anymore. We're about to be reaped and
* so no exit information would be available.
*/
pid->attr = PIDFS_PID_DEAD;
return;
}
}
/*
* If @pid->attr is set someone might still legitimately hold a
* pidfd to @pid or someone might concurrently still be getting
* a reference to an already stashed dentry from @pid->stashed.
* So defer cleaning @pid->attr until the last reference to @pid
* is put
*/
#ifdef CONFIG_CGROUPS
rcu_read_lock();
cgrp = task_dfl_cgroup(tsk);
attr->cgroupid = cgroup_id(cgrp);
rcu_read_unlock();
#endif
attr->exit_code = tsk->exit_code;
/* Ensure that PIDFD_GET_INFO sees either all or nothing. */
smp_wmb();
set_bit(PIDFS_ATTR_BIT_EXIT, &attr->attr_mask);
}
#ifdef CONFIG_COREDUMP
void pidfs_coredump(const struct coredump_params *cprm)
{
struct pid *pid = cprm->pid;
struct pidfs_attr *attr;
attr = READ_ONCE(pid->attr);
VFS_WARN_ON_ONCE(!attr);
VFS_WARN_ON_ONCE(attr == PIDFS_PID_DEAD);
Annotation
- Immediate include surface: `linux/anon_inodes.h`, `linux/exportfs.h`, `linux/file.h`, `linux/fs.h`, `linux/cgroup.h`, `linux/magic.h`, `linux/mount.h`, `linux/pid.h`.
- Detected declarations: `struct pidfs_anon_attr`, `struct pidfs_attr`, `struct pidfs_anon_attr`, `enum pidfs_attr_mask_bits`, `function pidfs_get_root`, `function pidfs_ino`, `function pidfs_gen`, `function pidfs_alloc_ino`, `function pidfs_ino`, `function pidfs_gen`.
- 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.