映射的冲突
时间:2007-06-19
来源:互联网
文件被映射时,都是按照逻辑块顺序被映射到连续的虚拟地址空间和物理页中
而文件在设备上的块是乱序的
如果块大小<物理页大小,那么设备文件和设备上的文件同时被映射时,岂不是无法满足其中的一个映射要求而形成冲突吗?
目前的块大小都是4k,难道是为了避免这个冲突?
作者: qtdszws 发布时间: 2007-06-19
设备文件和设备上的文件都可以被映射
文件被映射时,都是按照逻辑块顺序被映射到连续的虚拟地址空间和物理页中
而文件在设备上的块是乱序的
如果块大小<物理页大小,那么设备文件和设备上的文件同时 ...
楼主误解了mmap的实质了。首先在每个inode节点都有一组cache,称为page cache。也就是说你打开一个文件,它会有一个cache,你打开这个文件所在的设备,也会有个cache。mmap的作用就是把cache中的这些页和进程的地址空间关联起来。这样你在读一个文件的时候,mmap会帮你把文件中相应的内容读到cache中来,你就可以像操作内存一样操作文件。写的时候类似,所有更改都写到cache中,在同步到文件中去。所以映射和文件如何存储没有关系。
其次,通过文件和通过存放文件的设备文件来操作磁盘的某个区域实质是一样的。文件和存放文件的设备只是操作系统给你的对同一事物的不同抽象。乱序存放是存储器的概念,通过disk controller提供给操作系统的扇区号都是逻辑上顺序的。不管用哪种方式,你能看到的逻辑号都是顺序的。lz把文件系统和实际存储混淆了。
最后,linux中很少用4k这么大的block,这个在x86上已经是一个block的极限了(不能超过一个页),linux通常默认是1024的block,正好是2个sector的大小。
作者: zx_wing 发布时间: 2007-06-19
则mmap该文件后A
物理页|-------------------------------------------------|
块 |----a----|----b----|----c-----|-------d--------|
再映射该设备文件的话,必须这样映射B
物理页|-------------------------------------------------|
块 |----a----|----a+1---|---a+2---|----a+3----| b......c......d
但是这是不可能的
a,b,c,d已经被读入一个完整的页中,如何再映射到B中?
作者: qtdszws 发布时间: 2007-06-19
假如块大小为1k,文件f的开头四个块为a,b,c,d(不连续)
则mmap该文件后A
物理页|-------------------------------------------------|
块 |----a----|----b----|----c-----|-------d--------|
再映射该设 ...
请lz注意这句话:
首先在每个inode节点都有一组cache,称为page cache。也就是说你打开一个文件,它会有一个cache,你打开这个文件所在的设备,也会有个cache。mmap的作用就是把cache中的这些页和进程的地址空间关联起来。
所以,你这两个物理页面是不同的,一个属于文件,一个属于设备。
其实对于A的映射中,它只是把文件的内容读出来方到属于文件的物理页面中,并不更改文件的内容。所以对于B进行映射时,它同样可以把文件中的内容读入到自己的物理页面中。两者并不冲突。
作者: zx_wing 发布时间: 2007-06-19
按照你的解释,不就有了两个同样的buffer_head结构了吗?
作者: qtdszws 发布时间: 2007-06-19
在buffer层上,设备上的块是由设备号和块号唯一确定
按照你的解释,不就有了两个同样的buffer_head结构了吗?
首先没有所谓的buffer层,其次buffer_head只是把page cache中的page细分成以block为单位。当你用以文件的方式打开一个文件的时候,如果文件没有hole,则读写是以page为单位的而不是以block为单位的,所以不需要buffer_head。如果你用设备方式读写文件,则如你所说通过buffer_head来管理。不过这和映射没有什么关系。所以两种方式一般是不会有同样的buffer_head结构(除非文件有hole),及时有,也不存在问题,因为这些页面分属于不同的inode。
lz如果想把问题搞清楚,请阅读《understanding linux kernel》的第9章、第15章、第16章。如果仅仅想知道mmap的原理,阅读第16章第2节memory mapping就可以了。
[ 本帖最后由 zx_wing 于 2007-6-19 14:47 编辑 ]
作者: zx_wing 发布时间: 2007-06-19
那么你的这些数据是如何来的呢?是不是也要经过buffer层(buffer_head)从设备读取呢?
作者: qtdszws 发布时间: 2007-06-19
>>则读写是以page为单位的而不是以block为单位的,所以不需要buffer_head。
那么你的这些数据是如何来的呢?是不是也要经过buffer层(buffer_head)从设备读取呢?
lz混淆了buffer_head和下层block的关系了。
没有所谓的buffer层,我不知道你这个名字是哪儿看到的。buffer_head属于page cache,是kernel用来管理cache的一种数据结构,一般用于块设备。
最后的读操作最后是要转换成block,进而转换成sector,但这是在generic I/O layer做的事情,它在page cache的下层。
作者: zx_wing 发布时间: 2007-06-19
映射设备操作
v2.4.32
文件/dev/sda1
1.打开设备
fp=fopen("/dev/sda1","r");
sys_open->...->ext2_read_inode->init_special_inode->
inode->i_fop = &def_blk_fops;
该结构为(block_dev.c中)
struct file_operations def_blk_fops = {
open: blkdev_open,
release: blkdev_close,
llseek: block_llseek,
read: generic_file_read,
write: generic_file_write,
mmap: generic_file_mmap,
fsync: block_fsync,
ioctl: blkdev_ioctl,
};
sys_open->....->blkdev_open->bd_acquire->bdget
inode->i_data.a_ops = &def_blk_aops;
该结构为
struct address_space_operations def_blk_aops = {
readpage: blkdev_readpage,
writepage: blkdev_writepage,
sync_page: block_sync_page,
prepare_write: blkdev_prepare_write,
commit_write: blkdev_commit_write,
direct_IO: blkdev_direct_IO,
};
->bd_acquire
inode->i_mapping = bdev->bd_inode->i_mapping;
2.映射设备
mmap(fp,....)
sys_mmap2->....->generic_file_mmap
vma->vm_ops = &generic_file_vm_ops;
结构为
static struct vm_operations_struct generic_file_vm_ops = {
nopage: filemap_nopage,
};
3.对该内存块,发生缺页中断
do_page_fault->handle_mm_fault->handle_pte_fault->do_no_page
new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, 0);
调用filemap_nopage->page_cache_read
int error = mapping->a_ops->readpage(file, page);
调用blkdev_readpage->block_read_full_page->submit_bh
这样一来,就有可能存在一个块的两份拷贝了,从而可能导致混乱
谢谢zx_wing的帮助
作者: qtdszws 发布时间: 2007-06-19
看了一下代码,发现还真可以存在两个一样的buffer_head(dev,block)
映射设备操作
v2.4.32
文件/dev/sda1
1.打开设备
fp=fopen("/dev/sda1","r");
sys_open->...->ext2_rea ...
>>这样一来,就有可能存在一个块的两份拷贝了,从而可能导致混乱
所以这些同步的工作应该由kernel来保证,应该由我们程序员来做。赞lz遇到问题阅读源码的精神!
作者: zx_wing 发布时间: 2007-06-19
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28