linux内核md源代码解读 八 阵列同步二:同步过程
发布时间:2016-01-18 12:31:33 所属栏目:Linux 来源:网络整理
导读:在上一小节里讲到启动同步线程: 7824 mddev-sync_thread = md_register_thread(md_do_sync, 7825 mddev, 7826 resync); md_register_thread函数如下: 6697 st
7411 blk_start_plug(&plug); 7412 while (j < max_sectors) { 7413 sector_t sectors; 7414 7415 skipped = 0; 7416 7417 if (!test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && 7418 ((mddev->curr_resync > mddev->curr_resync_completed && 7419 (mddev->curr_resync - mddev->curr_resync_completed) 7420 > (max_sectors >> 4)) || 7421 (j - mddev->curr_resync_completed)*2 7422 >= mddev->resync_max - mddev->curr_resync_completed 7423 )) { 7424 /* time to update curr_resync_completed */ 7425 wait_event(mddev->recovery_wait, 7426 atomic_read(&mddev->recovery_active) == 0); 7427 mddev->curr_resync_completed = j; 7428 set_bit(MD_CHANGE_CLEAN, &mddev->flags); 7429 sysfs_notify(&mddev->kobj, NULL, "sync_completed"); 7430 } 7431 7432 while (j >= mddev->resync_max && !kthread_should_stop()) { 7433 /* As this condition is controlled by user-space, 7434 * we can block indefinitely, so use '_interruptible' 7435 * to avoid triggering warnings. 7436 */ 7437 flush_signals(current); /* just in case */ 7438 wait_event_interruptible(mddev->recovery_wait, 7439 mddev->resync_max > j 7440 || kthread_should_stop()); 7441 } 7442 7443 if (kthread_should_stop()) 7444 goto interrupted; 7445 7446 sectors = mddev->pers->sync_request(mddev, j, &skipped, 7447 currspeed < speed_min(mddev)); 7448 if (sectors == 0) { 7449 set_bit(MD_RECOVERY_INTR, &mddev->recovery); 7450 goto out; 7451 } 7452 7453 if (!skipped) { /* actual IO requested */ 7454 io_sectors += sectors; 7455 atomic_add(sectors, &mddev->recovery_active); 7456 } 7457 7458 if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) 7459 break; 7460 7461 j += sectors; 7462 if (j>1) mddev->curr_resync = j; 7463 mddev->curr_mark_cnt = io_sectors; 7464 if (last_check == 0) 7465 /* this is the earliest that rebuild will be 7466 * visible in /proc/mdstat 7467 */ 7468 md_new_event(mddev); 7469 7470 if (last_check + window > io_sectors || j == max_sectors) 7471 continue; 7472 7473 last_check = io_sectors; 7474 repeat: 7475 if (time_after_eq(jiffies, mark[last_mark] + SYNC_MARK_STEP )) { 7476 /* step marks */ 7477 int next = (last_mark+1) % SYNC_MARKS; 7478 7479 mddev->resync_mark = mark[next]; 7480 mddev->resync_mark_cnt = mark_cnt[next]; 7481 mark[next] = jiffies; 7482 mark_cnt[next] = io_sectors - atomic_read(&mddev->recovery_active); 7483 last_mark = next; 7484 } 7485 7486 7487 if (kthread_should_stop()) 7488 goto interrupted; 7489 7490 7491 /* 7492 * this loop exits only if either when we are slower than 7493 * the 'hard' speed limit, or the system was IO-idle for 7494 * a jiffy. 7495 * the system might be non-idle CPU-wise, but we only care 7496 * about not overloading the IO subsystem. (things like an 7497 * e2fsck being done on the RAID array should execute fast) 7498 */ 7499 cond_resched(); 7500 7501 currspeed = ((unsigned long)(io_sectors-mddev->resync_mark_cnt))/2 7502 /((jiffies-mddev->resync_mark)/HZ +1) +1; 7503 7504 if (currspeed > speed_min(mddev)) { 7505 if ((currspeed > speed_max(mddev)) || 7506 !is_mddev_idle(mddev, 0)) { 7507 msleep(500); 7508 goto repeat; 7509 } 7510 } 7511 } 7512 printk(KERN_INFO "md: %s: %s done.n",mdname(mddev), desc); 查看本栏目更多精彩内容:http://www.bianceng.cn/OS/Linux/ (编辑:云计算网_泰州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |