访问proc/pid/stat的调用过程
/fs/proc/internal.h
struct proc_dir_entry {
unsigned int low_ino; //inode编号
umode_t mode; //访问权限的分配,目录项的类型(文件、目录)
nlink_t nlink;
kuid_t uid; //文件所有者的UID
kgid_t gid; //文件所有者的GID
loff_t size;
const struct inode_operations *proc_iops; //对应的inode操作
const struct file_operations *proc_fops; //对应的file操作
struct proc_dir_entry *parent; //proc的父目录项
struct rb_root subdir;
struct rb_node subdir_node;
void *data;
atomic_t count; /* use count */ //引用计数
atomic_t in_use; /* number of callers into module in progress; */
/* negative -> it's going away RSN */
struct completion *pde_unload_completion;
struct list_head pde_openers; /* who did ->open, but not ->release */
spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
u8 namelen;
char name[]; //目录名,如“/proc”
};
union proc_op {
int (*proc_get_link)(struct dentry *, struct path *);
int (*proc_show)(struct seq_file *m,
struct pid_namespace *ns, struct pid *pid,
struct task_struct *task);
};
struct proc_inode {
struct pid *pid;
int fd;
union proc_op op;
struct proc_dir_entry *pde;
struct ctl_table_header *sysctl;
struct ctl_table *sysctl_entry;
const struct proc_ns_operations *ns_ops;
struct inode vfs_inode;
};
/proc对应的实现
static const struct file_operations proc_root_operations = {
.read = generic_read_dir,
.iterate = proc_root_readdir,
.llseek = default_llseek,
};
static const struct inode_operations proc_root_inode_operations = {
.lookup = proc_root_lookup,
.getattr = proc_root_getattr,
};
struct proc_dir_entry proc_root = {
.low_ino = PROC_ROOT_INO,
.namelen = 5,
.mode = S_IFDIR | S_IRUGO | S_IXUGO,
.nlink = 2,
.count = ATOMIC_INIT(1),
.proc_iops = &proc_root_inode_operations,
.proc_fops = &proc_root_operations,
.parent = &proc_root,
.subdir = RB_ROOT,
.name = "/proc",
};
接下再看看/proc/kcore对应的实现,一般crash工具会依赖/proc/kcore来实现dump内核的需求
/fs/proc/kcore.c
static const struct file_operations proc_kcore_operations = {
.read = read_kcore,
.open = open_kcore,
.llseek = default_llseek,
};
static struct proc_dir_entry *proc_root_kcore;
static int __init proc_kcore_init(void)
{
proc_root_kcore = proc_create("kcore", S_IRUSR, NULL,
&proc_kcore_operations);
。。。。。
}
//如果没有在cache里找到的话,就mapping->a_ops->readpage