Linux 系统调用之open(二)

本文详细解析了Linux系统调用open过程中,dentry结构的创建以及如何通过inode查找和关联的过程。从d_alloc_parallel()开始,经d_alloc()、__d_alloc()函数,最终在ext4_lookup()中找到inode,并在d_splice_alias()和__d_add()函数中完成dentry与inode的绑定,确保后续lookup快速定位。
摘要由CSDN通过智能技术生成
上一篇里面我们以打开"/home/gaobsh/a.txt"为例分析了系统调用"open"的内核实现。其中我们假设了路径名中所有部分的dentry结构体均已存在在系统缓存中。即通过 lookup_fast()函数成功找到目标文件的dentry。这里我们分析一下如果上述路径名某一部分如果不能通过 lookup_fast()函数查找到的情况。这里还以 上一篇里面的例子进行分析。在 walk_component()函数通过调用 lookup_fast()函数如果失败,则进入 lookup_slow()函数。在 lookup_slow()函数为目标文件创建一个新的dentry,并加入到系统缓存中。现来分析其具体过程。例如假设文件夹“gaobsh”尚不存在在系统缓存中(虽然这种情况几乎不存在。。。)。 lookup_slow()函数在本示例中定义等价与如下(在这里我们仍然不考虑函数调用失败和进程同步等问题):
static struct dentry *lookup_slow(const struct qstr *name,
                  struct dentry *dir,
                  unsigned int flags)
{
    struct dentry *dentry = ERR_PTR(-ENOENT), *old;
    struct inode *inode = dir->d_inode;
    DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);

    inode_lock_shared(inode);
    /* Don't go there if it's already dead */
    if (unlikely(IS_DEADDIR(inode))) /* if 判断为 0 */
        ...
again:
    dentry = d_alloc_parallel(dir, name, &wq);
    if (IS_ERR(dentry)) /* if 判断为 0 */
        ...
    if (unlikely(!d_in_lookup(dentry))) { /*不考虑并发性问题, if 判断为 0 */
        ...
    } else {
        old = inode->i_op->lookup(inode, dentry, flags); /* 一般情况下,返回NULL */
        d_lookup_done(dentry);
        if (unlikely(old)) { /* if 判断为  0 */
            ...
        }
    }
out:
    inode_unlock_shared(inode);
    return dentry;
}

先来分析其中的d_alloc_parallel()函数。在本例中,该函数定义等价与如下,(该函数涉及很多并发性问题的考虑,参考这篇文章):

struct dentry *d_alloc_parallel(struct dentry *parent,
				const struct qstr *name,
				wait_queue_head_t *wq)
{
	unsigned int hash = name->hash;
	struct hlist_bl_head *b = in_lookup_hash(parent, hash);
	struct hlist_bl_node *node;
	struct dentry *new = d_alloc(parent, name);
	struct dentry *dentry;
	unsigned seq, r_seq, d_seq;

	if (unlikely(!new)) /* if 判断为 0 */
		...

retry:
	rcu_read_lock();
	seq = smp_load_acquire(&parent->d_inode->i_dir_seq) & ~1;
	r_seq = read_seqbegin(&rename_lock);
	dentry = __d_lookup
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值