加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_镇江站长网 (https://www.0511zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

linux内核md源代码解读 十 raid5数据流之同步数据流程 - Linux系统

发布时间:2014-03-24 10:23:21 所属栏目:Linux 来源:站长网
导读:上一节讲到在raid5的同步函数sync_request中炸土豆片是通过handle_stripe来进行的。从最初的创建阵列,到申请各种资源,建立每个阵列的personality,所有的一切
上一节讲到在raid5的同步函数sync_request中炸土豆片是通过handle_stripe来进行的。从最初的创建阵列,到申请各种资源,建立每个阵列的personality,所有的一切都是为了迎接数据流而作的准备。就像我们寒窗苦读就是为了上大学一样。数据流的过程就像大学校园一样丰富多彩并且富有挑战性,但只要跨过了这道坎,内核代码将不再神秘,剩下的问题只是时间而已。

首先看handle_stripe究竟把我们的土豆片带往何处:

3379 static void handle_stripe(struct stripe_head *sh)  
3380 {  
3381         struct stripe_head_state s;  
3382         struct r5conf *conf = sh->raid_conf;  
3383         int i;  
3384         int prexor;  
3385         int disks = sh->disks;  
3386         struct r5dev *pdev, *qdev;  
3387  
3388         clear_bit(STRIPE_HANDLE, &sh->state);  
3389         if (test_and_set_bit_lock(STRIPE_ACTIVE, &sh->state)) {  
3390                 /* already being handled, ensure it gets handled 
3391                  * again when current action finishes */
3392                 set_bit(STRIPE_HANDLE, &sh->state);  
3393                 return;  
3394         }  
3395  
3396         if (test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) {  
3397                 set_bit(STRIPE_SYNCING, &sh->state);  
3398                 clear_bit(STRIPE_INSYNC, &sh->state);  
3399         }  
3400         clear_bit(STRIPE_DELAYED, &sh->state);  
3401  
3402         pr_debug("handling stripe %llu, state=%#lx cnt=%d, "
3403                 "pd_idx=%d, qd_idx=%dn, check:%d, reconstruct:%dn",  
3404                (unsigned long long)sh->sector, sh->state,  
3405                atomic_read(&sh->count), sh->pd_idx, sh->qd_idx,  
3406                sh->check_state, sh->reconstruct_state);  
3407  
3408         analyse_stripe(sh, &s);

这个函数代码比较长先贴第一部分,分析条带。分析的作用就是根据条带的状态做一些预处理,根据这些状态再来判断下一步应该做什么具体操作。比如说同步,那么首先会读数据盘,等读回来之后,再校验,然后再写校验值。但是这些步骤又不是一次性在handle_stripe里就完成的,因为跟磁盘IO都是异步的,所以必要要等上一次磁盘请求回调之后再次调用handle_stripe,通常每个数据流都会多次进入handle_stripe,而每一次进入经过的代码流程是不大一样的。

struct stripe_head有很多状态,这些状态决定条带应该怎么处理,所以必须非常小心处理这些标志,这些标志很多,现在先简单地过一下。

enum {  
     STRIPE_ACTIVE,   // 正在处理  
     STRIPE_HANDLE,  // 需要处理  
     STRIPE_SYNC_REQUESTED,  // 同步请求   
     STRIPE_SYNCING,  // 正在处理同步  
     STRIPE_INSYNC,  // 条带已同步  
     STRIPE_PREREAD_ACTIVE,  // 预读  
     STRIPE_DELAYED,  // 延迟处理  
     STRIPE_DEGRADED,  // 降级  
     STRIPE_BIT_DELAY,  // 等待bitmap处理  
     STRIPE_EXPANDING,  //   
     STRIPE_EXPAND_SOURCE,  //   
     STRIPE_EXPAND_READY,  //   
     STRIPE_IO_STARTED,     /* do not count towards 'bypass_count' */   // IO已下发  
     STRIPE_FULL_WRITE,     /* all blocks are set to be overwritten */  // 满写  
     STRIPE_BIOFILL_RUN,  // bio填充,就是将page页拷贝到bio  
     STRIPE_COMPUTE_RUN,  // 运行计算  
     STRIPE_OPS_REQ_PENDING,  // handle_stripe排队用  
     STRIPE_ON_UNPLUG_LIST,  // 批量release_stripe时标识是否加入unplug链表  
};

3388行,清除需要处理标志。

3389行,设置正在处理标志。

3392行,如果已经在处理则设置下次处理标志并返回。

3396行,如果是同步请求。

3397行,设置正在处理同步标志。

3398行,清除已同步标志。

3400行,清除延迟处理标志。

3408行,分析stripe,这个函数很长分几段来说明:

(编辑:应用网_镇江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!