ext2文件读(写)过程:结构图(P561) 理解每一层的做什么
read(P508) 【层:User Mode】
-->sys_read-->vfs_read-->file->f_op->read() 【层:VFS】
---->generic_file_read(P632) 【层:Disk File(Block Device File)】
------>do_generic_file_read(p635)-->do_generic_mapping_read 【层:Page Cache (inode)】
-------->ext2_read_page(P638)-->mpage_readpage() 【层:ext2】
---------->submit_bio()-->generic_make_request(P570) 【层:Generic Block Layer】
------------>__make_request -->q->add_request() 【层:I/O Scheduler】
相关request在I/O Scheduler队列中的 q->request_fn函数(即do_hd_request)调用:
do_hd_request(以HD.c为例) 【层:Block Device Driver 取队列,发起读请求】
-->elv_next_request(),
-->hd_request()
read_intr() 【层:Block Device Driver中断,读数据,从队列中删除,再发起请求】
-->end_request()
---->end_that_request_first()
---->blkdev_dequeue_request()
---->end_that_request_last()
共享内存(P801)、文件映射(P657)、直接文件读写的区别
a. 共享内存的缺页:
do_no_page (预先在mmap()-->shmem_zero_setup设置shmem_nopage )
-->vma->vm_ops->nopage
-->shmem_nopage
---->shmem_getpage
------>find_lock_page
------>shmem_alloc_page
------>add_to_page_cache_lru
b. 文件映射的缺页:
do_no_page(预先在mmap-->file->f_op->mmap设置filemap_nopage)
-->vma->vm_ops->nopage
-->filemap_nopage
---->find_get_page
---->mapping->a_ops->readpage(一般为ext2_aops.read)
---->ext2_readpage 函数直接读写 ext2文件系统,inode缓存由前面的步骤建立了。
c. 文件映射和直接读写文件相同点:
i. 都调用ext2_readpage函数,则ext2层以下完全相同
ii. 都采用inode的Page Cache,由直接文件读写的do_generic_file_read和文件映射的filemap_nopage分别建立
iii. 都可能尝试磁盘的预读。
d. 文件映射和直接文件读写不同点:
直接读文件,修改后并写入文件:数据需要从内核态-->用户态复制一次,再从用户态-->内核态复制一次,还可能需要两次高端映射。
read(P508) 【层:User Mode】
-->sys_read-->vfs_read-->file->f_op->read() 【层:VFS】
---->generic_file_read(P632) 【层:Disk File(Block Device File)】
------>do_generic_file_read(p635)-->do_generic_mapping_read 【层:Page Cache (inode)】
-------->ext2_read_page(P638)-->mpage_readpage() 【层:ext2】
---------->submit_bio()-->generic_make_request(P570) 【层:Generic Block Layer】
------------>__make_request -->q->add_request() 【层:I/O Scheduler】
相关request在I/O Scheduler队列中的 q->request_fn函数(即do_hd_request)调用:
do_hd_request(以HD.c为例) 【层:Block Device Driver 取队列,发起读请求】
-->elv_next_request(),
-->hd_request()
read_intr() 【层:Block Device Driver中断,读数据,从队列中删除,再发起请求】
-->end_request()
---->end_that_request_first()
---->blkdev_dequeue_request()
---->end_that_request_last()
共享内存(P801)、文件映射(P657)、直接文件读写的区别
a. 共享内存的缺页:
do_no_page (预先在mmap()-->shmem_zero_setup设置shmem_nopage )
-->vma->vm_ops->nopage
-->shmem_nopage
---->shmem_getpage
------>find_lock_page
------>shmem_alloc_page
------>add_to_page_cache_lru
b. 文件映射的缺页:
do_no_page(预先在mmap-->file->f_op->mmap设置filemap_nopage)
-->vma->vm_ops->nopage
-->filemap_nopage
---->find_get_page
---->mapping->a_ops->readpage(一般为ext2_aops.read)
---->ext2_readpage 函数直接读写 ext2文件系统,inode缓存由前面的步骤建立了。
c. 文件映射和直接读写文件相同点:
i. 都调用ext2_readpage函数,则ext2层以下完全相同
ii. 都采用inode的Page Cache,由直接文件读写的do_generic_file_read和文件映射的filemap_nopage分别建立
iii. 都可能尝试磁盘的预读。
d. 文件映射和直接文件读写不同点:
直接读文件,修改后并写入文件:数据需要从内核态-->用户态复制一次,再从用户态-->内核态复制一次,还可能需要两次高端映射。