在Linux内核里内存可以和硬盘空间通用的,当内存利用很少时,数据可以存到内存里,反之硬盘空间可以用来当内存用但是有个共同点数据总是现在内存里操作再写回到硬盘上的。由于这个原因,块存储设备被当成后备存储器。
Linux提供了两种操作的方法:
1 后台进程不停的检查系统内存周期性的写操作
2 当系统有太多的脏页需要清理时进程被激活
内存和cache以及后备存储器之间的同步被分成两种
1 可以控制数据交换时的优先级策列,我们可以设置各种参数帮助内核确定何时要交换数据
2 当在内存,cache以及后备存储器之间同步数据时涉及到硬件相关的特性
触发数据的刷新有很多个不同的时间和不同的原因
1 内核线程周期性的查找在页链表中的脏页当有脏页产生时就挑选一些将他们写回,当系统写操作太忙时,可以设置系统中脏页脏的比率再操作
2 如果系统中有太多的脏页,系统就会同步到一个可接受的水平
3 当特定事件发生时内核要求数据同步,不如umount
内核有进程pdflush 针对前面两个原因,在第三个则有很多种方法可供选择
内核可以在很多地方开始同步,但是最终都是调用sync_sb_inodes,这个函数负责同步所有的脏的inode到superblock writeback_single_inode用作同步每个inode
Pdflush由两部分组成,分别是描述进程的数据结构和这方面的策略pdflush的定义如下:
struct pdflush_work {
struct task_struct *who; /* The thread */
void (*fn)(unsigned long); /* A callback function */
unsigned long arg0; /* An argument to the callback */
struct list_head list; /* On pdflush_list, when idle */
unsigned long when_i_went_to_sleep;
};
Pdflush是一个内核线程,它一旦产生就进入睡眠状态一直等到内核其他的部分调度到为止
pdflush_operation是pdflush线程被唤醒时调用的函数
wb_kupdate函数负责flushing的技术方面的具体实现。它是基于地址概念的关于wb_kupdata有两个重要的数据结构vm_stat
atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
第二个是struct writeback_control
Sync_super 是超级块的同步函数
Writeback_inode则是inode的同步函数
Linux同步inode里的数据则是调用__writeback_single_inode
阻塞指当读或写操作时内核的块设备队列超载,这时不能提交更多的块设备读写请求,最好的办法是当一些读写请求被处理,在新的请求之前块设备队列变的短一点
内核使用了两个队列,一个是输出,另一个是输入
对于内核来只说定义了一个最小的内存值
上面的机制回写页是合适的,但是当系统中的缓存数据快速变为脏页时就有问题了。当内核收到大量的内存请求但不能满足请求时因为有大量的脏页,这就必须尽快的清空内存把页里的数据写到块设备中去,内核提供了sync类似的调用都是基于wakeup_pdflush函数的
Linux内核里提供了系统调用可以同步
全部同步
同步inode:
同步个别文件则可以调用:
同步内存映射: