fs/proc/generic.c

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

File Facts

System
Linux kernel
Corpus path
fs/proc/generic.c
Extension
.c
Size
20247 bytes
Lines
858
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_dir_operations = {
	.llseek			= generic_file_llseek,
	.read			= generic_read_dir,
	.iterate_shared		= proc_readdir,
};

static int proc_net_d_revalidate(struct inode *dir, const struct qstr *name,
				 struct dentry *dentry, unsigned int flags)
{
	return 0;
}

const struct dentry_operations proc_net_dentry_ops = {
	.d_revalidate	= proc_net_d_revalidate,
	.d_delete	= always_delete_dentry,
};

/*
 * proc directories can do almost nothing..
 */
static const struct inode_operations proc_dir_inode_operations = {
	.lookup		= proc_lookup,
	.getattr	= proc_getattr,
	.setattr	= proc_setattr,
};

static void pde_set_flags(struct proc_dir_entry *pde)
{
	const struct proc_ops *proc_ops = pde->proc_ops;

	if (!proc_ops)
		return;

	if (proc_ops->proc_flags & PROC_ENTRY_PERMANENT)
		pde->flags |= PROC_ENTRY_PERMANENT;
	if (proc_ops->proc_read_iter)
		pde->flags |= PROC_ENTRY_proc_read_iter;
#ifdef CONFIG_COMPAT
	if (proc_ops->proc_compat_ioctl)
		pde->flags |= PROC_ENTRY_proc_compat_ioctl;
#endif
	if (proc_ops->proc_lseek)
		pde->flags |= PROC_ENTRY_proc_lseek;
}

/* returns the registered entry, or frees dp and returns NULL on failure */
struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
		struct proc_dir_entry *dp)
{
	if (proc_alloc_inum(&dp->low_ino))
		goto out_free_entry;

	if (!S_ISDIR(dp->mode))
		pde_set_flags(dp);

	write_lock(&proc_subdir_lock);
	dp->parent = dir;
	if (pde_subdir_insert(dir, dp) == false) {
		WARN(1, "proc_dir_entry '%s/%s' already registered\n",
		     dir->name, dp->name);
		write_unlock(&proc_subdir_lock);
		goto out_free_inum;
	}
	dir->nlink++;
	write_unlock(&proc_subdir_lock);

	return dp;
out_free_inum:
	proc_free_inum(dp->low_ino);
out_free_entry:
	pde_free(dp);
	return NULL;
}

static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
					  const char *name,
					  umode_t mode,
					  nlink_t nlink)
{
	struct proc_dir_entry *ent = NULL;
	const char *fn;
	struct qstr qstr;

	if (xlate_proc_name(name, parent, &fn) != 0)
		goto out;
	qstr.name = fn;
	qstr.len = strnlen(fn, NAME_MAX + 1);
	if (qstr.len == 0) {
		WARN(1, "empty name\n");
		return NULL;

Annotation

Implementation Notes