一、前言
在linux2.6.32之前,linux下数据同步是基于pdflush线程机制来实现的,在linux2.6.32以上的版本,内核彻底删掉了pdflush机制,改为了基于per-bdi线程来实现数据同步,与pdflush线程相比,在per-bdi线程机制中,每个后备存储器拥有自己唯一的回写线程,数据同步时需要更少的线程、也不会有多个pdflush对同一个后备存储器进行回写的竞态问题,回写的效率更高。

二、初始化默认的后备存储器default_backing_dev_info

static int __init default_bdi_init(void)
{
int err; /*创建同步每个后备存储器的超级块的线程*/
sync_supers_tsk = kthread_run(bdi_sync_supers, NULL, "sync_supers");
BUG_ON(IS_ERR(sync_supers_tsk)); /*初始化一个定时器,该定时器控制同步超级块的周期,每隔dirty_writeback_interval去唤醒一次sync_supers_tsk,从而同步超级块。
dirty_writeback_interval可以通过修改/proc/sys/vm/下的dirty_writeback_centisecs来修改,默认值是500,单位是10ms
定时器函数sync_supers_timer_fn用于唤醒同步超级块的线程sync_supers_tsk,并且更新定时器的到期时间,具体实现如下*/
setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0);
/*用于更新定时器的到期时间,详见下面代码。*/
bdi_arm_supers_timer(); /*初始化default_backing_dev_info的成员变量,初始化相关的链表,相关的变量赋初值等操作,请读者自行阅读。*/
err = bdi_init(&default_backing_dev_info);
if (!err)
/*调用bdi_register注册默认的后备存储器default_backing_dev_info到bdi_list链表,并创建默认的backing_dev_info管理线程,
用于管理其他的后备存储器的数据同步线程的创建和销毁,所有的后备存储器在初始化时都会调用bdi_register注册到bdi_list链表中。
bdi_register详见下文分析。*/
bdi_register(&default_backing_dev_info, NULL, "default"); /*初始化空的后备存储器,可以忽略。*/
err = bdi_init(&noop_backing_dev_info); return err;
}
void bdi_arm_supers_timer(void)
{
unsigned long next; if (!dirty_writeback_interval)
return; next = msecs_to_jiffies(dirty_writeback_interval * 10) + jiffies;
mod_timer(&sync_supers_timer, round_jiffies_up(next));
}
static void sync_supers_timer_fn(unsigned long unused)
{
wake_up_process(sync_supers_tsk);
bdi_arm_supers_timer();
}

bdi_arm_supers_timer函数重设定时器

void bdi_arm_supers_timer(void)
{
unsigned long next; if (!dirty_writeback_interval)
return; next = msecs_to_jiffies(dirty_writeback_interval * 10) + jiffies;
mod_timer(&sync_supers_timer, round_jiffies_up(next));
}

三、bdi_register()函数分析
bdi_register函数用于注册后备存储器到全局链表bdi_list上,并且判断如果是默认的后备存储器default_backing_dev_info则创建bdi-default线程,用于管理创建或销毁所有后备存储器相关的同步回写线程。

int bdi_register(struct backing_dev_info *bdi, struct device *parent,
const char *fmt, ...)
{
va_list args;
struct device *dev; if (bdi->dev) /* The driver needs to use separate queues per device */
return 0; va_start(args, fmt);
dev = device_create_vargs(bdi_class, parent, MKDEV(0, 0), bdi, fmt, args);
va_end(args);
if (IS_ERR(dev))
return PTR_ERR(dev); bdi->dev = dev; /*
* Just start the forker thread for our default backing_dev_info,
* and add other bdi's to the list. They will get a thread created
* on-demand when they need it.
*/
if (bdi_cap_flush_forker(bdi)) {
struct bdi_writeback *wb = &bdi->wb; wb->task = kthread_run(bdi_forker_thread, wb, "bdi-%s",
dev_name(dev));
if (IS_ERR(wb->task))
return PTR_ERR(wb->task);
} bdi_debug_register(bdi, dev_name(dev));
set_bit(BDI_registered, &bdi->state); spin_lock_bh(&bdi_lock);
list_add_tail_rcu(&bdi->bdi_list, &bdi_list);
spin_unlock_bh(&bdi_lock); trace_writeback_bdi_register(bdi);
return 0;
}

