亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
123456下一頁(yè)
最近訪問(wèn)板塊 發(fā)新帖
查看: 21643 | 回復(fù): 55
打印 上一主題 下一主題

映射的沖突 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2007-06-19 10:27 |只看該作者 |倒序?yàn)g覽
設(shè)備文件和設(shè)備上的文件都可以被映射

文件被映射時(shí),都是按照邏輯塊順序被映射到連續(xù)的虛擬地址空間和物理頁(yè)中

而文件在設(shè)備上的塊是亂序的

如果塊大小<物理頁(yè)大小,那么設(shè)備文件和設(shè)備上的文件同時(shí)被映射時(shí),豈不是無(wú)法滿足其中的一個(gè)映射要求而形成沖突嗎?

目前的塊大小都是4k,難道是為了避免這個(gè)沖突?

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2007-06-19 11:19 |只看該作者
原帖由 qtdszws 于 2007-6-19 10:27 發(fā)表于 1樓  
設(shè)備文件和設(shè)備上的文件都可以被映射

文件被映射時(shí),都是按照邏輯塊順序被映射到連續(xù)的虛擬地址空間和物理頁(yè)中

而文件在設(shè)備上的塊是亂序的

如果塊大小<物理頁(yè)大小,那么設(shè)備文件和設(shè)備上的文件同時(shí) ...

樓主誤解了mmap的實(shí)質(zhì)了。首先在每個(gè)inode節(jié)點(diǎn)都有一組cache,稱(chēng)為page cache。也就是說(shuō)你打開(kāi)一個(gè)文件,它會(huì)有一個(gè)cache,你打開(kāi)這個(gè)文件所在的設(shè)備,也會(huì)有個(gè)cache。mmap的作用就是把cache中的這些頁(yè)和進(jìn)程的地址空間關(guān)聯(lián)起來(lái)。這樣你在讀一個(gè)文件的時(shí)候,mmap會(huì)幫你把文件中相應(yīng)的內(nèi)容讀到cache中來(lái),你就可以像操作內(nèi)存一樣操作文件。寫(xiě)的時(shí)候類(lèi)似,所有更改都寫(xiě)到cache中,在同步到文件中去。所以映射和文件如何存儲(chǔ)沒(méi)有關(guān)系。

其次,通過(guò)文件和通過(guò)存放文件的設(shè)備文件來(lái)操作磁盤(pán)的某個(gè)區(qū)域?qū)嵸|(zhì)是一樣的。文件和存放文件的設(shè)備只是操作系統(tǒng)給你的對(duì)同一事物的不同抽象。亂序存放是存儲(chǔ)器的概念,通過(guò)disk controller提供給操作系統(tǒng)的扇區(qū)號(hào)都是邏輯上順序的。不管用哪種方式,你能看到的邏輯號(hào)都是順序的。lz把文件系統(tǒng)和實(shí)際存儲(chǔ)混淆了。

最后,linux中很少用4k這么大的block,這個(gè)在x86上已經(jīng)是一個(gè)block的極限了(不能超過(guò)一個(gè)頁(yè)),linux通常默認(rèn)是1024的block,正好是2個(gè)sector的大小。

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2007-06-19 12:19 |只看該作者
假如塊大小為1k,文件f的開(kāi)頭四個(gè)塊為a,b,c,d(不連續(xù))
則mmap該文件后A
物理頁(yè)|-------------------------------------------------|
塊    |----a----|----b----|----c-----|-------d--------|

再映射該設(shè)備文件的話,必須這樣映射B
物理頁(yè)|-------------------------------------------------|
塊    |----a----|----a+1---|---a+2---|----a+3----|    b......c......d
但是這是不可能的
a,b,c,d已經(jīng)被讀入一個(gè)完整的頁(yè)中,如何再映射到B中?

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2007-06-19 12:33 |只看該作者
原帖由 qtdszws 于 2007-6-19 12:19 發(fā)表于 3樓  
假如塊大小為1k,文件f的開(kāi)頭四個(gè)塊為a,b,c,d(不連續(xù))
則mmap該文件后A
物理頁(yè)|-------------------------------------------------|
塊    |----a----|----b----|----c-----|-------d--------|

再映射該設(shè) ...

請(qǐng)lz注意這句話:
首先在每個(gè)inode節(jié)點(diǎn)都有一組cache,稱(chēng)為page cache。也就是說(shuō)你打開(kāi)一個(gè)文件,它會(huì)有一個(gè)cache,你打開(kāi)這個(gè)文件所在的設(shè)備,也會(huì)有個(gè)cache。mmap的作用就是把cache中的這些頁(yè)和進(jìn)程的地址空間關(guān)聯(lián)起來(lái)。
所以,你這兩個(gè)物理頁(yè)面是不同的,一個(gè)屬于文件,一個(gè)屬于設(shè)備。
其實(shí)對(duì)于A的映射中,它只是把文件的內(nèi)容讀出來(lái)方到屬于文件的物理頁(yè)面中,并不更改文件的內(nèi)容。所以對(duì)于B進(jìn)行映射時(shí),它同樣可以把文件中的內(nèi)容讀入到自己的物理頁(yè)面中。兩者并不沖突。

論壇徽章:
0
5 [報(bào)告]
發(fā)表于 2007-06-19 14:14 |只看該作者
在buffer層上,設(shè)備上的塊是由設(shè)備號(hào)和塊號(hào)唯一確定

