open重复打开 linux,open()在Linux内核的实现(6)-打开操作分析

原标题:open()在Linux内核的实现(6)-打开操作分析

1.基本说明

当link_path_walk()进行完毕之后,也就意味着文件路径的查找位于最后一个目录项中,这个目录项是否存在目前还不明确,因为还需要配合用户使用open()时所传递的参数,有可能是打开已存在文件,有可能是创建新文件。

2.函数分析 2.1.do_last()

在path_openat()中,经过link_path_walk()对open路径的查找,将进入do_last()对路径中最后一个目录项做处理。最后一个目录项可能是各种类型,比如“.”或者“..”,也可能是符号链接文件或者是“/”,在此将对普通目录项(LAST_NORM)所进行的处理进行说明。

对于open系统调用来说,flags参数通过取不同的值可以进行不同的操作,下面将针对open最常用的两种操作进行说明,即打开文件和创建文件。

2.1.1.打开文件

如果使用open系统调用的作用仅仅是打开文件,那么flags中必然不会存在O_CREAT标志,基本步骤如下:

1.通过walk_component()对最后一个目录项进行查找。walk_component()首先在rcu模式下对目录项进行查找,如果查找失败则进行ref模式下的目录项查找。如果两种方式均查找失败,则返回值小于0;如果当前目录项为符号链接文件,则返回1,该函数将直接返回到path_openat()中,进而通过follow_link()进行处理;如果查找成功,则跳至ok标号处;

2.完成最后一个目录项的查找工作,即将进行真正的打开操作。不过,在这之前还需要通过may_open()对当前inode的权限和标志位进行检查;

3.如果一切顺利,则通过nameidata_to_filp()执行打开操作;

4.返回file结构。

2.1.2.创建文件

如果创建一个文件,那么flags必然设置标志O_CREAT。基本步骤如下:

1.首先会检查最后一个目录项是否以“/”结尾,如果是,则直接错误返回。否则,继续进行;

2.通过lookup_hash()对最后一个目录项进行查找,这个查找函数将返回一个dentry。如果最后一个目录项确实存在,那么dentry->d_inode不为空,那么说明要创建的这个文件事先是存在的。此时先进行标志位的判断,比如如果用户设置了O_EXCL标志,那么此时就不必继续进行直接错误返回。如果标志检查一切成功,则进行步骤4;否则,dentry->d_inode将为空,继续进行;

3.当最后一个目录项inode为空时,那么需要通过vfs_create()调用具体文件系统的create钩子函数创建这个文件;

4.通过may_open()检查inode标志位和权限的合法性;

5.通过nameidate_to_flip()调用具体文件系统的open钩子函数进行文件的打开工作;

6.返回file。

3.总结

通过前面的系列文章,说明了open()在Linux内核实现。事实上,这仅仅反映的是它在在虚拟文件系统的实现过程,主要涉及的内容为对路径的查找。最终,文件的打开操作必须经过具体文件系统的实现,虽然每个文件系统具体实现不同,但是他们的输入输出都将受到虚拟文件系统的限制保持一致。

参考资料:

2.Linux系统调用open七日游:http://blog.chinaunix.net/uid-20522771-id-4419666.html

3.深入理解Linux内核:http://book.douban.com/subject/2287506/;

4.深入Linux内核架构:http://book.douban.com/subject/4843567/;

5.Linux内核探秘:http://book.douban.com/subject/25817503/;返回搜狐,查看更多

责任编辑:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值