11 ext2文件系统IO流程:读写文件read/write

ext2使用page页面缓存来完成对文件的读写。这些页面的管理是通过inode的字段i_mapping来完成,也就是地址空间。所以在创建inode时,要指定i_mapping的操作表a_ops,帮助地址空间完成页面操作。

参考:014 Linux文件系统数据结构详解:地址空间struct address_space

地址空间操作表a_ops中,需要指定读page、写page等多种页面操作的函数指针,但是具体的块操作(读取、写入)、buffer操作、VM页面操作,其实文件系统不用太关注,因为Linux内核提供了大量公共函数(参考:buffer.c和mpage.c),文件系统可以直接调用完成读取和写入。但是,文件系统需要提供块的映射方法,帮助完成文件系统逻辑块号(就是在文件中的偏移量)到实际块设备块号映射,最后填充到buffer_head中。

// inode.c

const struct address_space_operations ext2_aops = {
	.set_page_dirty		= __set_page_dirty_buffers,
	.readpage		= ext2_readpage,
	.readahead		= ext2_readahead,
	.writepage		= ext2_writepage,
	.write_begin		= ext2_write_begin,
	.write_end		= ext2_write_end,
	.bmap			= ext2_bmap,
	.direct_IO		= ext2_direct_IO,
	.writepages		= ext2_writepages,
	.migratepage		= buffer_migrate_page,
	.is_partially_uptodate	= block_is_partially_uptodate,
	.error_remove_page	= generic_error_remove_page,
};
继续阅读“11 ext2文件系统IO流程:读写文件read/write”

06 ext2文件系统IO流程:创建目录mkdir

前一篇介绍了在目录下创建文件,我接下来们继续ext2主IO流程:创建目录。不论是创建文件还是创建目录,都是基于父目录,两者有很多相似之处,都要新建inode和目录项,然后建立inode与dentry的关系。但是创建目录操作,在写入目录项时,要多写两个目录项.(当前目录)和..(上层目录),详细流程如下:

  • 新建inode,并标记dirty,待内核同步
  • 设置操作表:i_op、i_fop、i_mapping->a_ops
  • 新建.和..两个目录项,inode指向新建的inode,并持久化
  • 在父目录的页缓存中,寻找一个空间,新建目录的目录项,inode指向新建的inode,并持久化(ext2_add_link)
  • 建立缓存dentry与inode关系
ext2创建目录
ext2创建目录
继续阅读“06 ext2文件系统IO流程:创建目录mkdir”