linux内核md源代码解读 十 raid5数据流之同步数据流程 - Linux系统
上一节讲到在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,这个函数很长分几段来说明:
(编辑:应用网_镇江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |