檔案描述符
定義
在Linux系統中,當我們開啟或者建立一個檔案時,系統會提供一個檔案描述符作為該檔案的“代號”,我們可以透過使用這個“代號”來對原檔案進行一系列的讀寫操作。
在Linux中,檔案描述符0、1、2是有特殊含義的。
0是標準輸入(stdin)的檔案描述符
1是標準輸出(stdout)的檔案描述符
2是標準錯誤(stderr)的檔案描述符
檔案描述符關聯的資料結構
struct file
每個檔案描述符都關聯到核心一個 struct file 型別的結構體資料。struct file的結構體定義如下:
struct file {
......
atomic_long_t f_count; // 引用計數,管理檔案物件的生命週期
struct mutex f_pos_lock; // 保護檔案位置的互斥鎖
loff_t f_pos; // 當前檔案位置(讀寫位置)
......
struct path f_path; // 記錄檔案路徑
struct inode *f_inode; // 指向與檔案相關聯的 inode 物件的指標,該物件用於維護檔案後設資料,如檔案型別、訪問許可權等
const struct file_operations *f_op; // 指向檔案操作函式表的指標,定義了檔案支援的操作,如讀、寫、鎖定等
......
void *private_data; // 儲存特定驅動或模組的私有資料
......
}
這個資料結構記錄了與檔案相關的所有資訊,其中比較關鍵的是 f_path 記錄了檔案的路徑資訊,f_inode記錄了檔案的後設資料。
f_count的作用是管理檔案的開啟與關閉。檔案IO中的open和close並不能真正的開啟和關閉檔案。事實上,open和close都是使f_count做加減操作,每當有程式執行open時,f_count+1;每當有程式執行close時,f_count-1。只有當f_count值為0時,檔案描述符才真正被關閉。
struct path
struct path {
struct vfsmount *mnt;
struct dentry *dentry;
}
struct vfsmount:是虛擬檔案系統掛載點的表示,儲存有關掛載檔案系統的資訊。
struct dentry:目錄項結構體,代表了檔案系統中的一個目錄項。目錄項是檔案系 統中的一個實體,通常對應一個檔案或目錄的名字。透過這個型別的屬性,可以定位檔案 位置。
struct inode
struct inode {
umode_t i_mode; // 檔案型別和許可權。這個欄位指定了檔案是普通檔案、目錄、字元裝置、塊裝置等,以及它的訪問許可權(讀、寫、執行)。
unsigned short i_opflags;
kuid_t i_uid; // 檔案的使用者 ID,決定了檔案的擁有者。
kgid_t i_gid; // 檔案的組 ID,決定了檔案的擁有者組。
unsigned int i_flags;
......
unsigned long i_ino; // inode 編號,是檔案系統中檔案的唯一標識。
......
loff_t i_size; // 檔案大小
}
檔案描述符表關聯的資料結構
struct files_struct {
......
struct fdtable __rcu *fdt; // 指向當前使用的檔案描述符表(fdtable)
......
unsigned int next_fd; // 儲存下一個可用的最小檔案描述符編號
......
struct file __rcu *fd_array[NR_OPEN_DEFAULT]; // struct file 指標的陣列,大小固定,用於快速訪問。
}
fdt維護了檔案描述符表,其中記錄了所有開啟的檔案描述符和 struct file的對應關係。
struct fdtable {
unsigned int max_fds; // 檔案描述符陣列的容量,即可用的最大檔案描述符
struct file __rcu **fd; // 指向 struct file 指標陣列的指標
unsigned long *close_on_exec;
unsigned long *open_fds;
unsigned long *full_fds_bits;
struct rcu_head rcu;
}