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

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. jQuery加载一个html页面到指定的div里

    一.jQuery加载一个html页面到指定的div里 把a.html里面的某一部份的内容加载到b.html的一个div里.比如:加载a.html里面的<div id=“row"> ...

  2. yii2中自定义验证规则rules

    作者:白狼 出处:www.manks.top/article/yii2_custom_rules 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追 ...

  3. 【真的是随笔】如何利用htaccess把网站流量引到一个页面上(站点维护页效果)

    咕咕咕,好久没来博客园转悠了,最近(这个最近好长啊)一直没时间写博(事实上也不知道写点什么有逼格的东西),所以一直都在潜水,,,(此处省略n字) 好了切入正题,关于如何把网站的所有流量引向一个页面的方 ...

  4. MySQL 调优基础(三) Linux文件系统

    Linux的文件系统有点像MySQL的存储引擎,它支持各种各样的文件系统.它最上层是通过 virtual files system虚拟文件系统作为一个抽象接口层来对外提供调用的.然后下层的各种文件系统 ...

  5. 数据分页处理系列之二:HBase表数据分页处理

      HBase是Hadoop大数据生态技术圈中的一项关键技术,是一种用于分布式存储大数据的列式数据库,关于HBase更加详细的介绍和技术细节,朋友们可以在网络上进行搜寻,笔者本人在接下来的日子里也会写 ...

  6. oracle学习笔记系列------oracle 基本操作之表的增删改查

    --创建一个表 CREATE TABLE employee_souvc( id ), name ), gender ), birth DATE, salary ,), job ), deptno ) ...

  7. JavaScript动态显示当前时间

    JavaScript动态显示当前时间: 2016年01月04日  时间:16:58:32  星期一 <span id="timejs"></span> &l ...

  8. linux基础-第七单元 用户、群组及权限的深入讨论

    怎样查看文件的权限 ls命令详解 root用户及文件的安全控制 什么是root用户 用户分类 文件操作权限 文件操作权限的字符表示 chown chgrp 使用符号表示法设定文件或目录上的权限 chm ...

  9. andriod 动态设置TextView 和 RelativeLayou 高度

    XML布局 <RelativeLayout android:id="@+id/rlay_meeting_contact_context" android:layout_wid ...

  10. IIS7 配合 vs2013内置 LocalDB使用

    错误提示: 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误.未找到或无法访问服务器.请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接. (provide ...