VFS四大對象之四-struct file


繼上一篇文章:

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:對應於上面三個的安裝點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM