f2fs中node page的lock_page
[都是思想片段, 待好好整理]
node page的lock_page首先是为了改变page的状态:set_page_dirty, 还有set_nid操作时也会设置父节点的nid, 但是这样设置node-page的粒度是不是太小了!
node_page首先不会有用户态的进程去操作它, 因为node对用户态是透明的, 所以lock_page node page的处理的race condition是:
node分成两类:dnode和间接node, 对于dnode, 需要处理的gc和f2fs_write_data_page之间的
dnode的lock_page处理的是gc&f2fs_write_data_page的互斥;
gc是一个非常简单的进程, 找到了文件的node之后,就直接move_data了,原来GC才是整个f2fs文件系统的终极大boss! 里面包含着一个非常重要的互斥: gc和truncate互斥!
因为整个gc的过程是通过SSA完成的, SSA中存放的是这个block的dnode的nid,然后再通过这个nid找到nid所属的ino的信息;
由于SSA一经写回便不再修改, 所以参照SSA去回收数据的时候, 最重要的一个参考就是sit bitmap, 这是个超重要, 如果一直以来没有操作这个文件还好, 一旦发生了文件的写操作, 导致了异地更新, 那么这个block就是无效的, 但是sit的判断已经过了呢! 还有一个问题, 那就是truncate部分数据, 以及truncate掉这个文件所有的数据, 会发现,这个block的地址都是无意义的才对, 但是SSA中这一块的数据仍然是在的!
如何判断一个inode的数据仍然是在的呢?
首先根据summary中的nid得到node_page, node_page中的信息就丰富了(这个另谈), 然后根据nid的信息, 我们查找nid_root基树, 根据这棵树, 我们就能找到这个nid更丰富的信息, 包括这个nid的blkaddr, ino, version, 还有flag, 当然这个flag是指CHECKPOINTED那些, 是给fsync, recovery机制用的!也就是说, 根据SSA中的nid, 基本这个文件的信息就全乎了!
那么下面说说各种竟态条件:
1) 当文件发生了异地更新. 此时, 这个nid依旧是坚挺的, 我还要用, 但是我node_page中的索引发生了变化, 所以需要判断一下是否是node_page[ofs] 是否是和 blk_addr相等,
2)当文件发生了truncate操作. 分两种情况, 该data_block的dnode是否被删除了, 如果没有, 那么可以归结为状况1), 如果被删除了, 那么这个nat_entry中version就要+1了, 并且已经没有了dnode, 连地址都没得比![看来, 看lock_page还是对的, 瞅瞅, version一直以来的未解之谜终于解开了! ]
3)当整个文件都被truncate掉了, 可以归结为状况2);
应该没有其他的情况了, 因为f2fs的代码里面也就说了1)和2), 哎, 我也不想了, 心累!
但是, 还!没!完! 还有更高级的大boss在等着, 那就是这里到底是如何处理互斥的,
可以看到, 这里和互斥相关的代码有两部分, 首先看gc部分:
gc中的代码主要是上来先把dnode的锁(lock_page)持有了, 这个就很重要了, 因为我们发现, 当异地更新和truncate的时候, 也是先要试着得到dnode的锁才能进行下面的操作呢(异地更新:do_write_data_page, truncate:truncate_dnode)! 数据更新部分都是在这两部分之间完成的!
但是整个代码是值得商榷的, is_alive函数里面, 在dnode在lock_page的前提下进行的inode的检查, 检查完了之后, 就直接退了出来, 假设就在这个时候, 发生了do_write_data_page 或者 truncate_dnode, 那么is_alive一步的检查也被过滤掉了, 其实可以最大限度地过滤掉无用segment!
-----------------
至此, f2fs文件系统里面,基本所有的元数据都研究结束了!
那么, high level地去看文件系统中的锁, 有如下心得:
1) 文件系统会暴露出外部接口供用户态使用:write/read/truncate/mkdir/unlink/fallocate等等, 这些操作都是有 inode->i_mutex 保护, 这个锁的粒度是很大的, 可以屏蔽掉我们许多的顾虑. inode->i_mutex加锁, 是为了达到用户文件操作层面的原子性, 这一点是很重要的, 因为涉及到文件元数据的更新, 一定不能同时进入这个共享资源区!
2) 许多重要的元数据的变化都是外部文件系统接口变化引入的, 比如 f2fs 文件系统, truncate 的时候, 会涉及到大面的 nat_entry 基树中节点的数据变化, node page中无效索引的变化
3) write_back过程涉及到如下几个点: ①元数据的更新, 因为涉及SIT的update, SSA, 还有全局的数据, 包括valid block的数目等, 所以需要有f2fs_lock_op来保证与write_checkpoint的互斥! ② 由于data page已经被lock_page住了, 所以我们最害怕的truncate操作肯定是不用担心了, 因为truncate这个page的时候会lock失败的, 因此此时此刻, 不会又进程会碰到这个页, 这样也不会碰到这个page的dnode也不会出现什么问题, 所以这个page是安全的, 此时dnode的page已经创建了, 但是此时此刻, dnode应该也是安全的[会不会有一个竟态? truncate的时候, 不都是先得到dnode, 然后再去truncate里面的数据的吗?应该不会, truncate之前会truncate掉所有page-cache中的页!]
4) write_back完了之后, 很可能马上会触发truncate操作, 此时就很尴尬了, 刚写回的东西是无效的了, 但是不影响我们文件系统的行为!
突然想起一件事情, 在这里白扯白扯, 就是在write_checkpoint的时候, 怎么就能保证文件系统的一直性呢? 首先, 我们会把所有的脏的dentry写回, 然后把脏的node_page写回, 然后一些基本的元数据也是一样一样地写回去, 然后就是一些基本的数据了,包括NAT, SIT,SSA等信息, 但是, 这个时候有个很尴尬的问题, 那就是NAT, 包括dnode中有很多索引都是NEW_ADDR(-1), 即数据都还没有写回呢都!
首先NAT是不会出现这个问题的, 因为write_checkpoint的时候, node的page会强制的刷回, 这样一来, 所有已经分配的NID, 其对应的node都会对应的, 所以这个是无所谓的, 但是dnode中还是可能会存在NEW_ADDR的情形, 这个时候就说明上次数据没写回就强制断电了!
f2fs中node page的lock_page的更多相关文章
- 回发或回调参数无效。在配置中使用 pages enableEventValidation=true 或在页面中使用 %@ Page EnableEventValidation=true % 启用了事件验证
WebForm中回发或回调参数无效问题的解决 解决 .NET中回发或回调参数无效问题的解 该错误的详细提示信息为: 回发或回调参数无效.在配置中使用 <pages enableEventVali ...
- 回发或回调参数无效。在配置中使用 <pages enableEventValidation="true"/> 或在页面中使用 <%@ Page EnableEventValidation="true" %> 启用了事件验证。
问题补充: “/Source”应用程序中的服务器错误. 回发或回调参数无效.在配置中使用 <pages enableEventValidation="true"/> 或 ...
- Centos7 中 Node.js安装简单方法
最近,我一直对学习Node.js比较感兴趣.下面是小编给大家带来的Centos7 中 Node.js安装简单方法,在此记录一下,方便自己也方便大家,一起看看吧! 安装node.js 登陆Centos ...
- ionic中generate page后module.ts报错的解决办法
此问题出现在Ionic官方将版本从2.2升级到Ionic3以上之后, 在项目中generate page时,自动创建的module.ts就报错,如下: 解决办法如下: 1)将IonicModule替换 ...
- 在jsp中,page指令的()属性用来引入需要的包或类。
在jsp中,page指令的()属性用来引入需要的包或类. A.extends B.import C.language D.contentType 解答:B
- (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(3)修正
@author: 白袍小道 转载说明原处,爱护劳动 插件同步在GITHUB: DaoZhang_XDZ 说明 1.本篇是接着-----(原) MaterialEditor部- Umat ...
- (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(3)
@author: 白袍小道 转载说明原处 插件同步在GITHUB: DaoZhang_XDZ 说明 1.本篇是接着-----(原) MaterialEditor部- UmateriaE ...
- kubernetes中node心跳处理逻辑分析
最近在查看一个kubernetes集群中node not ready的奇怪现象,顺便阅读了一下kubernetes kube-controller-manager中管理node健康状态的组件node ...
- Linux系统中的Page cache和Buffer cache
Linux系统中的Page cache和Buffer cache Linux中有两个很容易混淆的概念,pagecache和buffercache,首先简单将一些Linux系统下内存的分布,使用free ...
随机推荐
- iOS开发之多线程技术——GCD篇
本篇将从四个方面对iOS开发中GCD的使用进行详尽的讲解: 一.什么是GCD 二.我们为什么要用GCD技术 三.在实际开发中如何使用GCD更好的实现我们的需求 一.Synchronous & ...
- iOS开发之多线程技术
本篇争取一篇讲清讲透,依然将通过四大方面清晰的对iOS开发中多线程的用法进行详尽的讲解: 一.什么是多线程 1)多线程执行原理 2)线程与进程 3)多线程的优缺点 二.我们为什么要用多线程编程技术 三 ...
- 使用windows服务更新站点地图
由于公司平台访问人数逐渐增多,公司项目的数据库已经几次出现宕机现象.为减轻数据库压力,我上个月对公司项目做了下调整.把新闻板块提取出来单独一个站点,单独一个数据库.减少了主站点和数据库的负担和压力. ...
- jar 命令 打包装class文件的文件夹
由于将spring源代码导入到eclipse后,缺少jar包, 所以从maven仓库中下载spring发布的spring-core jar包. 为了方便理解目录结构,使用tree命令: tr ...
- js自执行函数的几种不同写法的比较
经常需要一个函数自执行,可惜这一种写法是错的: function(){alert(1);}(); 原因是前半段“function(){alert(1);}”被当成了函数声明,而不是一个函数表达式,从 ...
- JavaScript Patterns 4.8 Function Properties - A Memoization Pattern
Gets a length property containing the number of arguments the function expects: function func(a, b, ...
- Oracle systemstate dump介绍
当数据库出现严重的性能问题或者hang起的时候,那么我们非常需要通过systemstate dump来知道进程在做什么,在等待什么,谁是资源的持有者,谁阻塞了别人.在出现上述问题时,及时收集syste ...
- Tomcat:Custom a common error page valve for all web application in tomcat
如果在一个Tomcat Server上会部署多个Web应用,又希望这多个Web应用共用一套错误页面,而不是使用默认的错误页面.就需要自定义错误页面了. 在每个web应用中都可以通过error-page ...
- sql server 小记——分区表(上)
我们知道很多事情都存在一个分治的思想,同样的道理我们也可以用到数据表上,当一个表很大很大的时候,我们就会想到将表拆 分成很多小表,查询的时候就到各个小表去查,最后进行汇总返回给调用方来加速我们的查询速 ...
- .NET领域驱动设计—实践(穿过迷雾走向光明)
阅读目录 开篇介绍 1.1示例介绍 (OnlineExamination在线考试系统介绍) 1.2分析.建模 (对真实业务进行分析.模型化) 1.2.1 用例分析 (提取系统的所有功能需求) 1.3系 ...