from:http://sunjiangang.blog.chinaunix.net/uid-9543173-id-3568434.html

linux下数据同步、回写机制分析的更多相关文章

  1. Linux页快速缓存与回写机制分析

    參考 <Linux内核设计与实现> ******************************************* 页快速缓存是linux内核实现的一种主要磁盘缓存,它主要用来降低 ...

  2. Linux 3.2中回写机制的变革

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://alanwu.blog.51cto.com/3652632/1109952 wri ...

  3. linux下的KSM内存共享机制分析

    2017-04-26 KSM是内核中的一种内存共享机制,在2.6.36版本的内核中开始引入,简单来说就是其会 合并某些相同的页面以减少页面冗余.在内核中有一个KSM守护进程 ksmd,它定期扫描用户向 ...

  4. linux块设备的IO调度算法和回写机制

    ************************************************************************************** 參考: <Linux ...

  5. 【转帖】Linux上搭建Samba,实现windows与Linux文件数据同步

    Linux上搭建Samba,实现windows与Linux文件数据同步 2018年06月09日 :: m_nanle_xiaobudiu 阅读数 15812更多 分类专栏: Linux Samba 版 ...

  6. 大并发连接的oracle在Linux下内存不足的问题的分析

    大并发连接的oracle在Linux下内存不足的问题的分析 2010-01-28 20:06:21 分类: Oracle 最近一台装有Rhel5.3的40G内存的机器上有一个oracle数据库,数据库 ...

  7. Linux下USB suspend/resume源码分析【转】

    转自:http://blog.csdn.net/aaronychen/article/details/3928479 Linux下USB suspend/resume源码分析 Author:aaron ...

  8. linux下的同步与互斥

    linux下的同步与互斥 谈到linux的并发,必然涉及到线程之间的同步和互斥,linux主要为我们提供了几种实现线程间同步互斥的 机制,本文主要介绍互斥锁,条件变量和信号量.互斥锁和条件变量包含在p ...

  9. linux下利用elk+redis 搭建日志分析平台教程

    linux下利用elk+redis 搭建日志分析平台教程 http://www.alliedjeep.com/18084.htm   elk 日志分析+redis数据库可以创建一个不错的日志分析平台了 ...

随机推荐

  1. poj1094-Sorting It All Out-拓扑排序

    题意: 1).给你一些大写字母,共n个:大写字母间有m条关系: 2).举例:关系:A<B,意思就是A要排在B的前面(也就是说可能B排在A的前面 3).输出:有三种情况: 1.n个字母在前 i 条 ...

  2. jms - activeMQ入门案例

    activeMQ入门案例 叨叨一波,很久没写博客了,最近比较慢,时间抽不出来,这个借口说的很尴尬...我知道作为一名合格的码农就必须养成每天一博客的习惯.希望友友们别像我这样懒,闲话不多时进入今天的主 ...

  3. [LeetCode] Max Chunks To Make Sorted 可排序的最大块数

    Given an array arr that is a permutation of [0, 1, ..., arr.length - 1], we split the array into som ...

  4. [LeetCode] Sliding Window Median 滑动窗口中位数

    Median is the middle value in an ordered integer list. If the size of the list is even, there is no ...

  5. codeforces Gym - 100633J Ceizenpok’s formula

    拓展Lucas #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring ...

  6. ●杜教筛入门(BZOJ 3944 Sum)

    入门杜教筛啦. http://blog.csdn.net/skywalkert/article/details/50500009(好文!) 可以在$O(N^{\frac{2}{3}})或O(N^{\f ...

  7. hihocoder 1391 树状数组

    #1391 : Countries 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 There are two antagonistic countries, countr ...

  8. Codeforces 671 D. Roads in Yusland

    题目描述 Mayor of Yusland just won the lottery and decided to spent money on something good for town. Fo ...

  9. 【LA 3027 Corporative Network】

    ·一些很可爱的询问和修改,放松地去用并查集解决. ·英文题,述大意: 输入n(5<=n<=20000)表示树有n个节点,并且会EOF结束地读入不超过 20000个操作,一共有两种:    ...

  10. hdu 5592 BestCoder Round #65(树状数组)

    题意: ZYB有一个排列PP,但他只记得PP中每个前缀区间的逆序对数,现在他要求你还原这个排列. (i,j)(i < j)(i,j)(i<j)被称为一对逆序对当且仅当A_i>A_jA ...