日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux系统篇-文件系统虚拟文件系统

發(fā)布時(shí)間:2025/6/15 linux 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux系统篇-文件系统虚拟文件系统 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

看了之前的關(guān)于Linux內(nèi)存管理和進(jìn)程調(diào)度的文章,相比讀者們應(yīng)該對(duì)Linux有了大致的了解,本文的主題是Linux虛擬文件系統(tǒng)。閑話少說,開始!

1.軟鏈接和硬鏈接的區(qū)別

我們知道文件都有文件名與數(shù)據(jù),數(shù)據(jù)分兩部分:用戶數(shù)據(jù) (user data) 與元數(shù)據(jù) (metadata)。用戶數(shù)據(jù),即文件數(shù)據(jù)塊 (data block),數(shù)據(jù)塊是記錄文件真實(shí)內(nèi)容的地方;而元數(shù)據(jù)則是文件的附加屬性,如文件大小、創(chuàng)建時(shí)間、所有者等信息。在 Linux 中,元數(shù)據(jù)中的 inode 號(hào)(inode 是文件元數(shù)據(jù)的一部分但其并不包含文件名,inode 號(hào)即索引節(jié)點(diǎn)號(hào))才是文件的唯一標(biāo)識(shí)而非文件名。文件名僅是為了方便人們的記憶和使用,系統(tǒng)或程序通過 inode 號(hào)尋找正確的文件數(shù)據(jù)塊

為解決文件的共享使用,Linux 系統(tǒng)引入了兩種鏈接:硬鏈接 (hard link) 與軟鏈接(又稱符號(hào)鏈接,即 soft link 或 symbolic link)。鏈接為 Linux 系統(tǒng)解決了文件的共享使用,還帶來了隱藏文件路徑、增加權(quán)限安全及節(jié)省存儲(chǔ)等好處。若一個(gè) inode 號(hào)對(duì)應(yīng)多個(gè)文件名,則稱這些文件為硬鏈接。硬鏈接就是同一個(gè)文件使用了多個(gè)別名

由于硬鏈接是有著相同 inode 號(hào)僅文件名不同的文件,因此硬鏈接存在以下幾點(diǎn)特性:

  • 文件有相同的 inode 及 data block;
  • 只能對(duì)已存在的文件進(jìn)行創(chuàng)建;
  • 不能交叉文件系統(tǒng)進(jìn)行硬鏈接的創(chuàng)建;
  • 不能對(duì)目錄進(jìn)行創(chuàng)建,只可對(duì)文件創(chuàng)建;
  • 刪除一個(gè)硬鏈接文件并不影響其他有相同 inode 號(hào)的文件。

inode 號(hào)僅在各文件系統(tǒng)下是唯一的,當(dāng) Linux 掛載多個(gè)文件系統(tǒng)后將出現(xiàn) inode 號(hào)重復(fù)的現(xiàn)象,因此硬鏈接創(chuàng)建時(shí)不可跨文件系統(tǒng)

軟鏈接與硬鏈接不同,若文件用戶數(shù)據(jù)塊中存放的內(nèi)容是另一文件的路徑名的指向,則該文件就是軟連接。軟鏈接就是一個(gè)普通文件,只是數(shù)據(jù)塊內(nèi)容有點(diǎn)特殊。軟鏈接有著自己的 inode 號(hào)以及用戶數(shù)據(jù)塊。因此軟鏈接的創(chuàng)建與使用沒有類似硬鏈接的諸多限制:

  • 軟鏈接有自己的文件屬性及權(quán)限等;
  • 可對(duì)不存在的文件或目錄創(chuàng)建軟鏈接;
  • 軟鏈接可交叉文件系統(tǒng);
  • 軟鏈接可對(duì)文件或目錄創(chuàng)建;
  • 創(chuàng)建軟鏈接時(shí),鏈接計(jì)數(shù) i_nlink 不會(huì)增加;
  • 刪除軟鏈接并不影響被指向的文件,但若被指向的原文件被刪除,則相關(guān)軟連接被稱為死鏈接(即 dangling link,若被指向路徑文件被重新創(chuàng)建,死鏈接可恢復(fù)為正常的軟鏈接)。
  • 一般情況下,文件名和inode號(hào)碼是"一一對(duì)應(yīng)"關(guān)系,每個(gè)inode號(hào)碼對(duì)應(yīng)一個(gè)文件名。但是,Unix/Linux系統(tǒng)允許,多個(gè)文件名指向同一個(gè)inode號(hào)碼。這意味著,可以用不同的文件名訪問同樣的內(nèi)容;對(duì)文件內(nèi)容進(jìn)行修改,會(huì)影響到所有文件名;但是,刪除一個(gè)文件名,不影響另一個(gè)文件名的訪問。這種情況就被稱為"硬鏈接"(hard link)。

