the data structures used by the kernel for all I/O

以下的描述是概念性的,它可能符合或者不符合一個特定的實現。


內核使用三種數據結構表示打開的文件,它們之間的關係決定了在文件共享方面一個進程對另一個進程可能產生的影響。


1、每個進程在其進程表中都有一個記錄項,記錄項中包含有一張該進程打開文件描述符表。我們可以將它看做是一個vector,每條記錄對應一個描述符。與每個文件描述符相關聯的是:

a) 文件描述符標誌(The file descriptor flags) 

b) 一個指向文件表條目的指針(A pointer to a file table entry)


2、內核爲所有打開的文件維護一張文件表。每個文件表條目包含

a) 文件狀態標誌(The file status flags for the file)

b) 當前文件偏移量(The current file offset)

c) 指向該文件v-node表條目的指針(A pointer to the v-node table entry for the file)


3、每個打開的文件(或設備)都有一個v-node結構,它用於包含文件類型,在文件上操作的函數指針這些信息。對於大多數文件,v-node同時包含一個該文件的i-node。當文件被打開時,這個信息會從磁盤上被讀取,該文件所有相關的信息也會很容易被獲取。




對於兩個獨立的進程同時打開一個文件,則會有下面的安排:



我們在這假設第一個進程在文件描述符3上打開這個文件,第二個進程在文件描述符4上打開這個文件。每個打開文件的進程有它自己的文件表條目,但是對於一個給定的文件只需要一個v-node表條目。每個進程都有它自己的文件表條目的一個原因,就是每個進程都有它對於這個文件的偏移量。

給出這些數據結構後,我們對以下操作進行更深入的說明:

1、每個write完成後,在文件表條目中的偏移量就會增加所寫的字節數。如果引起當前文件偏移量超過文件大小,那麼在i-node中的當前文件大小將會被設置成當前文件偏移量。

2、如果一個文件使用O_APPEND標誌打開,那麼一個對應的標誌將會在文件表條目中的文件狀態標誌中被設置。每次對一個文件運行write時,在文件表條目中的當前文件偏移量會首先設置成i-node中的當前文件大小的值。這使得使每次write都會寫到文件尾。

3、如果一個文件通過lseek被定位到當前文件尾部,那麼就會發生:文件表條目中的當前文件偏移量被設置成i-node中的當前文件大小。(注意,這與通過O_APPEND標誌打開一個文件並不一樣)。

4、lseek函數只是修改文件表條目中的當前文件偏移量,並沒有I/O發生。


【備註】

1、多於一個文件描述符條目指向同一個文件表條目是可能的。可以通過dup函數實現。經過fork()後,父子進程對於每隔一文件都會共享相同的文件表條目。

2、注意文件描述符標誌(file descriptor flags)和文件狀態標誌(file status flags)作用於的區別。前者適用於單個進程內的單個文件,後者適用於指向該給定文件表條目的任何進程中的所有描述符。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章