您的位置:首页 > 运维架构

procfs下的proc_fops何时调用.

2013-02-25 17:50 127 查看
最近有一网友在看代码时,问到proc下的文件如何ioctl,以前一直以为其不能ioctl,因为proc做一个子文件系统,有其独特的操作方式及api.人呢,最不应该犯的就是主观主义错误,查看内核代码发现proc的注册入口中包含:

struct proc_dir_entry {
unsigned int low_ino;
unsigned short namelen;
const char *name;
mode_t mode;
nlink_t nlink;
uid_t uid;
gid_t gid;
loff_t size;
const struct inode_operations *proc_iops;
/*
* NULL ->proc_fops means "PDE is going away RSN" or
* "PDE is just created". In either case, e.g. ->read_proc won't be
* called because it's too late or too early, respectively.
*
* If you're allocating ->proc_fops dynamically, save a pointer
* somewhere.
*/
const struct file_operations *proc_fops;
struct proc_dir_entry *next, *parent, *subdir;
void *data;
read_proc_t *read_proc;
write_proc_t *write_proc;
atomic_t count;		/* use count */
int pde_users;	/* number of callers into module in progress */
spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
struct completion *pde_unload_completion;
struct list_head pde_openers;	/* who did ->open, but not ->release */
};
const struct file_operations *proc_fops;
这句说明了其是可以实现文件的正常操作的.

那执行cat /proc/xxxx时,什么时候调用read_proc,什么时候调用proc_fops->read呢?

答案:

在注册entry的时候,如果提供read_proc,读文件时调用路径为
proc_file_operations->read->proc_file_read->read_proc

否则使用文件自己的file_operations中的read来读

proc_register函数

static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
{
unsigned int i;
struct proc_dir_entry *tmp;

i = get_inode_number();
if (i == 0)
return -EAGAIN;
dp->low_ino = i;

if (S_ISDIR(dp->mode)) {
if (dp->proc_iops == NULL) {
dp->proc_fops = &proc_dir_operations;
dp->proc_iops = &proc_dir_inode_operations;
}
dir->nlink++;
} else if (S_ISLNK(dp->mode)) {
if (dp->proc_iops == NULL)
dp->proc_iops = &proc_link_inode_operations;
} else if (S_ISREG(dp->mode)) {
if (dp->proc_fops == NULL)
dp->proc_fops = &proc_file_operations;
if (dp->proc_iops == NULL)
dp->proc_iops = &proc_file_inode_operations;
}

spin_lock(&proc_subdir_lock);

for (tmp = dir->subdir; tmp; tmp = tmp->next)
if (strcmp(tmp->name, dp->name) == 0) {
WARN(1, KERN_WARNING "proc_dir_entry '%s/%s' already registered\n",
dir->name, dp->name);
break;
}

dp->next = dir->subdir;
dp->parent = dir;
dir->subdir = dp;
spin_unlock(&proc_subdir_lock);

return 0;
}
如果proc_fops == NULL时,dp->proc_fops = &proc_file_operations;

作者:张亮校

日期 :2013.2.25
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: