繼上一篇文章: http://www.cnblogs.com/linhaostudy/p/7428971.html 四、file結構體 文件對象:註意文件對象描述的是進程已經打開的文件。因為一個文件可以被多個進程打開,所以一個文件可以存在多個文件對象。但是由於文件是唯一的,那麼inode就是唯一的, ...
繼上一篇文章:
http://www.cnblogs.com/linhaostudy/p/7428971.html
四、file結構體
文件對象:註意文件對象描述的是進程已經打開的文件。因為一個文件可以被多個進程打開,所以一個文件可以存在多個文件對象。但是由於文件是唯一的,那麼inode就是唯一的,目錄項也是定的!
進程其實是通過文件描述符來操作文件的,註意每個文件都有一個32位的數字來表示下一個讀寫的位元組位置,這個數字叫做文件位置。
565 struct file { 566 struct list_head f_list; 567 struct dentry *f_dentry; 568 struct vfsmount *f_vfsmnt; 569 struct file_operations *f_op; 570 atomic_t f_count; 571 unsigned int f_flags; 572 mode_t f_mode; 573 loff_t f_pos; 574 unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin; 575 struct fown_struct f_owner; 576 unsigned int f_uid, f_gid; 577 int f_error; 578 579 size_t f_maxcount; 580 unsigned long f_version; 581 582 /* needed for tty driver, and maybe others */ 583 void *private_data; 584 585 /* preallocated helper kiobuf to speedup O_DIRECT */ 586 struct kiobuf *f_iobuf; 587 long f_iobuf_lock; 588 };
f_list:所有的打開的文件形成的鏈表!註意一個文件系統所有的打開的文件都通過這個鏈接到super_block中的s_files鏈表中!
f_dentry:與該文件相關的dentry
f_vfsmnt:該文件在這個文件系統中的安裝點
f_op:文件操作,當進程打開文件的時候,這個文件的關聯inode中的i_fop文件操作會初始化這個f_op欄位
f_count:引用計數
f_flags:打開文件時候指定的標識
f_mode:文件的訪問模式
f_pos:目前文件的相對開頭的偏移
unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin:預讀標誌、要預讀的最多頁面數、上次預讀後的文件指針、預讀的位元組數以及預讀的頁面數
f_owner:記錄一個進程ID,以及當某些事發送的時候發送給該ID進程的信號
f_uid:用戶ID
f_gid:組ID
f_error:寫操作錯誤碼
f_version:版本號,當f_pos改變時候,version遞增
private_data:私有數據( 文件系統和驅動程式使用 )
重點解釋一些重要欄位:
首先,f_flags、f_mode和f_pos代表的是這個進程當前操作這個文件的控制信息。這個非常重要,因為對於一個文件,可以被多個進程同時打開,那麼對於每個進程來說,操作這個文件是非同步的,所以這個三個欄位就很重要了。
第二:對於引用計數f_count,當我們關閉一個進程的某一個文件描述符時候,其實並不是真正的關閉文件,僅僅是將f_count減一,當f_count=0時候,才會真的去關閉它。對於dup,fork這些操作來說,都會使得f_count增加,具體的細節,以後再說。
第三:f_op也是很重要的!是涉及到所有的文件的操作結構體。例如:用戶使用read,最終都會調用file_operations中的讀操作,而file_operations結構體是對於不同的文件系統不一定相同。裡面一個重要的操作函數式release函數,當用戶執行close時候,其實在內核中是執行release函數,這個函數僅僅將f_count減一,這也就解釋了上面說的,用戶close一個文件其實是將f_count減一。只有引用計數減到0才關閉文件。
註意:對於“正在使用”和“未使用”的文件對象分別使用一個雙向鏈表進行管理。
註意上面的file只是對一個文件而言,對於一個進程(用戶)來說,可以同時處理多個文件,所以需要另一個結構來管理所有的files!
即:用戶打開文件表--->files_struct
172 struct files_struct { 173 atomic_t count; 174 rwlock_t file_lock; /* Protects all the below members. Nests inside tsk->alloc_lock */ 175 int max_fds; 176 int max_fdset; 177 int next_fd; 178 struct file ** fd; /* current fd array */ 179 fd_set *close_on_exec; 180 fd_set *open_fds; 181 fd_set close_on_exec_init; 182 fd_set open_fds_init; 183 struct file * fd_array[NR_OPEN_DEFAULT]; 184 };
解釋一些欄位:
count:引用計數
file_lock:鎖,保護下麵的欄位
max_fds:當前文件對象的最大的數量
max_fdset:文件描述符最大數
next_fd:已分配的最大的文件描述符+1
fd:指向文件對象指針數組的指針,一般就是指向最後一個欄位fd_arrray,當文件數超過NR_OPEN_DEFAULT時候,就會重新分配一個數組,然後指向這個新的數組指針!
close_on_exec:執行exec()時候需要關閉的文件描述符
open_fds:指向打開的文件描述符的指針
close_on_exec_init:執行exec()時候需要關閉的文件描述符初始化值
open_fds_init:文件描述符初值集合
fd_array:文件對象指針的初始化數組
註意上面的file和files_struct記錄的是與進程相關的文件的信息,但是對於進程本身來說,自身的一些信息用什麼表示,這裡就涉及到fs_struct結構體。
5 struct fs_struct { 6 atomic_t count; 7 rwlock_t lock; 8 int umask; 9 struct dentry * root, * pwd, * altroot; 10 struct vfsmount * rootmnt, * pwdmnt, * altrootmnt; 11 };
解釋一些欄位:
count:引用計數
lock:保護鎖
umask:打開文件時候預設的文件訪問許可權
root:進程的根目錄
pwd:進程當前的執行目錄
altroot:用戶設置的替換根目錄
註意:實際運行時,這三個目錄不一定都在同一個文件系統中。例如,進程的根目錄通常是安裝於“/”節點上的ext文件系統,而當前工作目錄可能是安裝於/etc的一個文件系統,替換根目錄也可以不同文件系統中。
rootmnt,pwdmnt,altrootmnt:對應於上面三個的安裝點。