Linux2.4从路径名到目标结点

本文深入探讨了Linux内核如何处理文件系统路径名,包括如何查找或创建目标文件的dentry和inode结构。介绍了核心函数如__user_walk()、path_walk()及其实现细节,例如缓存查找、真实查找、i节点获取等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0.__user_walk() -----> 根据给定的文件路径名在,内存中找到或建立代表着目标文件或目录的dentry结构和inode结构

(1)获得路径名getname():在上一篇博客中有介绍

(2)准备路径搜索path_init():见1

(3)沿着路径名的指引进行搜索path_walk():见2

(4)释放路径名putname()


1.path_init() -----> 准备路径搜索

(1)将vfsmount设置为搜索起点所在的文件系统的安装信息

(2)将dentry设置为搜索起点的目录项

搜索起点可以因系统调用的参数而不同,可以是当前目录,或是根目录,或是“替换”根目录


2.path_walk():沿着路径名的指引进行搜索


补充:

到达父节点:

(1)若当前节点是本进程的根结点,则不需要处理

(2)若当前节点不是其所在设备的根结点,则:

修改其dentry指针,指向其父节点的目录项

(3)运行到这里,说明当前节点一定是其所在设备的根节点,若其所在的设备是根设备,则不需要处理

(4)运行到这里,说明当前节点是非根设备的根节点,因此要往上跑一层跑到安装点的上一层目录中,则:

获得父设备的vfsmount

获得当前设备的安装点的dentry

释放原dentry

置为新的dentry

释放原vfsmount

置为新的vfsmount

go to step1//再循环一次,是因为这里只是从根节点的dentry得到其安装点的dentry,但从文件系统的角度看,它们是等价的


3.对于正常的中间节点的处理

(1)从文件名得到对应的dentry

先从内存中找这个dentry:cached_lookup()见4

如果内存中没有,则申请一个新的,并从磁盘中找到对应文件名的dentry,用于设置内存中dentry的信息:real_lookup()见5

(2)如果目标结点是一个安装点,则前进到所安装设备的根节点

如果前进后还是安装点,继续前进,直到不是安装点

(3)若当前操作系统支持连接,则

跟随连接do_follow_link():见7

        若当前操作系统不支持连接,则(已经找到目标节点)

释放当前目录项

将目标节点的目录项置为当前目录项


4.cached_lookup() -----> 从内存中找到文件名对应的dentry

(1)再hash一次

(2)找到文件名在hash表中的队列的头结点

dentry在内存是以hash的方式存在的

(3)从队列中dentry依次和目标dentry比较

(4)若找到了正常的dentry,对找到的dentry进行验证

若未找到,则返回空


5.real_lookup -----> 从磁盘中找到对应文件名的dentry

(1)再次确认不在内存中cached_lookup():见4

(2)从内存中分配 一个dentry数据结构,并对其初始化

(3)从磁盘中由当前节点代表的那个目录中寻找目标节点的目录项(结合文件和读写和设备驱动),并根据其内容设置内存中的dentry

书把当前节点称为父节点,把目标节点称为当前节点,但我认为些时还没有进行节点切换,这段代码中针对的节点还是下一个节点,只是相对于这一段代码来说算是当前节点,但相对于整篇文章来说,是下一个节点,或是目标节点

(4)由目录项得到i节点号

(5)从i节点号得到i节点结构,如果内存中没有,就申请一个,把并内容从磁盘中读进来iget():见6

过程与3相似

(6)把新申请的dentry结构挂入i节点的d_alias队列中,dentry的d_inode指针也指向i节点结构

一个dentry指向一个inode,但一个inode可以指向多个dentry,因为一个有效的路径名一定对应一个文件,但是一个文件不一定只有一个路径名(或文件名)

(7)把dentry结构挂入hash队列

4中正是利用这个hash队列来查找dentry结构的


6.iget() ----> 从i节点号得到i节点结构,如果内存中没有,就申请一个,把并内容从磁盘中读进来

(1)从内存中寻找i节点号对应的i节点结构,通过hash表

(2)若未找到,则

申请一个i节点结构

再试一次从内存中寻找i节点号对应的i节点结构

把新申请的i节点结构链入队列

为什么新申请的i节点初始化

读入i节点


7.do_follor_link() -----> 跟随连接

(1)获取连接目标的路径名

(2)调用2.path_walk()来找到代表连接对象的dentry结构

因为符号连接是跨文件系统的,所以这里是VFS层次的调用


8.last_with_slashes()

路径名末尾有个'/'字符,意味着路径名的终点是个目录,并且,如果这个节点代表着一个连接,就一定要前进到所连接的对象(也是个目录)


9.last_component()

与3-7的过程几乎一样,稍微有一点区别,觉得不重要,不详细写出,见《Linux内核源代码情景分析》  上册P466                                                                                                                           

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值