fs/proc/fd.c

Source file repositories/reference/linux-study-clean/fs/proc/fd.c

File Facts

System
Linux kernel
Corpus path
fs/proc/fd.c
Extension
.c
Size
9104 bytes
Lines
408
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.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations proc_fdinfo_file_operations = {
	.open		= seq_fdinfo_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static bool tid_fd_mode(struct task_struct *task, unsigned fd, fmode_t *mode)
{
	struct file *file;

	file = fget_task(task, fd);
	if (file) {
		*mode = file->f_mode;
		fput(file);
	}
	return !!file;
}

static void tid_fd_update_inode(struct task_struct *task, struct inode *inode,
				fmode_t f_mode)
{
	task_dump_owner(task, 0, &inode->i_uid, &inode->i_gid);

	if (S_ISLNK(inode->i_mode)) {
		unsigned i_mode = S_IFLNK;
		if (f_mode & FMODE_READ)
			i_mode |= S_IRUSR | S_IXUSR;
		if (f_mode & FMODE_WRITE)
			i_mode |= S_IWUSR | S_IXUSR;
		inode->i_mode = i_mode;
	}
	security_task_to_inode(task, inode);
}

static int tid_fd_revalidate(struct inode *dir, const struct qstr *name,
			     struct dentry *dentry, unsigned int flags)
{
	struct task_struct *task;
	struct inode *inode;
	unsigned int fd;

	if (flags & LOOKUP_RCU)
		return -ECHILD;

	inode = d_inode(dentry);
	task = get_proc_task(inode);
	fd = proc_fd(inode);

	if (task) {
		fmode_t f_mode;
		if (tid_fd_mode(task, fd, &f_mode)) {
			tid_fd_update_inode(task, inode, f_mode);
			put_task_struct(task);
			return 1;
		}
		put_task_struct(task);
	}
	return 0;
}

static const struct dentry_operations tid_fd_dentry_operations = {
	.d_revalidate	= tid_fd_revalidate,
	.d_delete	= pid_delete_dentry,
};

static int proc_fd_link(struct dentry *dentry, struct path *path,
			struct task_struct *task)
{
	int ret = -ENOENT;
	unsigned int fd = proc_fd(d_inode(dentry));
	struct file *fd_file;

	fd_file = fget_task(task, fd);
	if (fd_file) {
		*path = fd_file->f_path;
		path_get(&fd_file->f_path);
		ret = 0;
		fput(fd_file);
	}

	return ret;
}

struct fd_data {
	fmode_t mode;
	unsigned fd;
};

static struct dentry *proc_fd_instantiate(struct dentry *dentry,

Annotation

Implementation Notes