Linux内核2.6.32中的Raid5.h一上来就是150多行的注释!看起来好辛苦,简单翻译一份留在这里,翻译不对的地方希望大家指出~

每个条纹都包含一个buffer,每个buffer和每个磁盘对应。每个buffer都包括一些列的状态,存储在flags字段中。这些状态之间的切换“几乎”都是异步的,并且在一个“每条纹”的自旋锁中进行。一些非常特殊的标志位改变可以在bi_end_io中进行,这些改变不会由自旋锁保护。

两个标志位R5_UPTODATE和R5_LOCKED指出四种不同的状态:
State Empty == !UPTODATE, !LOCK
       内存(buffer)中没有数据,而且也没有活跃的请求
State Want == !UPTODATE, LOCK
       这个块上提交有读请求
State Dirty == UPTODATE, LOCK
       内存中有数据,正在被写入磁盘
State Clean == UPTODATE, !LOCK
       内存中有数据,并且和磁盘上的数据是同步的
状态转换可能:
 *  Empty -> Want   - 读或者写(写操作需要读旧数据用于更新校验)
 *  Empty -> Dirty  - 计算校验数据(sync或者重构写)
 *  Empty -> Clean  - 一个失效的设备上恢复出来的数据
 *  Want  -> Empty  - 读失败
 *  Want  -> Clean  - 读请求成功完成
 *  Dirty -> Clean  - 写请求成功完成
 *  Dirty -> Clean  - 写失败
 *  Clean -> Dirty  - 计算校验数据(sync或者重构、读改写)

Want->Empty, Want->Clean, Dirty->Clean的过程都发生在b_end_io的中断中。每次都要在释放锁标记位之前设置Uptodate位。
只剩下一种多状态转换可能:Want->Dirty->Clean。这种转换是安全的,因为,试想一个标记为Clean的buffer如果实际上是dirty的,最坏情况便是推迟了一些动作,条纹会在转换完成的时候注意到并且被重新调度。

上述状态并未包括一种可能性,即如果一个设备失效,同时有一个spare的设备正在重构。我们无法区分一个由计算校验而产生的clean的块还是一个成功写入spare设备的块(或者是resync进行中的校验)。为了区分这两种情况,条纹中的STRIPE_INSYNC为用以指明。当一个写操作是面向spare设备,或者没有spare设备的时候面向校验盘,该位将被置位。一个sync请求将复位该位,当我们发现(置位并且)没有任何buffer锁住的时候,就知道sync完成了。

md设备的buffer通过make_request是依附在合适的条纹中,这些条纹在两个b_reqnext链表之一。bh_read是读请求链表,bh_write是写请求链表。一个buffer应该是不可能同时存在于两个链表中,但是我们无法保证这一点,因此需要做更多的许可。

如果一个buffer对应的cache buffer标记为Uptodate的并且在读链表中,数据将拷贝到读缓冲区,并且调用自己的b_end_io例程。这种情况仅仅发生在buffer刚刚成功读取时候的end_request例程中。end_request需要将buffer从列表中移除,然后设置buffer的Uptodate位。其他线程仅仅在他们第一次检测Uptodate被设置的时候这么做,一旦检测完成,就将buffer从读队列中移除。

当一个写链表中的buffer进行写提交时候,将被拷贝到cache buffer中,这时将标记为dirty,并且移至第三个列表,written列表(bh_written)。一旦校验快和cache buffer都被成功写入磁盘,written列表中的buffer们将随b_end_io返回。

写列表和读列表都以fifo的方式工作。读列表由device_lock保护。write和written列表由条纹锁保护。device_lock将在条纹块持有的时候声明,仅仅用于人工修改列表,并且持有很短的时间。可以从中断中声明。

