Linux Page IO

page IO,顾名思义,一端连接着内存,一端连接着IO系统,可以看作内存子系统和IO子系统的中间层,部分资料把这部分划归到Block层, 但我觉得虽然这部分上和IO强相关, 但同时又涉及到很多内存页的数据结构, 所以还是单独划归到一层比较好. 通常,对一个文件的回写IO数据首先通过文件系统写入到Page Cache中,之后,就通过Page IO层,以异步的方式下发到Block IO子系统。当然,文件系统的数据也可以直接写入到Block IO子系统(Direct IO)。

Page IO层的核心工作就是构造并管理bio, bio作为IO的基本单位,描述了IO从内存到磁盘的映射,bio的构造借助了内存管理中的buffer_head结构完成其构造。 buffer_head负责page到扇区的固定映射,在此基础上,bio只需了解IO的内存端,即可计算出它的磁盘端位置

在IO路径中,构造bio的代码流程如下:

__filemap_fdatawrite_range()			//mm/filemap.c +286
	struct writeback_control wbc = {...}	
	do_writepages()						//mm/page-writeback.c +2337
		mapping->a_ops->writepages()	//mm/page-writeback.c +2035
ext4_writepages()
	write_cache_pages(mapping, wbc, __writepage, mapping)
__writepage()	
	ext4_writepage()
		ext4_io_submit_init(&io_submit, wbc)
			io->io_wbc = wbc;
   			io->io_bio = NULL;
  			io->io_end = NULL;
		ext4_init_io_end(inode, GFP_NOFS)
		ext4_bio_write_page()
			bh = head = page_buffers(page)
			io_submit_add_bh()
				ext4_io_submit()
				io_submit_init_bio()						//分配并初始化bio
			        bio = bio_alloc(GFP_NOIO, BIO_MAX_PAGES);	
        			wbc_init_bio(io->io_wbc, bio);
        			bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); 
        			bio->bi_bdev = bh->b_bdev;
        			bio->bi_end_io = ext4_end_bio;
        			bio->bi_private = ext4_get_io_end(io->io_end);
        			io->io_bio = bio;
        			io->io_next_block = bh->b_blocknr;	
				bio_add_page()
		ext4_io_submit(&io_submit)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.