在之前的探索中,我們已經掌握了文件的打開與管理機制,以及磁盤和ext2文件系統的存儲方式。
那么問題來了,當我們想要打開一個文件時,操作系統是如何找到它的呢?這背后又隱藏著怎樣的查找邏輯?
1. 目錄與文件名的秘密
文件名并不直接作為屬性保存在inode中。在一個分區內部,通過inode編號即可唯一確定一個文件。然而在日常操作中,我們總是通過文件名來訪問文件,而非使用inode編號。
那目錄是否也是一種文件呢?
查看后可以發現目錄同樣擁有自己的inode值,這說明目錄本質上也是一種文件。
既然文件 = 屬性 + 內容,那么目錄的內容究竟是什么?
答案是:目錄的內容是由一組文件名和對應的inode號構成的映射表。當我們要訪問某個文件時,必須先打開當前工作目錄,從中查找出目標文件名所對應的inode編號,才能進一步訪問該文件。
因此,訪問任何文件都離不開當前工作目錄的支持,也就是需要打開并讀取目錄文件的內容以獲取目標文件的inode信息。
2. 路徑解析過程
為了訪問當前工作目錄下的文件,我們需要先打開當前目錄,并讀取其內容。
但如何獲得當前目錄的inode編號呢?
這就需要向上查找它的父目錄,再從父目錄中查找當前目錄的inode。而要訪問父目錄,又需要知道父目錄的inode,繼續向上追溯,直到根目錄/為止。
每個進程都有一個CWD(Current Working Directory)字段記錄當前工作路徑。在調用open函數打開指定路徑的文件時,也必須提供完整的路徑信息。
因此,訪問文件的本質是通過路徑中的目錄結構逐級查找,最終定位到目標文件的inode。
3. 路徑緩存機制
雖然文件實際存儲在磁盤上,但在linux系統中,內核維護了一種樹狀結構體:Struct dentry,用于表示路徑緩存。
struct dentry { atomic_t d_count; unsigned int d_flags; spinlock_t d_lock; struct inode *d_inode; struct hlist_node d_hash; struct dentry *d_parent; struct qstr d_name; struct list_head d_lru; union { struct list_head d_child; struct rcu_head d_rcu; } d_u; struct list_head d_subdirs; struct list_head d_alias; unsigned long d_time; struct dentry_operations *d_op; struct super_block *d_sb; void *d_fsdata; #ifdef CONFIG_PROFILING struct dcookie_struct *d_cookie; #endif int d_mounted; unsigned char d_iname[DNAME_INLINE_LEN_MIN]; };
每一個文件都有對應的dentry結構,普通文件也不例外。這些dentry節點共同構成了內存中的路徑樹形結構。
該結構同時屬于LRU鏈表(最近最少使用淘汰機制)和哈希表(快速查找),使得路徑查找效率大大提高。這樣就形成了Linux的路徑緩存體系。每次訪問文件時,系統會優先在dentry樹中查找,命中則返回對應inode;未命中則從磁盤加載路徑信息并插入到緩存中。
4. 分區掛載機制
前面討論的是在同一文件系統內的文件查找。但如果涉及多個分區,僅靠inode無法跨分區識別文件。
為了解決這個問題,我們需要將不同分區上的文件系統掛載到某個目錄下,這個目錄就是“掛載點”。
一旦完成掛載,系統就可以根據路徑前綴判斷目標文件所在的分區。
軟鏈接與硬鏈接機制
1. 軟鏈接
在windows中,快捷方式是一種常見的文件引用方式。而在Linux中,軟鏈接(Symbolic Link)也具有類似功能。
創建軟鏈接命令如下:
ln -s code code.c
這條命令創建了一個名為code的軟鏈接,指向文件code.c。軟鏈接本身是一個獨立的文件。
2. 硬鏈接
在任何一個目錄中,我們都會看到.和..這兩個特殊條目。它們分別代表當前目錄和上級目錄。
實際上,它們就是典型的硬鏈接。. 指向當前目錄的inode,而..指向上一級目錄的inode。
內核中通過連接數來管理硬鏈接的數量:
創建硬鏈接的命令如下:
ln 已存在文件 硬鏈接文件
需要注意的是,硬鏈接只能針對文件創建,不能對目錄創建。
3. 軟鏈接與硬鏈接的區別
類型 | 是否獨立文件 | 是否支持跨分區 | 是否可鏈接目錄 |
---|---|---|---|
軟鏈接 | 是 | 是 | 否 |
硬鏈接 | 否(共享同一inode) | 否 | 否 |
4. 鏈接的實際用途
- 軟鏈接:相當于文件的快捷方式,便于訪問。
- 硬鏈接:如.和..的存在,方便用戶和進程導航目錄結構;也可用于文件備份。
本篇文章到這里就結束了,感謝各位讀者的關注與支持!