Linux虚拟文件系统–文件路径名的解析(3)–普通文件名

对于一个文件路径的分量,如果其不为’.’和’..’则属于普通文件名,普通文件名的解析由do_lookup()函数来处理

可以想象,搜索一个文件(目录)时,首先肯定要在dentry缓存中查找,当缓存中查找不到对应的dentry时,才需要从磁盘中查找,并新建一个dentry,将磁盘中的数据保存到其中。找到了目标dentry后,就将相应的信息保存到path中,这里因为路径向下进了一层,因此要判断下层目录是否有新的文件系统挂载的问题,和上文讨论的类似,因此要通过__follow_mount()函数判断是否有文件系统挂载在该目录下,另外,对于网络文件系统,还要通过文件系统中定义的d_revalidate()函数来判断该dentry是否有效以保证一致性。

相关阅读: ?where=nkey&keyword=3305

先来看看在dentry缓存中查找的过程

struct dentry * __d_lookup(struct dentry * parent, struct qstr * name) { unsigned int len = name->len; unsigned int hash = name->hash; const unsigned char *str = name->name; struct hlist_head *head = d_hash(parent,hash);//通过parent的地址和hash(hash是name的哈希值)进行定位 struct dentry *found = NULL; struct hlist_node *node; struct dentry *dentry; rcu_read_lock(); hlist_for_each_entry_rcu(dentry, node, head, d_hash) {//扫描head对应的碰撞溢出表 struct qstr *qstr; if (dentry->d_name.hash != hash)//name的hash值不相符,则放弃该dentry continue; if (dentry->d_parent != parent)//父目录不一样,则放弃该dentry continue; spin_lock(&dentry->d_lock); /* * Recheck the dentry after taking the lock – d_move may have * changed things. Don’t bother checking the hash because we’re * about to compare the whole name anyway. */ if (dentry->d_parent != parent) goto next; /* non-existing due to RCU? */ if (d_unhashed(dentry)) goto next; /* * It is safe to compare names since d_move() cannot * change the qstr (protected by d_lock). */ /*当确保了父目录和文件名的哈希值与目标dentry的一致性后,,接下来就只用匹配文件名了*/ qstr = &dentry->d_name;//取当前dentry的文件名 /*如果父目录文件系统定义了比较文件名的方法,则调用之*/ if (parent->d_op && parent->d_op->d_compare) { if (parent->d_op->d_compare(parent, qstr, name)) goto next; } else {//如果没定义 if (qstr->len != len)//先确定长度是否相等 goto next; if (memcmp(qstr->name, str, len))//再比较内存 goto next; } atomic_inc(&dentry->d_count); found = dentry; //这里表明找到了目标dentry spin_unlock(&dentry->d_lock); break; next: spin_unlock(&dentry->d_lock); } rcu_read_unlock(); return found; }

相信梦想是价值的源泉,相信眼光决定未来的一切,

Linux虚拟文件系统–文件路径名的解析(3)–普通文件名

相关文章:

你感兴趣的文章:

标签云: