玩转VFS(sys_open, overlayfs, rename)
带着问题学习dentry
1)文件删除时 dentry的结构是如何变化的?是直接设置无效的吗?如果此时正好有个访问是在要删除目录下的一个文件,这咋办呢?
2)内核document目录下级联式地使用 d_seq 去自顶向下地访问目录文件,到底是怎么实现的呢?顺序锁又是个什么东西?
3)dentry 应该是整个内核中被优化最多的地方了吧,既包括 RCU ,又有 seqcount_t, 甚至在RCU模式查找下两者都用到了!并且两种锁设计的初衷都是解决读和写互斥的问题,并且,seqcount_t锁好像是RCU的关键,这几天争取把这个问题搞明白的。
4)http://blog.csdn.net/denzilxu/article/details/9188003
overlayfs简直就是一个逆天的发明,不过这也可能是因为自己刚开始看。它让lowdir老老实实地在下面坐着等,我upperlayer的改动丝毫不会影响到lowerdir,这就逆天了知道吗?除了比较常用的iso文件的读写之外,你还可以搭建一个不同分支多世界观系统啊!比如f2fs-stable仓库中有3.10,4.1,4.4四个分支,每个分支你都是要用的,那么3.10时你就git checkout到3.10分支,需要4.1时你就checkout到4.1的分支,这不合适,那么就需要一个轻量级的多世界系统啊,从此之后,在不拷贝的情况下,你可以同时访问f2fs-stable的所有分支,咋样?
2017/2/7
rename操作简直就疯了,因为它涉及到的东西很多很多,之前一直以为读/写/删除才是文件系统中最重要的部分,但是后面发现rename和setlink操作才是这些操作中比较难的,不过这个难是集中在VFS层,因为VFS要保证文件不会被删除,IBM有篇博客是写文件系统加锁的,里面就涉及到nesting的锁。还有一些概念,比如文件系统的差异备份功能,文件系统的原子写等特殊功能,都是要好好看看的。
rename操作中主要有如下几个标签,包括 RENAME_EXCHANGE 和 RENAME_WHITEOUT 等,材料上说这些都是为union filesystem准备的,现在还不是很清楚到底是怎么回事,试下renameat函数。
2017/2/8
dcache存在的最大好处是不用在目录里一项项查找,
最近在看f2fs的rename,感到这个操作的复杂,晚上坐班车回来看微博,看到阿里的一群人也曾经碰到rename/mv的问题,这么说rename的问题不是孤例。
问题:cp,mv对inode的影响有什么不同;cp和mv覆盖动态库有什么区别;
cp A B, 会首先把B给截断掉,mv则是会保留
2017/2/11
rename操作中涉及到的标签:RENMAE_NOREPLACE, RENAME_EXCHANGE, RENAME_WHITEOUT,这几个标签涉及到的操作。
在linux文件系统中,元数据的加锁操作基本上都是由其虚拟文件系统(VFS)规定的。这样的好处是可以统一管理所有元数据操作的加锁机制,底层的具体文件系统可以不理会这些问题,只需要按照VFS的调用来执行对元数据的操作即可。
在VFS中,对于大多数的元数据操作,可以通过制定统一的加锁顺序来避免死锁的发生,这个顺序是先对父目录加锁,再对要操作的对象加锁,以创建操作为例,当我们要在一个目录下创建新的对象时,必须先对这个目录进行加锁,然后才能放心地进行创建对象的步骤,因此也不用担心该目录中途会被删除,或者其他操作对该创建操作所造成的干扰。按照元数据名字空间的树状结构来看,我们可以认为,”先对父目录加锁,再对要操作的对象(目录或者文件)加锁“是一种从上到下的加锁顺序,只要所有的元数据都遵循这个规则,就不会出现相反的加锁顺序(即从下到上的顺序)。
这个普遍的加锁规则对绝大多数元数据操作都是适用的,比如创建、删除等操作,他们的加锁对象都是要操作的对象以及父目录。但是有两个元数据操作例外:rename和link,因为它们的操作对象不止两个,而这些对象可能位于名字树状结构中的任意几个位置,导致加锁的路径有可能不在名字空间树状结构”从上到下“的范畴内。【其实就是怕两空间是有交叠呗:比如 file1的路径是/home/hon/dir1/file1, file2的目录是/home/hon/dir1/dir2/file2,对file1的加锁路径是dir1->file1,对file2的加锁路径是dir2和file2,应该也没什么特殊才对啊】。错!rename中也有这样一个操作:
http://www.ibm.com/developerworks/cn/linux/l-cn-fsmeta/
单纯的rename很简单,但是当多个rename同时操作:
进程1:mv /home/hon/dir1/file1 /home/hon/dir2/file11
进程2:mv /home/hon/dir2/file2 /home/hon/dir1/file22
此时进程1,先要对dir1上锁,再对dir2上锁,而进程2,先对dir2上锁,然后再对dir1上锁,那么这就有可能产生死锁了。这种隐患的根源在于:rename操作的source和dest可能是在名字空间中的任意一个位置。
所以使用了s_vfs_rename_mutex来保证互斥。在对 target 和 distest 分别进行加锁时要考虑是否是有亲戚关系的,即A的祖父目录是否是B,B的祖父目录是否是A,如果存在祖父的关系,那么需要先对祖父目录加锁,如果不存在这种关系,那么A和B的顺序就无所了。为什么要先加祖父呢?这是为了保证是一个从上到下的加锁关系啊,因为内核中其他部分都是从上到下的,你 s_vfs_rename_mutex 虽然解决了rename之间的互斥,但是没有处理其他方面的互斥,假设还有一个进程C,它在其整条path上顺序加上了所有的锁呢?那怎么办?这不就导致了rename和其他操作的死锁了吗?所以解决了rename之间的冲突后,那么在rename里面,我们就要遵循自上而下的加锁方法!
你以为 move -i 仅仅是用户态的小把戏吗? 【如果真是这样,那么mv file1 file2命令中,无论file2是否存在,都会询问的啊,但是现在来看当file2不存在的时候,根本就没有这样指令输出来,所以move -i 在做真正的rename之前一定是对file2先查了一遍,看是否有这个目录存在,那么问题就来了,查询结束之后,mv会持有file2的引用计数吗?【在整个文件系统的目录中搜】】那么也很有可能发生如下的场景:我刚按下了y,此时有个进程就把file2和file1删掉了,甚至吧file1和file2的父目录给删掉了,这些情况都要咋整呢?】
fstat是一个挺常用的系统调用,会查询一个文件到底在不在
NOREPLACE 标签是说当目标节点存在的时候,
元数据的操作是一种事务操作。元数据的操作大多是由一些小的元数据操作组成,ACID是一个事务的基本特性:原子性,一致性,独立性,持续性。
2017/2/11 19:02 对dentry的构建再发起进攻.
有两种遍历的方式,一种是rcu-walk,一种是ref-walk。
在RCU查找的代码中,多处提到了与rename的互斥,怎么理解呢?
/××/ 插播一条信息:发现了一个很有意思的小工具叫ionotifywait,可以跟踪一个文件,并输出你对这个文件的操作,这个可能就是和文件系统中各处都是的 fsnotify 有关吧。
在 vfs_rename->d_move 中会对 dentry 进行重映射
为什么rename 在dentry的查找中一直被提及,这是因为rename操作涉及到dentry从一个 hash list 转移到另一个 hash list 中,而这种情形在普通的删除中是不存在的。这里好好说说。
这里涉及到RCU的grace period,在一次grace period彻底失效之前,这个被删除的dentry的指针是一直有效的,但是在rename中,由于他要在grace period之前把rename的dentry的及时插入到新的list中,所以其指针索引处就不是正确的,因此一定要避免rename这种情况。
A--B--C 三个dentry,怎么同时改变A和C的指针呢?
现在最关键的点是看 lookup_rcu 到底和 rename 冲突在哪里!或者说rename是怎么就在一个grace period里面就完成了历史性的从一个dentry hash表中删除,然后到另一个hash表中去。
普通的删除操作中在一个 grace period 中不会出现dentry的复用的【想起了f2fs中nid的复用!】
之前dentry想的方法是从头开始创建一个新的 dentry 插入到新的list中,但是这样做的效率太低,所以就想着直接”废物利用"了。在d_drop & d_rehash 外面,是被seq_count套住,所以lookup的地方可以在这里判断
玩转VFS(sys_open, overlayfs, rename)的更多相关文章
- 玩转VFS(二)
关于VFS的第一篇中已经太长了 http://www.cnblogs.com/honpey/p/6348914.html 另起一篇: 1)如何在kernel里找到目前文件系统中的根目录: 2) 如何能 ...
- 【Linux高级驱动】input子系统框架【转】
转自:http://www.cnblogs.com/lcw/p/3802617.html [1.input子系统框架(drivers\input)] 如何得出某个驱动所遵循的框架? 1) 通过网 ...
- Docker 的两类存储资源 - 每天5分钟玩转 Docker 容器技术(38)
我们从本章开始讨论 Docker 存储. Docker 为容器提供了两种存放数据的资源: 由 storage driver 管理的镜像层和容器层. Data Volume. 我们会详细讨论它们的原理和 ...
- CVE-2015-1328 Ubuntu 12.04, 14.04, 14.10, 15.04 overlayfs Local Root
catalog . 引言 . Description . Effected Scope . Exploit Analysis . Principle Of Vulnerability . Patch ...
- 使用 /proc 文件系统来访问 linux操作系统 内核的内容 && 虚拟文件系统vfs及proc详解
http://blog.163.com/he_junwei/blog/static/19793764620152743325659/ http://www.01yun.com/other/201304 ...
- 函数指针玩得不熟,就不要自称为C语言高手(函数指针是解耦对象关系的最佳利器,还有signal)
记得刚开始工作时,一位高手告诉我说,longjmp和setjmp玩得不熟,就不要自称为C语言高手.当时我半信半疑,为了让自己向高手方向迈进,还是花了一点时间去学习longjmp和setjmp的用法.后 ...
- Docker存储驱动之OverlayFS简介
简介 OverlayFS是一种和AUFS很类似的文件系统,与AUFS相比,OverlayFS有以下特性: 1) 更简单地设计: 2) 从3.18开始,就进入了Linux内核主线: 3) 可能更快一些. ...
- cgroup原理简析:vfs文件系统
要了解cgroup实现原理,必须先了解下vfs(虚拟文件系统).因为cgroup通过vfs向用户层提供接口,用户层通过挂载,创建目录,读写文件的方式与cgroup交互.因为是介绍cgroup的文章,因 ...
- Docker镜像存储-overlayfs
一.概述 Docker中的镜像采用分层构建设计,每个层可以称之为“layer”,这些layer被存放在了/var/lib/docker/<storage-driver>/目录下,这里的st ...
随机推荐
- 【TOJ 3305】Hero In Maze II
描述 500年前,Jesse是我国最卓越的剑客.他英俊潇洒,而且机智过人^_^.突然有一天,Jesse心爱的公主被魔王困在了一个巨大的迷宫中.Jesse听说这个消息已经是两天以后了,他急忙赶到迷宫,开 ...
- java.lang.Exception: No tests found matching [{ExactMatcher:fDisplayName=testSelect], {ExactMatcher:fDisplayName=testSelect(cool.zsn.Dao.UserMapperTest)], {LeadingIdentifierMatcher:fClassName=cool.zsn
@Before:每次调用类中的方法,都会先执行@Before下的方法 @Before下的方法应该是 public : @Before public void init() { application ...
- oracle的局部本地分区索引
环境:oracle 12.2.0.1 注:未确定10g,11g是否有这些特性.现在基本不用10g,主要用12c,11g. 毫无疑问,这种 特性对于dba或者实施人员而言显得很重要,尤其当你的数据库主要 ...
- Linux系统VPS主机SSH常用命令
putty查询log文当里的"test"关键字 /home/iotserver/WebServer3_log# grep "test" log.log.bak2 ...
- js | javascript获取和设置元素的属性
获取和设置元素的内容: var nv = document.getElementById("pid"); alert(nv.innerHTML); nv.innerHTML=&qu ...
- dom4j支持Xpath的具体操作
***默认情况下,dom4j不支持xpath. 如果想要使用xpath,需要引入jaxen-1.1-beta-6.jar包. 在dom4j中提供了两个方法来支持xpath. ***selectNode ...
- web前端总结面试问题<经常遇到的手写代码>
冒泡排序 var arr = [5,8,3,6,9] for(var i=0;i<arr.length;i++){ for(var j=i+1;j<arr.length;j++){ if( ...
- [MIP]mip-script组件自定义 JS 代码使用限制
自mip升级v2版本后,多了一个mip-script组件,很多人就都以为可以写自定义js代码了!然并卵,MIP2页中还是一样不允许自定义javascript代码,所有的交互须通过组件实现. 引用官方说 ...
- Windows使用Node.js自动生成Vue.js模版环境部署步骤-----记录
node.js官网下载并安装node 进入node文档目录下,运行cmd 输入 node -v 查看node版本 出现表示安装完成 输入 npm -v 显示npm版本信息 安装cnpm 输入 npm ...
- NAND Flash结构及驱动函数
目标:以NAND Flash K9F2G08U0M为例介绍其结构及其驱动程序的书写 1. 结构 由芯片手册中的图可知:K9F2G08U0M大小为2112Mbits(即 256MB = 2Gb ) 共有 ...