stripe cache中的条纹可以在两个列表中的一个里(也可以一个都不在)。“非活动列表”包括了当前没有被任何请求使用的列表,可以自由的由其他条纹使用。“处理列表”包括了需要按某种方法处理的条纹。这些列表都是fifo的队列。每个条纹也都(可能的)连接到一个哈希桶中,因此可以由扇区号索引到。条纹没有被哈希的,一定是在非活动列表中,并且一般都是在前头。所有的条纹都是以这种方式开始自己的生存期。

非活动列表、处理列表和哈希桶列表都由device_lock保护
---非活动列表中的条纹永远不会获得其条纹锁
---条纹都有引用计数,如果count==0,则必定在某个列表中
---如果一个条纹必须需要处理,STRIPE_HANDLE置位
---当引用计数到达0,如果STRIPE_HANDLE没有置位,该条纹放在非活动列表中,否则放在处理列表中

结合STRIPE_HANDLE仅仅当条纹具有一个非0的引用计数的情况下才能被复位,这意味着如果引用计数到达0并且STRIPE_HANDLE被置位,该条纹一定在处理列表中,如果STRIPE_HANDLE复位,该条纹一定在非活动列表中。

可能的转换包括:
---没有哈希/非活跃条纹---->激活(get_active_stripe())
   ++设备上锁--检验哈希--unlink条纹--cnt++--clean条纹--哈希条纹--设备解锁
---哈希(很可能是活跃)的条纹--->激活(get_active_stripe())
   ++设备上锁--检验哈希--if(!cnt++)unlink条纹--设备解锁
---将一个请求加到一个活跃条纹头上(add_stripe_bh())
   ++设备上锁--附加buffer--设备解锁
---处理一个条纹(handle_stripe())
   ++条文上锁--清STRIPE_HANDLE位--(设备上锁--检测buffers--设备解锁--)--改变状态--记录需要的io/ops--条纹解锁--调度io/ops
---释放一个活跃的条纹(release_stripe())
   ++设备上锁--if(!--cnt){根据STRIPE_HANDLE将条纹放回处理列表或者非活跃列表}--设备解锁

引用计数记录了激活了这个条纹的线程数+正在处理这个条纹的raid5d+cache buffer上的活跃请求数目,如果条纹正在进行条纹操作,那么再加1.

对条纹的操作在条纹锁的外面进行,主要包括:
---在stripe cache和用户应用缓冲之间拷贝数据
---为了减少一次磁盘访问进行的块(重构)计算,或者恢复一个丢失的块
---写操作中的更新校验
---检测校验是否正确
---运行到磁盘的I/O操作
这些操作都由raid5_run_ops进行,这个函数使用了async_tx相关api,使用专用的硬件以(可选的)减少操作负载。当请求一个操作时候,handle_stripe设置操作的pending位并且计数加一。每当计数为非0的时候,raid5_run_ops运行。
为了避免一些操作被请求而另一些操作正在进行的情况,操作之间要服从一些严格的依赖:
(1)因为校验检查操作破坏了校验块的缓存中版本,所以必须防止检查进程进行中的依赖校验的操作,比如写操作和计算块(即恢复块)操作。一些dma机器可以在不破坏校验块的前提下进行检查操作,这时校验块将被重新标记为实时(假设检查操作成功)并且不从磁盘中重新读取。
(2)当一个写请求到来时,要立即锁住相关的块,标记这些块为过期。这造成了新的读请求被拦截,并且带来了校验检查和块的计算操作。
(3)一旦有块计算请求,handle_stripe将这些块视作已经实时有效。raid5_run_ops保证任何独立于块计算结果的操作都在块计算完成之后被初始化。

操作状态 - sh->lock之外能看到的内部状态
一般的,_idle表示什么都没有进行中,_run表示一个数据操作正在进行,_result表示数据操作的结果是稳定的(即运算完了),并且可以受到(别的操作影响)。对于像biofill这样的简单操作和只有一个_idle和_run状态的计算,都用sh->state标志位表示(STRIPE_BIOFILL_RUN和STRIPE_COMPUTE_RUN)。

转载于:https://blog.51cto.com/luckybins/666430

