日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

2 FreeBSD 核心( 四 )


(代續(xù))



FreeBSD核心探討.7.驅(qū)動程序篇

2.2.5系統(tǒng)調(diào)用open()的處理概要
進(jìn)程通過系統(tǒng)調(diào)用read()/write()進(jìn)行io處理,它由文件描述符指定對哪里進(jìn)
行i/o,文件描述符是0以上的整數(shù),它在各個(gè)進(jìn)程的struct proc的成員
struct filedesc *p_fd(struct filedesc(@sys/filedesc.h))保留的struct file
((@sys/file.h)進(jìn)行選擇添加 。對struct file,它含有從文件的頭的輸入輸出的byte
位置,輸入操作,輸出操作,輸入輸出控制,輸入輸出的準(zhǔn)備狀態(tài)的檢查,執(zhí)行close
的routine,以及描述io處理對象的信息(v-node,socket,pipe)。系統(tǒng)調(diào)用open()
(@kern/vfs_syscalls.c)就是把包含路徑信息的v-node找尋出來,為了對它進(jìn)行io處理,
先要對struct file進(jìn)行初始化,然后返回文件描述符 。
從路徑名查找v-nodehe和io準(zhǔn)備操作由vn_open()(@kern/vfs_vnops.c)承擔(dān) 。
vn_open()通過namei()(@kern/vfs_lookup.c)查找路徑對應(yīng)的v-node名,由VOP_OPEN()
調(diào)用不同的v-node定義的準(zhǔn)備過程routine 。例如,有如下的處理方法 。
。普通的file/Directory
調(diào)用ufs_open()(@ufs/ufs/ufs_vnops.c),檢查open的mode
。特殊設(shè)備文件
調(diào)用spec_open()(@miscfs/specfs/spec_vnops.c)
文字型 調(diào)用device driver的open routine
快型 mount的時(shí)候出錯(cuò) 。如果不是這樣,就調(diào)用device driver的
open routine 。

回過頭來,namei()的任務(wù)是就是,對于指定的路徑名,對應(yīng)于跟目錄或者當(dāng)
前目錄的v-node作為起點(diǎn),通過lookup()(@kern/vfs_lookup.c)進(jìn)行v-node查找 。
lookup()從路徑名開始的v-node(VDIR)開始查找 。找到了的v-node作為新的起點(diǎn)繼續(xù)進(jìn)行
查找下一步的要素名,然后得到目的的v-node 。這個(gè)時(shí)候,根據(jù)v-node的不同,目錄的檢
索方法也就不同 。各個(gè)要素的實(shí)際檢索由VOP_LOOKUP()來做 。

2.2.6系統(tǒng)調(diào)用read()的處理概要
open()取得文件描述符后,對它的輸入處理,有如下的流程 。指定的文件描述符
的struct file內(nèi)登記的處理routine有vn_read()(@kern/vfs_vnops.c),vn_write(),
vn_ioctl(),vn_select(),vn_closefile(),v_node
登記的操作routine不能分開使用 。vn_*()里,只有在合適的前綴操作下,才能正確調(diào)用 。
read()首先在struct uio(@sys/uio.h)登記進(jìn)程指定的buffer的位置和長度 。
執(zhí)行read()后,vn_read()向struct file設(shè)定登記的文件的讀寫位置,然后調(diào)用VOP_READ() 。
根據(jù)讀出來的byte數(shù),讀寫位置相應(yīng)增加 。
VOP_READ()的call routine則是與v-node有關(guān),就象下圖一樣 。

vn_read()
文字型/塊型 |
/------------------
| | file/directory
spec_read() ---------ffs_read()-------VOP_READ()
block型 | |
/---------------|char型 |
bread() device driver bread()
| |
spec_strategy() ---------------ufs_strategy() --VOP_STRATEGY()
| | |
| | |
device driver spec_strategy() -------------/
|
|
device driver


。普通的file/directory
調(diào)用ffs_read()(@ufs/ufs/ufs_readwrite.c) 。對應(yīng)指定的讀寫位置,計(jì)算block
的位置,然后用bread()讀出來 。讀出來的數(shù)據(jù)送到進(jìn)程所準(zhǔn)備的緩沖區(qū) 。從bread()
傳遞過來的block并不是物理block的位置,而是把file作為block列的一個(gè)理論值 。
從理論塊到物理塊的變換由VOP_STARATEGY()完成 。也就是說,ufs_strategy()先把
文件內(nèi)位置轉(zhuǎn)化為物理block位置,然后從v-node記錄的i-node把表示物理設(shè)備的
v-node 去出來,這個(gè)VOP_STRATEGY就調(diào)用spec()(@miscfs/specfs/spec_vnops.c)
讓它進(jìn)行輸入要求 。
。特殊設(shè)備文件
通過調(diào)用spec_read()(@miscfs/specfs/spec_vnops.c),把它分為文字型和塊型兩類 。
文字型 調(diào)用device driver的輸入routine
塊型 通過bread()進(jìn)行輸入處理

對文件的系統(tǒng)調(diào)用write()的場合也是類似的處理流程(ufs_write()->bwrite()),

推薦閱讀