[都是思想片段, 待好好整理]

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的更多相关文章

  1. 回发或回调参数无效。在配置中使用 pages enableEventValidation=true 或在页面中使用 %@ Page EnableEventValidation=true % 启用了事件验证

    WebForm中回发或回调参数无效问题的解决 解决 .NET中回发或回调参数无效问题的解 该错误的详细提示信息为: 回发或回调参数无效.在配置中使用 <pages enableEventVali ...

  2. 回发或回调参数无效。在配置中使用 <pages enableEventValidation="true"/> 或在页面中使用 <%@ Page EnableEventValidation="true" %> 启用了事件验证。

    问题补充: “/Source”应用程序中的服务器错误. 回发或回调参数无效.在配置中使用 <pages enableEventValidation="true"/> 或 ...

  3. Centos7 中 Node.js安装简单方法

    最近,我一直对学习Node.js比较感兴趣.下面是小编给大家带来的Centos7 中 Node.js安装简单方法,在此记录一下,方便自己也方便大家,一起看看吧! 安装node.js 登陆Centos ...

  4. ionic中generate page后module.ts报错的解决办法

    此问题出现在Ionic官方将版本从2.2升级到Ionic3以上之后, 在项目中generate page时,自动创建的module.ts就报错,如下: 解决办法如下: 1)将IonicModule替换 ...

  5. 在jsp中,page指令的()属性用来引入需要的包或类。

    在jsp中,page指令的()属性用来引入需要的包或类. A.extends B.import C.language D.contentType 解答:B

  6. (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(3)修正

    @author: 白袍小道 转载说明原处,爱护劳动 插件同步在GITHUB: DaoZhang_XDZ         说明 1.本篇是接着-----(原) MaterialEditor部- Umat ...

  7. (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(3)

    @author: 白袍小道 转载说明原处 插件同步在GITHUB: DaoZhang_XDZ         说明 1.本篇是接着-----(原) MaterialEditor部- UmateriaE ...

  8. kubernetes中node心跳处理逻辑分析

    最近在查看一个kubernetes集群中node not ready的奇怪现象,顺便阅读了一下kubernetes kube-controller-manager中管理node健康状态的组件node ...

  9. Linux系统中的Page cache和Buffer cache

    Linux系统中的Page cache和Buffer cache Linux中有两个很容易混淆的概念,pagecache和buffercache,首先简单将一些Linux系统下内存的分布,使用free ...

随机推荐

  1. iOS 设置系统屏幕亮度

    // 设置系统屏幕亮度    //    [UIScreen mainScreen].brightness = value;    // 或者    [[UIScreen mainScreen] se ...

  2. 【VLC-Android】vlc-android简例

    前言 继续折腾vlc,做这个例子并不顺利,卡在只有声音没有图像这个问题好久,网上的例子有些API已经对不上,继续分享,,, 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cn ...

  3. Mysql查询按照某字段指定顺序排序

    在项目当中用到Sphinx的时候,很多人遇到了这样的问题:使用mysql+Sphinx检索出了相关度的ID后,如何按照指定ID在Mysql中进行排序呢?这里是我在项目中的解决方法: 1 SELECT ...

  4. 通过dubbo暴露接口调用方法,及基于zookeeper的dubbo涉及配置文件

    现在很流行的Dubbo很多朋友都听说过吧,最近我也在看这方面的东西,分享先我的心得笔记. 先说说我们团队要做的项目框架,很简单重在实现基于zookeeper的dubbo注册. 框架:springmvc ...

  5. 赫夫曼\哈夫曼\霍夫曼编码 (Huffman Tree)

    哈夫曼树 给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree).哈夫曼树是带权路径长度最短的树,权值较大的结点离 ...

  6. 适当使用enum做数据字典 ( .net c# winform csharp asp.net webform )

    在一些应用中,通常会用到很多由一些常量来进行描述的状态数据,比如性别(男.女),审核(未审核.已审核)等.在数据库中一般用数字形式来存储,比如0.1等. 不好的做法 经常看到一些应用(ps:最近又看到 ...

  7. Hadoop自定义分组Group

    matadata: hadoop a spark a hive a hbase a tachyon a storm a redis a 自定义分组 import org.apache.hadoop.c ...

  8. 弹出层在兼容模式和IE8模式下显示不正常

    弹出层在火狐.谷歌.360极速模式.IE6下都能100%面积正常显示,但在IE8和360的兼容模式下只显示弹出层下半部分或右半部分的内容,在主页面加上: <meta http-equiv=&qu ...

  9. 0022 Java学习笔记-面向对象-继承、多态、组合

    继承的特点 单继承:每个子类最多只有一个直接父类,注意是直接父类,间接父类个数不限 注意父类的概念:A-->B-->C-->D,在这里,ABC都是D的父类,C是D的直接父类,AB是D ...

  10. coursera机器学习笔记-多元线性回归,normal equation

    #对coursera上Andrew Ng老师开的机器学习课程的笔记和心得: #注:此笔记是我自己认为本节课里比较重要.难理解或容易忘记的内容并做了些补充,并非是课堂详细笔记和要点: #标记为<补 ...