按照你的解釋,不就有了兩個(gè)同樣的buffer_head結(jié)構(gòu)了嗎?

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2007-06-19 14:38 |只看該作者
原帖由 qtdszws 于 2007-6-19 14:14 發(fā)表于 5樓  
在buffer層上,設(shè)備上的塊是由設(shè)備號(hào)和塊號(hào)唯一確定

按照你的解釋,不就有了兩個(gè)同樣的buffer_head結(jié)構(gòu)了嗎?

首先沒(méi)有所謂的buffer層,其次buffer_head只是把page cache中的page細(xì)分成以block為單位。當(dāng)你用以文件的方式打開(kāi)一個(gè)文件的時(shí)候,如果文件沒(méi)有hole,則讀寫(xiě)是以page為單位的而不是以block為單位的,所以不需要buffer_head。如果你用設(shè)備方式讀寫(xiě)文件,則如你所說(shuō)通過(guò)buffer_head來(lái)管理。不過(guò)這和映射沒(méi)有什么關(guān)系。所以?xún)煞N方式一般是不會(huì)有同樣的buffer_head結(jié)構(gòu)(除非文件有hole),及時(shí)有,也不存在問(wèn)題,因?yàn)檫@些頁(yè)面分屬于不同的inode。

lz如果想把問(wèn)題搞清楚,請(qǐng)閱讀《understanding linux kernel》的第9章、第15章、第16章。如果僅僅想知道m(xù)map的原理,閱讀第16章第2節(jié)memory mapping就可以了。

[ 本帖最后由 zx_wing 于 2007-6-19 14:47 編輯 ]

論壇徽章:
0
7 [報(bào)告]
發(fā)表于 2007-06-19 14:54 |只看該作者
>>則讀寫(xiě)是以page為單位的而不是以block為單位的,所以不需要buffer_head。

那么你的這些數(shù)據(jù)是如何來(lái)的呢?是不是也要經(jīng)過(guò)buffer層(buffer_head)從設(shè)備讀取呢?

論壇徽章:
0
8 [報(bào)告]
發(fā)表于 2007-06-19 15:11 |只看該作者
原帖由 qtdszws 于 2007-6-19 14:54 發(fā)表于 7樓  
>>則讀寫(xiě)是以page為單位的而不是以block為單位的,所以不需要buffer_head。

那么你的這些數(shù)據(jù)是如何來(lái)的呢?是不是也要經(jīng)過(guò)buffer層(buffer_head)從設(shè)備讀取呢?

lz混淆了buffer_head和下層block的關(guān)系了。
沒(méi)有所謂的buffer層,我不知道你這個(gè)名字是哪兒看到的。buffer_head屬于page cache,是kernel用來(lái)管理cache的一種數(shù)據(jù)結(jié)構(gòu),一般用于塊設(shè)備。
最后的讀操作最后是要轉(zhuǎn)換成block,進(jìn)而轉(zhuǎn)換成sector,但這是在generic I/O layer做的事情,它在page cache的下層。

論壇徽章:
0
9 [報(bào)告]
發(fā)表于 2007-06-19 17:52 |只看該作者
看了一下代碼,發(fā)現(xiàn)還真可以存在兩個(gè)一樣的buffer_head(dev,block)

映射設(shè)備操作
v2.4.32
文件/dev/sda1

1.打開(kāi)設(shè)備
fp=fopen("/dev/sda1","r");
sys_open->...->ext2_read_inode->init_special_inode->
inode->i_fop = &def_blk_fops;
該結(jié)構(gòu)為(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;
該結(jié)構(gòu)為
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.映射設(shè)備
mmap(fp,....)
sys_mmap2->....->generic_file_mmap
vma->vm_ops = &generic_file_vm_ops;
結(jié)構(gòu)為
static struct vm_operations_struct generic_file_vm_ops = {
        nopage:                filemap_nopage,
};

3.對(duì)該內(nèi)存塊,發(fā)生缺頁(yè)中斷
do_page_fault->handle_mm_fault->handle_pte_fault->do_no_page
new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, 0);
調(diào)用filemap_nopage->page_cache_read
int error = mapping->a_ops->readpage(file, page);
調(diào)用blkdev_readpage->block_read_full_page->submit_bh

這樣一來(lái),就有可能存在一個(gè)塊的兩份拷貝了,從而可能導(dǎo)致混亂

謝謝zx_wing的幫助

論壇徽章:
0
10 [報(bào)告]
發(fā)表于 2007-06-19 18:09 |只看該作者
原帖由 qtdszws 于 2007-6-19 17:52 發(fā)表于 9樓  
看了一下代碼,發(fā)現(xiàn)還真可以存在兩個(gè)一樣的buffer_head(dev,block)

映射設(shè)備操作
v2.4.32
文件/dev/sda1

1.打開(kāi)設(shè)備
fp=fopen("/dev/sda1","r");
sys_open->...->ext2_rea ...

>>這樣一來(lái),就有可能存在一個(gè)塊的兩份拷貝了,從而可能導(dǎo)致混亂
所以這些同步的工作應(yīng)該由kernel來(lái)保證,應(yīng)該由我們程序員來(lái)做。贊lz遇到問(wèn)題閱讀源碼的精神!
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專(zhuān)區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP