fs/file.c
Source file repositories/reference/linux-study-clean/fs/file.c
File Facts
- System
- Linux kernel
- Corpus path
fs/file.c- Extension
.c- Size
- 40340 bytes
- Lines
- 1532
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: syscall or user/kernel boundary
- Status
- core 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 or participates in a user/kernel boundary; inspect argument validation, copy_from_user/copy_to_user, credentials, and dispatch target.
- 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/syscalls.hlinux/export.hlinux/fs.hlinux/kernel.hlinux/mm.hlinux/sched/signal.hlinux/slab.hlinux/file.hlinux/fdtable.hlinux/bitops.hlinux/spinlock.hlinux/rcupdate.hlinux/close_range.hlinux/file_ref.hnet/sock.hlinux/init_task.hinternal.h
Detected Declarations
syscall close_rangesyscall dup3syscall dup2syscall dupfunction Copyrightfunction putfunction __free_fdtablefunction free_fdtable_rcufunction copy_fd_bitmapsfunction copy_fdtablefunction expand_filesfunction expand_fdtablefunction expand_filesfunction __set_close_on_execfunction __set_open_fdfunction __clear_open_fdfunction fd_is_openfunction sane_fdtable_sizefunction put_files_structfunction exit_filesfunction find_next_fdfunction alloc_fdfunction __get_unused_fd_flagsfunction get_unused_fd_flagsfunction __put_unused_fdfunction put_unused_fdfunction might_sleepfunction fputfunction close_fdfunction last_fdfunction __range_cloexecfunction __range_closefunction sys_close_rangefunction do_close_on_execfunction get_file_rcufunction userspacefunction close_fdfunction fdgetfunction fdget_rawfunction file_needs_f_pos_lockfunction file_seek_cur_needs_f_lockfunction fdget_posfunction __f_unlock_posfunction countfunction get_close_on_execfunction do_dup2function replace_fdfunction receive_fd
Annotated Snippet
SYSCALL_DEFINE3(close_range, unsigned int, fd, unsigned int, max_fd,
unsigned int, flags)
{
struct task_struct *me = current;
struct files_struct *cur_fds = me->files, *fds = NULL;
if (flags & ~(CLOSE_RANGE_UNSHARE | CLOSE_RANGE_CLOEXEC))
return -EINVAL;
if (fd > max_fd)
return -EINVAL;
if ((flags & CLOSE_RANGE_UNSHARE) && atomic_read(&cur_fds->count) > 1) {
struct fd_range range = {fd, max_fd}, *punch_hole = ⦥
/*
* If the caller requested all fds to be made cloexec we always
* copy all of the file descriptors since they still want to
* use them.
*/
if (flags & CLOSE_RANGE_CLOEXEC)
punch_hole = NULL;
fds = dup_fd(cur_fds, punch_hole);
if (IS_ERR(fds))
return PTR_ERR(fds);
/*
* We used to share our file descriptor table, and have now
* created a private one, make sure we're using it below.
*/
swap(cur_fds, fds);
}
if (flags & CLOSE_RANGE_CLOEXEC)
__range_cloexec(cur_fds, fd, max_fd);
else
__range_close(cur_fds, fd, max_fd);
if (fds) {
/*
* We're done closing the files we were supposed to. Time to install
* the new file descriptor table and drop the old one.
*/
task_lock(me);
me->files = cur_fds;
task_unlock(me);
put_files_struct(fds);
}
return 0;
}
/**
* file_close_fd - return file associated with fd
* @fd: file descriptor to retrieve file for
*
* Doesn't take a separate reference count.
*
* Returns: The file associated with @fd (NULL if @fd is not open)
*/
struct file *file_close_fd(unsigned int fd)
{
struct files_struct *files = current->files;
struct file *file;
spin_lock(&files->file_lock);
file = file_close_fd_locked(files, fd);
spin_unlock(&files->file_lock);
return file;
}
void do_close_on_exec(struct files_struct *files)
{
unsigned i;
struct fdtable *fdt;
/* exec unshares first */
spin_lock(&files->file_lock);
for (i = 0; ; i++) {
unsigned long set;
unsigned fd = i * BITS_PER_LONG;
fdt = files_fdtable(files);
if (fd >= fdt->max_fds)
break;
set = fdt->close_on_exec[i];
if (!set)
continue;
fdt->close_on_exec[i] = 0;
for ( ; set ; fd++, set >>= 1) {
Annotation
- Immediate include surface: `linux/syscalls.h`, `linux/export.h`, `linux/fs.h`, `linux/kernel.h`, `linux/mm.h`, `linux/sched/signal.h`, `linux/slab.h`, `linux/file.h`.
- Detected declarations: `syscall close_range`, `syscall dup3`, `syscall dup2`, `syscall dup`, `function Copyright`, `function put`, `function __free_fdtable`, `function free_fdtable_rcu`, `function copy_fd_bitmaps`, `function copy_fdtable`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: core 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.