Linux内核源代码情景分析-特殊文件系统/proc-对/proc/self/cwd的访问

    继上篇文章Linux内核源代码情景分析-特殊文件系统/proc,我们对/proc/loadavg访问后,这篇文章是对/proc/self/cwd的访问。

int __user_walk(const char *name, unsigned flags, struct nameidata *nd)
{
	char *tmp;
	int err;

	tmp = getname(name);//在系统空间分配一个页面,并从用户空间把文件名复制到这个页面
	err = PTR_ERR(tmp);
	if (!IS_ERR(tmp)) {
		err = 0;
		if (path_init(tmp, flags, nd))
			err = path_walk(tmp, nd);
		putname(tmp);
	}
	return err;
}
    name就为 /proc/self/cwd,重要分析下path_walk函数,请参考Linux内核源代码情景分析-从路径名到目标节点

    第一次循环path_walk发现/proc是个安装节点而通过_follow_down找到了proc文件系统的根节点的dentry结构,nameidata结构中的指针dentry指向这个数据结构。、

    第二次循环搜索路径名中的下一个节点self,由于这个节点并不是路径名的最后一个节点,所以执行的代码如下:

dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);//在内存中寻找该节点业已建立的dentry结构  
        if (!dentry) {//如果没有找到  
            dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);//那么就要建立该节点的dentry结构  
            err = PTR_ERR(dentry);  
            if (IS_ERR(dentry))  
                break;  
        }  
    参考 Linux内核源代码情景分析-特殊文件系统/proc,最终也要通过proc_root_lookup()调用proc_lookup(),试图为节点建立起其dentry结构和inode结构。可是由于/proc/self并没有一个固定的proc_dir_entry结构,所以对proc_lookup()的调用必然会失败,因而会进一步调用proc_pid_lookup(),代码如下:

static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
{
	if (dir->i_ino == PROC_ROOT_INO) { /* check for safety... */
		int nlink = proc_root.nlink;

		nlink += nr_threads;

		dir->i_nlink = nlink;
	}

	if (!proc_lookup(dir, dentry))///由于/proc/self并没有一个固定的proc_dir_entry结构,所以对proc_lookup()的调用必然会失败
		return NULL;
	
	return proc_pid_lookup(dir, dentry);//会调用这个函数
}
struct dentry *proc_lookup(struct inode * dir, struct dentry *dentry)
{
	struct inode *inode;
	struct proc_dir_entry * de;
	int error;

	error = -ENOENT;
	inode = NULL;
	de = (struct proc_dir_entry *) dir->u.generic_ip;
	if (de) {//找不到/proc/self节点
		for (de = de->subdir; de ; de = de->next) {
			if (!de || !de->low_ino)
				continue;
			if (de->namelen != dentry->d_name.len)
				continue;
			if (!memcmp(dentry->d_name.name, de->name, de->namelen)) {
				int ino = de->low_ino;
				error = -EINVAL;
				inode = proc_get_inode(dir->i_sb, ino, de);
				break;
			}
		}
	}

	if (inode) {
		dentry->d_op = &proc_dentry_operations;
		d_add(dentry, inode);
		return NULL;
	}
	return ERR_PTR(error);//返回错误码
}

struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry)
{
	unsigned int pid, c;
	struct task_struct *task;
	const char *name;
	struct inode *inode;
	int len;

	pid = 0;
	name = dentry->d_name.name;
	len = dentry->d_name.len;
	if (len == 4 && !memcmp(name, "self", 4))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值