linux内核奇遇记之md源代码解读之八阵列同步二
7824 mddev->sync_thread = md_register_thread(md_do_sync,
7825 mddev,
7826 "resync");
md_register_thread函数如下:
6697 struct md_thread *md_register_thread(void (*run) (struct mddev *), struct mddev *mddev,
6698 const char *name)
6699 {
6700 struct md_thread *thread;
6701
6702 thread = kzalloc(sizeof(struct md_thread), GFP_KERNEL);
6703 if (!thread)
6704 return NULL;
6705
6706 init_waitqueue_head(&thread->wqueue);
6707
6708 thread->run = run;
6709 thread->mddev = mddev;
6710 thread->timeout = MAX_SCHEDULE_TIMEOUT;
6711 thread->tsk = kthread_run(md_thread, thread,
6712 "%s_%s",
6713 mdname(thread->mddev),
6714 name);
6715 if (IS_ERR(thread->tsk)) {
6716 kfree(thread);
6717 return NULL;
6718 }
6719 return thread;
6720 }
7245 #define SYNC_MARKS 10
7246 #define SYNC_MARK_STEP (3*HZ)
7247 void md_do_sync(struct mddev *mddev)
7248 {
7249 struct mddev *mddev2;
7250 unsigned int currspeed = 0,
7251 window;
7252 sector_t max_sectors,j, io_sectors;
7253 unsigned long mark[SYNC_MARKS];
7254 sector_t mark_cnt[SYNC_MARKS];
7255 int last_mark,m;
7256 struct list_head *tmp;
7257 sector_t last_check;
7258 int skipped = 0;
7259 struct md_rdev *rdev;
7260 char *desc;
7261 struct blk_plug plug;
7262
7263 /* just incase thread restarts... */
7264 if (test_bit(MD_RECOVERY_DONE, &mddev->recovery))
7265 return;
7266 if (mddev->ro) /* never try to sync a read-only array */
7267 return;
7268
7269 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
7270 if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
7271 desc = "data-check";
7272 else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
7273 desc = "requested-resync";
7274 else
7275 desc = "resync";
7276 } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
7277 desc = "reshape";
7278 else
7279 desc = "recovery";
7346 j = 0;
7347 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
7348 /* resync follows the size requested by the personality,
7349 * which defaults to physical size, but can be virtual size
7350 */
7351 max_sectors = mddev->resync_max_sectors;
7352 mddev->resync_mismatches = 0;
7353 /* we don't use the checkpoint if there's a bitmap */
7354 if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
7355 j = mddev->resync_min;
7356 else if (!mddev->bitmap)
7357 j = mddev->recovery_cp;
7358
7359 } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
7360 max_sectors = mddev->resync_max_sectors;
7361 else {
7362 /* recovery follows the physical size of devices */
7363 max_sectors = mddev->dev_sectors;
7364 j = MaxSector;
7365 rcu_read_lock();
7366 rdev_for_each_rcu(rdev, mddev)
7367 if (rdev->raid_disk >= 0 &&
7368 !test_bit(Faulty, &rdev->flags) &&
7369 !test_bit(In_sync, &rdev->flags) &&
7370 rdev->recovery_offset < j)
7371 j = rdev->recovery_offset;
7372 rcu_read_unlock();
7373 }
7374
7375 printk(KERN_INFO "md: %s of RAID array %s\n", desc, mdname(mddev));
7376 printk(KERN_INFO "md: minimum _guaranteed_ speed:"
7377 " %d KB/sec/disk.\n", speed_min(mddev));
7378 printk(KERN_INFO "md: using maximum available idle IO bandwidth "
7379 "(but not more than %d KB/sec) for %s.\n",
7380 speed_max(mddev), desc);
7381
7382 is_mddev_idle(mddev, 1); /* this initializes IO event counters */
7351行,所以对于不同阵列,max_sectors代表不同的含义。
7384 io_sectors = 0;
7385 for (m = 0; m < SYNC_MARKS; m++) {
7386 mark[m] = jiffies;
7387 mark_cnt[m] = io_sectors;
7388 }
7389 last_mark = 0;
7390 mddev->resync_mark = mark[last_mark];
7391 mddev->resync_mark_cnt = mark_cnt[last_mark];
7392
7393 /*
7394 * Tune reconstruction:
7395 */
7396 window = 32*(PAGE_SIZE/512);
7397 printk(KERN_INFO "md: using %dk window, over a total of %lluk.\n",
7398 window/2, (unsigned long long)max_sectors/2);
7399
7400 atomic_set(&mddev->recovery_active, 0);
7401 last_check = 0;
7402
7403 if (j>2) {
7404 printk(KERN_INFO
7405 "md: resuming %s of %s from checkpoint.\n",
7406 desc, mdname(mddev));
7407 mddev->curr_resync = j;
7408 }
7409 mddev->curr_resync_completed = j;
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);
7518 wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active));
7519
7520 /* tell personality that we are finished */
7521 mddev->pers->sync_request(mddev, max_sectors, &skipped, 1);
7522
7523 if (!test_bit(MD_RECOVERY_CHECK, &mddev->recovery) &&
7524 mddev->curr_resync > 2) {
7525 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
7526 if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
7527 if (mddev->curr_resync >= mddev->recovery_cp) {
7528 printk(KERN_INFO
7529 "md: checkpointing %s of %s.\n",
7530 desc, mdname(mddev));
7531 mddev->recovery_cp =
7532 mddev->curr_resync_completed;
7533 }
7534 } else
7535 mddev->recovery_cp = MaxSector;
7536 } else {
7537 if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery))
7538 mddev->curr_resync = MaxSector;
7539 rcu_read_lock();
7540 rdev_for_each_rcu(rdev, mddev)
7541 if (rdev->raid_disk >= 0 &&
7542 mddev->delta_disks >= 0 &&
7543 !test_bit(Faulty, &rdev->flags) &&
7544 !test_bit(In_sync, &rdev->flags) &&
7545 rdev->recovery_offset < mddev->curr_resync)
7546 rdev->recovery_offset = mddev->curr_resync;
7547 rcu_read_unlock();
7548 }
7549 }
7550 skip:
7551 set_bit(MD_CHANGE_DEVS, &mddev->flags);
7552
7553 if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
7554 /* We completed so min/max setting can be forgotten if used. */
7555 if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
7556 mddev->resync_min = 0;
7557 mddev->resync_max = MaxSector;
7558 } else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
7559 mddev->resync_min = mddev->curr_resync_completed;
7560 mddev->curr_resync = 0;
7561 wake_up(&resync_wait);
7562 set_bit(MD_RECOVERY_DONE, &mddev->recovery);
7563 md_wakeup_thread(mddev->thread);
7564 return;
linux内核奇遇记之md源代码解读之八阵列同步二相关推荐
- linux内核奇遇记之md源代码解读之十二raid读写
linux内核奇遇记之md源代码解读之十二raid读写 转载请注明出处:http://blog.csdn.net/liumangxiong 我们都知道,对一个linux块设备来说,都有一个对应的请求队 ...
- 复制linux内核,linux内核写时复制机制源代码解读
作者简介 写时复制技术(一下简称COW)是linux内核比较重要的一种机制,我们都知道:父进程fork子进程的时候,子进程会和父进程会以只读的方式共享所有私有的可写页,当有一方将要写的时候会发生COW ...
- 高通linux内核目录,高通 android 源代码以及目标系统目录结构
下面为高通android源代码结构 build/ – Build 环境建立和makefiles生成4 bionic/ – Android C 库 dalvik/ – Android Java 虚拟机 ...
- linux 内核网络协议栈--数据从接收到IP层(二)
此处主要讲的是从数据来到,中断到最终数据包被处理的过程. 首先来介绍一下IO端口访问问题,内核提供了这样一组函数处理: /kernel/io.c中 inb( ).inw( ).inl( )函数 分别从 ...
- linux内核网络协议栈--数据包的网卡转发流程(二十七)
原文链接:https://blog.csdn.net/jackywgw/article/details/78321226
- Linux内核调试方法总结
[转]Linux内核调试方法总结 目录[-] 一 调试前的准备 二 内核中的bug 三 内核调试配置选项 1 内核配置 2 调试原子操作 四 引发bug并打印信息 1 BUG()和BUG ...
- xilinx linux内核,Xilinx-Zynq Linux内核源码编译过程
本文内容依据http://www.wiki.xilinx.com网址编写,编译所用操作系统为ubuntu 14 1.交叉编译环境的安装配置 2.uboot的编译 1)下载uboot源代码 下载uboo ...
- Linux内核调试方法【转】
转自:http://www.cnblogs.com/shineshqw/articles/2359114.html kdb:只能在汇编代码级进行调试: 优点是不需要两台机器进行调试. gdb:在调试模 ...
- Linux内核移植之一:内核源码结构与Makefile分析
内容来自 韦东山<嵌入式Linux应用开发完全手册> 一.内核介绍 1.版本及其特点 Linux内核的版本号可以从源代码的顶层目录下的Makefile中看到,比如下面几行它们构成了Linu ...
最新文章
- 1 张图,拆解阿里 P8高级架构师必会技术栈!
- Python标准模块—Regular Expressions
- KVM虚拟机文件优化导出最小化体积的qcow2镜像文件
- redis学习(一)
- 并查集【CF731C】Socks
- redis安装190923课堂版
- VB案例:泸职院教师评学评价表计算程序
- TreeSet(不可重复,自动排序)实现自定义排序
- 被占满_关晓彤在家做饭暴露豪宅内景,冰箱占满一整面墙,酒柜比人还要高
- 关于beginPath()和closePath()的关系canvas的beginPath和closePath分析总结,包括多段弧的情况...
- 源码安装mysql初始化报错_源码安装MySQL5.6.39后,修改配置文件启动报错
- android 开发者模式进入
- 2021春招美团算法笔试题
- sentinel实现限流、降级、熔断配置和测试使用
- JVM进阶(六)——鲜为人知的二次标记
- ceph存储 pg归置组处于stuck以及degraded状态解决方案
- 语音芯片排行榜,为何唯创知音WT588F语音芯片如此受欢迎
- 主窗口给按钮控件发送消息 BN_CLICKED和BN_SETFOCUS和BN_KILLFOUCS
- Android手机连接笔记本电脑上网 linux环境
- 字体转换网站——Font Squirrel(推荐阅读)
热门文章
- Debian10搭建邮件服务器
- 腾讯云服务器+宝塔面板+wordpress搭建网站教程
- linux perf arm,linux kernel perf event(counter)
- (四)OpenCV | 斑点检测
- 【ybtoj】国王游戏
- .pages怎么在windows上打开?Windows下打开在Mac中编辑的.pages文件方法
- 6-1 字符串 - 8. 输入字符串分数 10
- 安全学院“传承文化”暑期实践团抵达西安
- UI组件-ViewAnimator及其子类
- java报错意外的类型_Java意外类型错误