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

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. 运算符&,|,^

    1.&按位“与”的计算是把两个数字分别写成二进制形式,然后按照每一位进行比较,&计算中,只要有一个是0就算成02.|运算转换成2进制进行比较,两个位只要有一个为1,那么结果就是1,否则 ...

  2. HTTP协议基本知识

    Xcode7.0以上版本必须操作:https http 在Info.plist中添加NSAppTransportSecurity类型Dictionary. 在NSAppTransportSecurit ...

  3. C#复习⑧

    C#复习⑧ 2016年6月22日 13:50 Main Attribute & Threads 属性与线程 1.Conditional Attribute 条件属性 #define debug ...

  4. spring的定时任务配置

    本文来源于:http://myspace1916.iteye.com/blog/1570707 也可参考:http://www.oschina.net/question/8676_9032 (个人只是 ...

  5. Python标准库(1) — itertools模块

    简介 官方描述:Functional tools for creating and using iterators.即用于创建高效迭代器的函数. itertools.chain(*iterable) ...

  6. SQL Server调优系列基础篇(子查询运算总结)

    前言 前面我们的几篇文章介绍了一系列关于运算符的介绍,以及各个运算符的优化方式和技巧.其中涵盖:查看执行计划的方式.几种数据集常用的连接方式.联合运算符方式.并行运算符等一系列的我们常见的运算符.有兴 ...

  7. 烂泥:学习ubuntu远程桌面(二):远程桌面会话管理

    本文由秀依林枫提供友情赞助,首发于烂泥行天下 在上一篇文章中,我们讲解了如何给ubuntu安装远程桌面及其配置,这篇文章我们再来讲解下有关ubuntu远程桌面会话的问题. 一.问题描述 在我们使用ub ...

  8. iNeedle系统之国舜项目

    一.简介 本周公司接了一个小项目,是给北京国舜科技股份有限公司做一个HTTP相关的小功能产品.大概实现功能是将交换机的源数据通过解析,分析出HTTP包配对的request和response头,并把每对 ...

  9. python可分组字典

    # -*- encoding: UTF-8 -*- from collections import defaultdict class News(object): def __init__(self, ...

  10. Arch Linux sudo: PAM authentication error: Module is unknown [Solved!]

    问题描述: 我的 Arch Linux 已经用了快半年多,由于 Arch Linux 的滚挂问题,我从没有直接升级过系统.软件版本以及库自然落后了一些. 就在我准备需要用到 NFS 时,挂载网络文件系 ...