2.Linux VFS

Linux 有著極其豐富的文件系統(tǒng),大體上可分如下幾類:

  • 網(wǎng)絡(luò)文件系統(tǒng),如 nfs、cifs 等;
  • 磁盤文件系統(tǒng),如 ext4、ext3 等;
  • 特殊文件系統(tǒng),如 proc、sysfs、ramfs、tmpfs 等。
  • 實(shí)現(xiàn)以上這些文件系統(tǒng)并在 Linux 下共存的基礎(chǔ)就是 Linux VFS(Virtual File System 又稱 Virtual Filesystem Switch),即虛擬文件系統(tǒng)。VFS 作為一個(gè)通用的文件系統(tǒng),抽象了文件系統(tǒng)的四個(gè)基本概念:文件、目錄項(xiàng) (dentry)、索引節(jié)點(diǎn) (inode) 及掛載點(diǎn),其在內(nèi)核中為用戶空間層的文件系統(tǒng)提供了相關(guān)的接口。VFS 實(shí)現(xiàn)了 open()、read() 等系統(tǒng)調(diào)并使得 cp 等用戶空間程序可跨文件系統(tǒng)。VFS 真正實(shí)現(xiàn)了上述內(nèi)容中:在 Linux 中除進(jìn)程之外一切皆是文件。

    Linux VFS 存在四個(gè)基本對(duì)象:超級(jí)塊對(duì)象 (superblock object)、索引節(jié)點(diǎn)對(duì)象 (inode object)、目錄項(xiàng)對(duì)象 (dentry object) 及文件對(duì)象 (file object)。超級(jí)塊對(duì)象代表一個(gè)已安裝的文件系統(tǒng);索引節(jié)點(diǎn)對(duì)象代表一個(gè)文件;目錄項(xiàng)對(duì)象代表一個(gè)目錄項(xiàng),如設(shè)備文件 event5 在路徑 /dev/input/event5 中,其存在四個(gè)目錄項(xiàng)對(duì)象:/ 、dev/ 、input/ 及 event5。文件對(duì)象代表由進(jìn)程打開的文件。為文件路徑的快速解析,Linux VFS 設(shè)計(jì)了目錄項(xiàng)緩存(Directory Entry Cache,即 dcache)。

    3.文件的打開過程

    open()系統(tǒng)調(diào)用的過程如下:

    1.查看system-wide open-file table(系統(tǒng)打開文件表)中是否有該文件,即查看該文件是否已經(jīng)被其他進(jìn)程打開了

    2.如果存在,那么該進(jìn)程會(huì)在自己的per-process open-file table(進(jìn)程打開文件表)中,建立一個(gè)項(xiàng)目,指向system-wide open-file table中的該文件

    3.如果不存在,則需要根據(jù)file name在directory中查找該file,通常directory中的部分內(nèi)容在cache中,這樣可以加快搜索速度。

    4.一旦文件被找到,那么FCB(file control block)文件控制塊會(huì)被復(fù)制到system-wide open-file table中,該表不僅僅保存FCB,而且記錄每個(gè)文件被多少個(gè)進(jìn)程打開

    5.接下來,在per-process open-file table(進(jìn)程打開文件表)中,簡(jiǎn)直一個(gè)entry,指向進(jìn)程打開文件表中該項(xiàng)目

    當(dāng)進(jìn)程close()一個(gè)文件時(shí):

    1.該進(jìn)程的per-process open-flle table中的對(duì)應(yīng)項(xiàng)會(huì)被刪除,系統(tǒng)打開表中的該文件計(jì)數(shù)器會(huì)減1

    2.如果系統(tǒng)打開表中的計(jì)算為0,那么刪除該文件項(xiàng)

    4.inode的理解

    操作系統(tǒng)讀取硬盤的時(shí)候,不會(huì)一個(gè)個(gè)扇區(qū)地讀取,這樣效率太低,而是一次性連續(xù)讀取多個(gè)扇區(qū),即一次性讀取一個(gè)"塊"(block)。這種由多個(gè)扇區(qū)組成的"塊",是文件存取的最小單位。"塊"的大小,最常見的是4KB,即連續(xù)八個(gè) sector組成一個(gè) block。

    文件數(shù)據(jù)都儲(chǔ)存在"塊"中,那么很顯然,我們還必須找到一個(gè)地方儲(chǔ)存文件的元信息,比如文件的創(chuàng)建者、文件的創(chuàng)建日期、文件的大小等等。這種儲(chǔ)存文件元信息的區(qū)域就叫做inode,中文譯名為"索引節(jié)點(diǎn)"。

    inode包含文件的元信息,具體來說有以下內(nèi)容:

    * 文件的字節(jié)數(shù)

    * 文件擁有者的User ID

    * 文件的Group ID

    * 文件的讀、寫、執(zhí)行權(quán)限

    * 文件的時(shí)間戳,共有三個(gè):ctime指inode上一次變動(dòng)的時(shí)間,mtime指文件內(nèi)容上一次變動(dòng)的時(shí)間,atime指文件上一次打開的時(shí)間。

    * 鏈接數(shù),即有多少文件名指向這個(gè)inode

    * 文件數(shù)據(jù)block的位置

    除了文件名以外的所有文件信息,都存在inode之中

    每個(gè)inode都有一個(gè)號(hào)碼,操作系統(tǒng)用inode號(hào)碼來識(shí)別不同的文件。

    表面上,用戶通過文件名,打開文件。實(shí)際上,系統(tǒng)內(nèi)部這個(gè)過程分成三步:首先,系統(tǒng)找到這個(gè)文件名對(duì)應(yīng)的inode號(hào);其次,通過inode號(hào),獲取inode信息;最后,根據(jù)inode信息,找到文件數(shù)據(jù)所在的block,讀出數(shù)據(jù)。

    目錄(directory)也是一種文件,目錄文件的結(jié)構(gòu)非常簡(jiǎn)單,就是一系列目錄項(xiàng)(dirent)的列表。每個(gè)目錄項(xiàng),由兩部分組成:所包含文件的文件名,以及該文件名對(duì)應(yīng)的inode號(hào)碼。

    數(shù)據(jù)塊尋址

    inode中記錄了文件數(shù)據(jù)塊的位置,有三種尋址方式:direct blocks直接指向數(shù)據(jù)塊;single indirect指向一個(gè)block,該block中為數(shù)據(jù)塊的指針;double indirect,兩級(jí)block

    Linux系統(tǒng)篇-文件系統(tǒng)&虛擬文件系統(tǒng)(非常重要!)

    5.文件描述符

    在Linux系統(tǒng)中一切皆可以看成是文件,文件又可分為:普通文件、目錄文件、鏈接文件和設(shè)備文件。文件描述符(file descriptor)是內(nèi)核為了高效管理已被打開的文件所創(chuàng)建的索引,其是一個(gè)非負(fù)整數(shù)(通常是小整數(shù)),用于指代被打開的文件,所有執(zhí)行I/O操作的系統(tǒng)調(diào)用都通過文件描述符。程序剛剛啟動(dòng)的時(shí)候,0是標(biāo)準(zhǔn)輸入,1是標(biāo)準(zhǔn)輸出,2是標(biāo)準(zhǔn)錯(cuò)誤。如果此時(shí)去打開一個(gè)新的文件,它的文件描述符會(huì)是3。POSIX標(biāo)準(zhǔn)要求每次打開文件時(shí)(含socket)必須使用當(dāng)前進(jìn)程中最小可用的文件描述符號(hào)碼

    文件描述符是系統(tǒng)的一個(gè)重要資源,雖然說系統(tǒng)內(nèi)存有多少就可以打開多少的文件描述符,但是在實(shí)際實(shí)現(xiàn)過程中內(nèi)核是會(huì)做相應(yīng)的處理的,一般最大打開文件數(shù)會(huì)是系統(tǒng)內(nèi)存的10%(以KB來計(jì)算)(稱之為系統(tǒng)級(jí)限制)

    6.文件描述符和打開文件之間的關(guān)系

    每一個(gè)文件描述符會(huì)與一個(gè)打開文件相對(duì)應(yīng),同時(shí),不同的文件描述符也會(huì)指向同一個(gè)文件。相同的文件可以被不同的進(jìn)程打開也可以在同一個(gè)進(jìn)程中被多次打開。系統(tǒng)為每一個(gè)進(jìn)程維護(hù)了一個(gè)文件描述符表,該表的值都是從0開始的,所以在不同的進(jìn)程中你會(huì)看到相同的文件描述符,這種情況下相同文件描述符有可能指向同一個(gè)文件,也有可能指向不同的文件。具體情況要具體分析,要理解具體其概況如何,需要查看由內(nèi)核維護(hù)的3個(gè)數(shù)據(jù)結(jié)構(gòu)。

    1. 進(jìn)程級(jí)的文件描述符表

    2. 系統(tǒng)級(jí)的打開文件描述符表

    3. 文件系統(tǒng)的i-node表

    進(jìn)程級(jí)的描述符表的每一條目記錄了單個(gè)文件描述符的相關(guān)信息。

    1. 控制文件描述符操作的一組標(biāo)志。(目前,此類標(biāo)志僅定義了一個(gè),即close-on-exec標(biāo)志)

    2. 對(duì)打開文件句柄的引用

    內(nèi)核對(duì)所有打開的文件的文件維護(hù)有一個(gè)系統(tǒng)級(jí)的描述符表格(open file description table)。有時(shí),也稱之為打開文件表(open file table),并將表格中各條目稱為打開文件句柄(open file handle)。一個(gè)打開文件句柄存儲(chǔ)了與一個(gè)打開文件相關(guān)的全部信息,如下所示:

    1. 當(dāng)前文件偏移量(調(diào)用read()和write()時(shí)更新,或使用lseek()直接修改)

    2. 打開文件時(shí)所使用的狀態(tài)標(biāo)識(shí)(即,open()的flags參數(shù))

    3. 文件訪問模式(如調(diào)用open()時(shí)所設(shè)置的只讀模式、只寫模式或讀寫模式)

    4. 與信號(hào)驅(qū)動(dòng)相關(guān)的設(shè)置

    5. 對(duì)該文件i-node對(duì)象的引用

    6. 文件類型(例如:常規(guī)文件、套接字或FIFO)和訪問權(quán)限

    7. 一個(gè)指針,指向該文件所持有的鎖列表

    8. 文件的各種屬性,包括文件大小以及與不同類型操作相關(guān)的時(shí)間戳

    在進(jìn)程A中,文件描述符1和30都指向了同一個(gè)打開的文件句柄(標(biāo)號(hào)23)。這可能是通過調(diào)用dup()、dup2()、fcntl()或者對(duì)同一個(gè)文件多次調(diào)用了open()函數(shù)而形成的。

    進(jìn)程A的文件描述符2和進(jìn)程B的文件描述符2都指向了同一個(gè)打開的文件句柄(標(biāo)號(hào)73)。這種情形可能是在調(diào)用fork()后出現(xiàn)的(即,進(jìn)程A、B是父子進(jìn)程關(guān)系),或者當(dāng)某進(jìn)程通過UNIX域套接字將一個(gè)打開的文件描述符傳遞給另一個(gè)進(jìn)程時(shí),也會(huì)發(fā)生。再者是不同的進(jìn)程獨(dú)自去調(diào)用open函數(shù)打開了同一個(gè)文件,此時(shí)進(jìn)程內(nèi)部的描述符正好分配到與其他進(jìn)程打開該文件的描述符一樣。

    此外,進(jìn)程A的描述符0和進(jìn)程B的描述符3分別指向不同的打開文件句柄,但這些句柄均指向i-node表的相同條目(1976),換言之,指向同一個(gè)文件。發(fā)生這種情況是因?yàn)槊總€(gè)進(jìn)程各自對(duì)同一個(gè)文件發(fā)起了open()調(diào)用。同一個(gè)進(jìn)程兩次打開同一個(gè)文件,也會(huì)發(fā)生類似情況。

    7. 總結(jié)

    1. 由于進(jìn)程級(jí)文件描述符表的存在,不同的進(jìn)程中會(huì)出現(xiàn)相同的文件描述符,它們可能指向同一個(gè)文件,也可能指向不同的文件

    2. 兩個(gè)不同的文件描述符,若指向同一個(gè)打開文件句柄,將共享同一文件偏移量。因此,如果通過其中一個(gè)文件描述符來修改文件偏移量(由調(diào)用read()、write()或lseek()所致),那么從另一個(gè)描述符中也會(huì)觀察到變化,無論這兩個(gè)文件描述符是否屬于不同進(jìn)程,還是同一個(gè)進(jìn)程,情況都是如此。

    3. 要獲取和修改打開的文件標(biāo)志(例如:O_APPEND、O_NONBLOCK和O_ASYNC),可執(zhí)行fcntl()的F_GETFL和F_SETFL操作,其對(duì)作用域的約束與上一條頗為類似。

    4. 文件描述符標(biāo)志(即,close-on-exec)為進(jìn)程和文件描述符所私有。對(duì)這一標(biāo)志的修改將不會(huì)影響同一進(jìn)程或不同進(jìn)程中的其他文件描述符


    總結(jié)

    以上是生活随笔為你收集整理的Linux系统篇-文件系统虚拟文件系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。