[基于2.6.8内核]
这两个函数在do_sync的时候都要调用两次,这是为何?sync_filesystems这个函数的作用是什么?do_sync在什么时候会被调用?
对于第一个问题,调用两次其实就是一个分类,do_sync的实现如下:
static void do_sync(unsigned long wait)
{
wakeup_pdflush(0); //唤醒pdflush,使之帮忙在调用do_sync的进程被调度出去之后pdflush(实际上是一个worker)被调度进来时仍然执行写回操作,也就是举全国之力进行同步
sync_inodes(0); //第一次调用同步inodes
sync_filesystems(0);//第一次...
sync_filesystems(wait); //第二次...
sync_inodes(wait); //第二次调用同步inodes
}
第一次调用同步inodes的时候,参数为0,进入sync_inodes之后发现对于被锁住的inode来说并不等待其被解锁直接返回,而且很轻松的仅仅是发起了一个当前可以被同步的inode的同步操作,然后在第二次进行sync_inodes调用的时候再等待所有第一次未被发起同步操作的inode的同步操作,包括等待第一次调用时发起但是还没有完成的同步操作。如果合并成一个调用,那么能迅速完成的和不能迅速完成混合在一起,处理起来弊端很多,比如等待被锁inode解锁的时间会很长,这期间可能它后面的一个inode也被锁上了,或者发生了别的什么事,最好的办法当然就是将可以尽快完成的操作尽快完成,万不得已的时候,也就是第二次调用sync_inodes的时候再处理那些慢速操作,这里面有一个思想,那就是对于那些慢速操作(inode被锁定,需要等待其解锁),反正第一次调用时会很慢,那么既然有第二次调用机会,姑且先不管它,说不定到第二次调用sync函数的时候,它还可能被解锁了呢!因此这两次sync_inodes调用的分工很明确,第一次调用的目的是尽可能多地“发起”io操作,并不等待其完成,第二次调用sync_inodes的目的是发起第一次调用不便发起的io操作,并等待两次发起的io操作的完成。
还有一个细节,那就是sync_inodes中对sync_blockdev的调用。既然在__sync_single_inode中已经调用了do_writepages,而sync_blockdev中基本上也是do_writepages的调用,这不是重复了吗?其实是不重复的,两个地方的调用参数mapping并不是一个mapping,__sync_single_inode中的mapping是针对一个特定的文件系统文件的,比如一个ext2文件系统的文件/home/aaa,而sync_blockdev中的mapping是针对整个块设备的,由于块设备也是一个文件,因此也有一个address_space负责管理页缓存,它主要是管理inode元数据的,比如一个特定文件系统的特定文件的inode所包含的数据就由这个address_space来管理,在__sync_single_inode中有write_inode的调用,然而这个调用将最终的执行流交给了具体文件系统超级块的回调函数,这个回调函数由该文件系统的设计者来实现,并不能保证其已经将数据刷新到了磁盘(但是必须能够弄脏一个inode数据所在的页面),因此必须显式刷新块设备的address_space中的dirty页面才可以保证。如果看一下代码就会发现,实际上即使是一般的文件,比如/home/aaa,它的数据页面最终也是进入到了其所在块设备的address_space中的,这在具体文件系统的get_block(如果有的话)中有所体现,这就意味着任何的(起码大多数)文件系统都是基于“块”来进行io的,而到了“块”这一层也就没有文件的概念了,因此几乎所有的文件数据最终都无法绕开“块”的管理,也就是说,所有的文件数据页面最终都要进入到对应块设备的address_space中,但是虽然一般文件的数据页面进入了对应块设备的address_space中,这个address_space并不管理这个页面的PAGECACHE_TAG_DIRTY或者PAGECACHE_TAG_XX,它仅仅管理诸如inode等元数据的数据页面在address_space中的tag(PAGECACHE_TAG_XX),因此sync_blockdev最终到达:
nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
PAGECACHE_TAG_DIRTY,
的时候,是不会触及到一般文件的数据页面的,块设备的address_space中页面的tag在诸如write_inode等处理元数据的位置被更改。因此__sync_inodes中的:
if (sb->s_root) {
sync_inodes_sb(sb, wait);
sync_blockdev(sb->s_bdev);
}
中sync_inodes_sb负责一般文件,而sync_blockdev负责元数据。
sync_filesystems这个函数的作用是什么?它很简单,就是调用了文件系统超级块的sync_fs回调函数,具体怎么实现,那就是文件系统自己的事情了,比如很多日志文件系统或者基于快照的文件的可恢复文件系统,在这里可以提交一个事务。do_sync在什么时候被调用呢?有两个地方,第一个就是显式的调用sync的时候,第二个就是pdflushd被唤醒的时候,pdflush在执行do_sync的时候,参数为0,这意味着它仅仅进行两次碰运气的操作,以求得最大限度的刷新文件,定时刷新这件事并不是急迫的。
最后set_sb_syncing是干什么的?实际上从do_sync中就可以看出,其第一句表明pdflush也会参与这次刷新操作,或者说别的用户进程也调用了sync,并且这个一般的操作并没有禁用掉中断之类的,也没有禁止抢占,因此真的有可能好几个执行流同时进行同步刷新操作,这并不是什么好事,为了保证每次只有一个进程在执行这个操作,set_sb_syncing函数起到了作用
分享到:
相关推荐
这段脚本首先设置了环境变量`PATH`以便找到`genext2fs`工具,然后计算了system分区所需的数据块数量(`num_blocks`)和inode数量(`num_inodes`),并最终调用`genext2fs`工具生成system.img。之后还使用`tune2fs`工具对...
- **i_file_acl**: 文件的访问控制列表。 - **i_dir_acl**: 目录的访问控制列表。 以上是Ext2文件系统的主要组成部分和数据结构的详细介绍。通过这些信息可以深入了解Ext2的工作原理及其如何高效地管理文件和目录。
- s_inodes_count:存储系统中文件节点的数量。 - s_free_inodes_count:记录空闲的文件节点数量。 - s_blocks_count:存储系统中总的块数。 - s_r_blocks_count:记录保留块的数量。 - s_free_blocks_count:记录...
__le32 s_inodes_count; // 文件系统中 inode 的总数 __le32 s_blocks_count; // 文件系统中块的总数 __le32 s_r_blocks_count; // 保留块的总数 __le32 s_free_blocks_count; // 未使用的块的总数(包括保留块...
安卓9.0 make_ext4fs文件,make_ext4fs用于Android平台上制作ext4文件系统的镜像。 make_ext4fs [ -l <len> ] [ -j <journal size>...[ -z | -s ] [ -w ] [ -c ] [ -J ] [ -v ] [ -B <block_list_file> ] <filename> []
此外,FSP HDR还维护了多个链表,如“free”列表(未使用的扩展)、“free_frag”列表(部分使用的扩展)、“full_frag”列表(全部使用的扩展,用于叶子节点数据)以及“full_inodes”和“free_inodes”列表(分别...
- **s_free_inodes_count**:文件系统中的空闲inode数。 - **s_first_data_block**:数据块的起始位置。 - **s_log_block_size**:块大小的对数值。 - **s_log_frag_size**:片段大小的对数值。 - **s_blocks_per_...
make_ext4fs用于Android平台上制作ext4文件系统的镜像。 make_ext4fs [ -l <len> ] [ -j <journal size> ] [ -b <block_size> ] ...[ -z | -s ] [ -w ] [ -c ] [ -J ] [ -v ] [ -B <block_list_file> ] <filename> []
- **s_inodes_per_group**: 每个块组中的索引节点数。 ##### 4. 块组描述符 块组描述符的字段包括: - **bg_block_bitmap**: 块位图的块号。 - **bg_inode_bitmap**: 索引节点位图的块号。 - **bg_inode_table**:...
innodb_log_file_size 是 MySQL 的另一个重要参数,对其进行调整可以提高 MySQL 的性能。一般情况下,innodb_log_file_size 应该设为 64M。 其他优化方法 除了以上方法外,还有其他的优化方法,可以根据实际情况...
* s_inodes_count:文件系统中 inode 的总数 * s_blocks_count:数据块总数 * s_r_blocks_count:保留块总数 * s_free_blocks_count:空闲块总数 * s_free_inodes_count:空闲的 inode 总数 * s_log_block_size:...
- `s_inodes_count`:文件卷的I节点总数。 - `s_blocks_count`:文件卷的逻辑块总数。 - `s_r_blocks_count`:为超级用户预留的块数。 - `s_free_blocks_count`:空闲块数。 - `s_free_inodes_count`:空闲I节点数。...
make_ext4fs用于Android平台上制作ext4文件系统的镜像。 make_ext4fs [ -l <len> ] [ -j <journal size> ] [ -b <block_size> ] ...[ -z | -s ] [ -w ] [ -c ] [ -J ] [ -v ] [ -B <block_list_file> ] <filename> []
同时,也会更新相应的空间管理信息,如free_inodes和free_blocks。 5. 快照创建:UBIFS还会创建一个快照,保存当前提交点的系统状态,用于后续的回滚操作。这是UBIFS能够提供一致性的关键。 三、"lpt_commit.c...
4. 释放 pagecache、dentries 和 inodes:使用 echo 3 > /proc/sys/vm/drop_caches 命令释放 pagecache、dentries 和 inodes。 5. 确保文件系统的完整性:使用 sync 命令确保文件系统的完整性。 Linux 系统中的内存...
这些系统调用可能包括`sync`(确保所有数据写入磁盘)、`shrink_file_cache`(减少文件系统缓存)和`drop_caches`(清除内核缓存)。但是,`drop_caches`这个系统调用通常需要root权限,并且谨慎使用,因为它可能会...
Linux的虚拟文件系统(Virtual File System, VFS)是内核中的一个核心组件,负责提供统一的接口来管理不同类型的文件系统。VFS层抽象了各种文件系统实现之间的差异,使得应用程序无需关心底层文件系统的具体实现细节。...
VxFS(Veritas File System)是Veritas Technologies LLC开发的一种高性能、高可用性和高可扩展性的日志文件系统,广泛应用于大型企业级环境,特别是那些需要高度数据完整性和一致性的场景。在“vxfs_immed.rar_...