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,这个函数很长分几段来说明:
(编辑:应用网_镇江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