Raid5.h注释翻译相关推荐

  1. HashMap源码注释翻译

    HashMap注释翻译 package java.util;import java.io.IOException; import java.io.InvalidObjectException; imp ...

  2. 通过例子学Solidity[注释翻译]

    [官方译文(2)] 通过例子学Solidity[注释翻译] 前 继续翻译Solidity的官方文档, 以此也算是自己的学习[Solidity官方手册](https://solidity.readthe ...

  3. 官方完整HL7 ECG-XML例子及注释翻译(1)

    编者:李国帅 qq:9611153 微信lgs9611153 时间:2019-7-4 背景: 存储心电图数据的格式有很多种,比如HL7,Dicom,EDF,GDF等,其中HL7最是简单,直观,使用Xm ...

  4. IntelliJ IDEA生产力工具 -- 源码注释翻译神器

    IntelliJ IDEA生产力工具 – 源码注释翻译神器 本次给大家分享的IntelliJ IDEA提效插件是Translation. 用IDEA看源码时,难免会遇到有不认知的英文单词或翻译不通的句 ...

  5. IDEA Translation(翻译插件)使用(注释翻译,单词翻译)

    1 安装Translation File->Settings->Plugins->Marketplace->输入Translation->Install. 2 注释翻译 ...

  6. x265-1.8版本-common/wavefront.h注释

    注:问号以及未注释部分 会在x265-1.9版本内更新 /*********************************************************************** ...

  7. x265-1.8版本-common/contexts.h注释

    注:问号以及未注释部分 会在x265-1.9版本内更新 /*********************************************************************** ...

  8. x265-1.8版本-common/cudata.h注释

    注:问号以及未注释部分 会在x265-1.9版本内更新 /*********************************************************************** ...

  9. x265-1.7版本-common/cudata.h注释

    注:问号以及未注释部分 会在x265-1.8版本内更新  /********************************************************************** ...

最新文章

  1. 01_字符串处理-----04_在文本中应用ZIpf定律
  2. 汇编语言--数据传送指令
  3. 使用openocd调试Linux内核,openocd安装与调试
  4. Python第三方库的安装及路径查看总结
  5. 编码方法论,赋能你我他
  6. MySQL基础2——表的约束
  7. 使用 FOR XML语句 将查询结构作为XML格式返回【转】
  8. 一个注册页面的前端模板(html+css+javascript)可自适应屏幕
  9. 自走棋投降代码_自走棋太火惨遭针对!代码哥之后又是锁钱挂?玩家:还有拒绝员!...
  10. Vue之webpack之vue
  11. wangeditor react中使用
  12. Java Restful风格-Jersey RESTful 框架入门
  13. 易语言PHP自动更新,易语言自动更新源码
  14. 视频监控流媒体服务器工作原理,流媒体服务器传输基本原理
  15. fastlane php,fastlane自动化打包ipa并发布到firim或者蒲公英
  16. Windows 文件夹 显示svg缩略图
  17. We‘re sorry but XXX doesn‘t work properly without JavaScript enabled. Please enable it to contin
  18. ArcMap学习笔记(三)地图数字化
  19. LC6936-TWS耳机方案
  20. EXFO 光时反射仪MAX-730C-SM1基本规格

热门文章

  1. Net Present Value - NPV
  2. JMS的两种消息模型(Point-to-Point(P2P)和Publish/Subscribe(Pub/Sub))应用举例
  3. 【题解】lugu P4095 Eden的新背包问题
  4. DCGAN in Tensorflow生成动漫人物
  5. JavaScript高级程序设计之基本概念篇
  6. Java基础知识强化之IO流笔记13:递归之不死神兔问题(斐波那契数列)
  7. JAVA 两个简单的抽奖算法
  8. Spring学习(九)Spring 和数据库编程【了解】
  9. 超详细SQLMap使用攻略及技巧分享
  10. jvm内置锁synchronized不能被中断