0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

介紹虛擬文件系統(tǒng)的原理與實(shí)現(xiàn)

Linux愛好者 ? 來(lái)源:Linux內(nèi)核那些事 ? 2023-02-02 10:01 ? 次閱讀

在 Unix 的世界里,有句很經(jīng)典的話:一切對(duì)象皆是文件。這句話的意思是說,可以將 Unix 操作系統(tǒng)中所有的對(duì)象都當(dāng)成文件,然后使用操作文件的接口來(lái)操作它們。Linux 作為一個(gè)類 Unix 操作系統(tǒng),也努力實(shí)現(xiàn)這個(gè)目標(biāo)。

虛擬文件系統(tǒng)簡(jiǎn)介

為了實(shí)現(xiàn)一切對(duì)象皆是文件這個(gè)目標(biāo),Linux 內(nèi)核提供了一個(gè)中間層:虛擬文件系統(tǒng)(Virtual File System)。

如果大家使用過面向?qū)ο?a target="_blank">編程語(yǔ)言(如C++/Java等)的話,應(yīng)該對(duì)接口這個(gè)概念并不陌生。而虛擬文件系統(tǒng)類似于面向?qū)ο笾械慕涌冢x了一套標(biāo)準(zhǔn)的接口。開發(fā)者只需要實(shí)現(xiàn)這套接口,即可以使用操作文件的接口來(lái)操作對(duì)象。如下圖所示:

88541544-a233-11ed-bfe3-dac502259ad0.jpg

上圖中的藍(lán)色部分就是虛擬文件系統(tǒng)所在位置。

從上圖可以看出,虛擬文件系統(tǒng)為上層應(yīng)用提供了統(tǒng)一的接口。如果某個(gè)文件系統(tǒng)實(shí)現(xiàn)了虛擬文件系統(tǒng)的接口,那么上層應(yīng)用就能夠使用諸如open()、read()和write()等函數(shù)來(lái)操作它們。

今天,我們就來(lái)介紹虛擬文件系統(tǒng)的原理與實(shí)現(xiàn)。

虛擬文件系統(tǒng)原理

在闡述虛擬文件系統(tǒng)的原理前,我們先來(lái)介紹一個(gè) Java 例子。通過這個(gè) Java 例子,我們能夠更容易理解虛擬文件系統(tǒng)的原理。

一個(gè)Java例子

如果大家使用過 Java 編寫程序的話,那么就很容易理解虛擬文件系統(tǒng)了。我們使用 Java 的接口來(lái)模擬虛擬文件系統(tǒng)的定義:

publicinterfaceVFSFile{
intopen(Stringfile,intmode);
intread(intfd,byte[]buffer,intsize);
intwrite(intfd,byte[]buffer,intsize);
...
}

上面定義了一個(gè)名為VFSFile的接口,接口中定義了一些方法,如open()、read()和write()等?,F(xiàn)在我們來(lái)定義一個(gè)名為Ext3File的對(duì)象來(lái)實(shí)現(xiàn)這個(gè)接口:

publicclassExt3FileimplementsVFSFile{
@Override
publicintopen(Stringfile,intmode){
...
}

@Override
publicintread(intfd,byte[]buffer,intsize){
...
}

@Override
publicintwrite(intfd,byte[]buffer,intsize){
...
}

...
}

現(xiàn)在我們就能使用VFSFile接口來(lái)操作Ext3File對(duì)象了,如下代碼:

publicclassMain(){
publicstaticvoidmain(String[]args){
VFSFilefile=newExt3File();

intfd=file.open("/tmp/file.txt",0);
...
}
}

從上面的例子可以看出,底層對(duì)象只需要實(shí)現(xiàn)VFSFile接口,就可以使用VFSFile接口相關(guān)的方法來(lái)操作對(duì)象,用戶完全不需要了解底層對(duì)象的實(shí)現(xiàn)過程。

虛擬文件系統(tǒng)原理

上面的 Java 例子已經(jīng)大概說明虛擬文件系統(tǒng)的原理,但由于 Linux 是使用 C 語(yǔ)言來(lái)編寫的,而 C 語(yǔ)言并沒有接口這個(gè)概念。所以,Linux 內(nèi)核使用了一些技巧來(lái)模擬接口這個(gè)概念。

下面來(lái)介紹一下 Linux 內(nèi)核是如何實(shí)現(xiàn)的。

1. file結(jié)構(gòu)

為了模擬接口,Linux 內(nèi)核定義了一個(gè)名為file的結(jié)構(gòu)體,其定義如下:

structfile{
...
conststructfile_operations*f_op;
...
};

在 file 結(jié)構(gòu)中,最為重要的一個(gè)字段就是f_op,其類型為file_operations結(jié)構(gòu)。而file_operations結(jié)構(gòu)是由一組函數(shù)指針組成,其定義如下:

structfile_operations{
...
loff_t(*llseek)(structfile*,loff_t,int);
ssize_t(*read)(structfile*,char__user*,size_t,loff_t*);
ssize_t(*write)(structfile*,constchar__user*,size_t,loff_t*);
...
int(*open)(structinode*,structfile*);
...
};

從file_operations結(jié)構(gòu)的定義可以隱約看到接口的影子,所以可以猜想出,如果實(shí)現(xiàn)了file_operations結(jié)構(gòu)中的方法,應(yīng)該就能接入到虛擬文件系統(tǒng)中。

在 Linux 內(nèi)核中,file結(jié)構(gòu)代表著一個(gè)被打開的文件。所以,只需要將file結(jié)構(gòu)的f_op字段設(shè)置成不同文件系統(tǒng)實(shí)現(xiàn)好的方法集,那么就能夠使用不同文件系統(tǒng)的功能。

這個(gè)過程在__dentry_open()函數(shù)中實(shí)現(xiàn),如下所示:

staticstructfile*
__dentry_open(structdentry*dentry,
structvfsmount*mnt,
tructfile*f,
int(*open)(structinode*,structfile*),
conststructcred*cred)
{
...
inode=dentry->d_inode;
...
//設(shè)置file結(jié)構(gòu)的f_op字段為底層文件系統(tǒng)實(shí)現(xiàn)的方法集
f->f_op=fops_get(inode->i_fop);
...
returnf;
}

設(shè)置好file結(jié)構(gòu)的f_op字段后,虛擬文件系統(tǒng)就能夠使用通用的接口來(lái)操作此文件了。調(diào)用過程如下:

8863a5cc-a233-11ed-bfe3-dac502259ad0.png

2. file_operations結(jié)構(gòu)

底層文件系統(tǒng)需要實(shí)現(xiàn)虛擬文件系統(tǒng)的接口,才能被虛擬文件系統(tǒng)使用。也就是說,底層文件系統(tǒng)需要實(shí)現(xiàn)file_operations結(jié)構(gòu)中的方法集。

一般底層文件系統(tǒng)會(huì)在其內(nèi)部定義好file_operations結(jié)構(gòu),并且填充好其方法集中的函數(shù)指針。如minix文件系統(tǒng)就定義了一個(gè)名為minix_file_operations的file_operations結(jié)構(gòu)。其定義如下:

//文件:fs/minix/file.c

conststructfile_operationsminix_file_operations={
.llseek=generic_file_llseek,
.read=do_sync_read,
.aio_read=generic_file_aio_read,
.write=do_sync_write,
.aio_write=generic_file_aio_write,
.mmap=generic_file_mmap,
.fsync=generic_file_fsync,
.splice_read=generic_file_splice_read,
};

也就是說,如果當(dāng)前使用的是 minix 文件系統(tǒng),當(dāng)使用read()函數(shù)讀取其文件的內(nèi)容時(shí),那么最終將會(huì)調(diào)用do_sync_read()函數(shù)來(lái)讀取文件的內(nèi)容。

3. dentry結(jié)構(gòu)

到這里,虛擬文件系統(tǒng)的原理基本分析完畢,但還有兩個(gè)非常重要的結(jié)構(gòu)要介紹一下的:dentry和inode。

dentry結(jié)構(gòu)表示一個(gè)打開的目錄項(xiàng),當(dāng)我們打開文件/usr/local/lib/libc.so文件時(shí),內(nèi)核會(huì)為文件路徑中的每個(gè)目錄創(chuàng)建一個(gè)dentry結(jié)構(gòu)。如下圖所示:

887c2a02-a233-11ed-bfe3-dac502259ad0.png

可以看到,file結(jié)構(gòu)有個(gè)指向dentry結(jié)構(gòu)的指針,如下所示:

structfile{
...
structpathf_path;
...
conststructfile_operations*f_op;
...
};

structpath{
...
structdentry*dentry;
};

與文件類似,目錄也有相關(guān)的操作接口,所以在dentry結(jié)構(gòu)中也有操作方法集,如下所示:

structdentry{
...
structdentry*d_parent;//父目錄指針
structqstrd_name;//目錄名字
structinode*d_inode;//指向inode結(jié)構(gòu)
...
conststructdentry_operations*d_op;//操作方法集
...
};

其中的d_op字段就是目錄的操作方法集。

內(nèi)核在打開文件時(shí),會(huì)為路徑中的每個(gè)目錄創(chuàng)建一個(gè)dentry結(jié)構(gòu),并且使用d_parent字段來(lái)指向其父目錄項(xiàng),這樣就能通過d_parent字段來(lái)追索到根目錄。

4. inode結(jié)構(gòu)

在 Linux 內(nèi)核中,inode結(jié)構(gòu)表示一個(gè)真實(shí)的文件。為什么有了dentry結(jié)構(gòu)還需要inode結(jié)構(gòu)呢?這是因?yàn)?Linux 存在硬鏈接的概念。

例如使用以下命令為/usr/local/lib/libc.so文件創(chuàng)建一個(gè)硬鏈接:

ln/usr/local/lib/libc.so/tmp/libc.so

現(xiàn)在/usr/local/lib/libc.so和/tmp/libc.so指向同一個(gè)文件,但它們的路徑是不一樣的。所以,就需要引入inode結(jié)構(gòu)了。如下圖所示:

888c689a-a233-11ed-bfe3-dac502259ad0.png

由于/usr/local/lib/libc.so和/tmp/libc.so指向同一個(gè)文件,所以它們都使用同一個(gè)inode對(duì)象。

inode 結(jié)構(gòu)保存了文件的所有屬性值,如文件的創(chuàng)建時(shí)間、文件所屬用戶和文件的大小等。其定義如下所示:

structinode{
...
uid_ti_uid;//文件所屬用戶
gid_ti_gid;//文件所屬組
...
structtimespeci_atime;//最后訪問時(shí)間
structtimespeci_mtime;//最后修改時(shí)間
structtimespeci_ctime;//文件創(chuàng)建時(shí)間
...
unsignedshorti_bytes;//文件大小
...
conststructfile_operations*i_fop;//文件操作方法集(用于設(shè)置file結(jié)構(gòu))
...
};

我們注意到 inode 結(jié)構(gòu)有個(gè)類型為file_operations結(jié)構(gòu)的字段i_fop,這個(gè)字段保存了文件的操作方法集。當(dāng)用戶調(diào)用open()系統(tǒng)調(diào)用打開文件時(shí),內(nèi)核將會(huì)使用inode結(jié)構(gòu)的i_fop字段賦值給file結(jié)構(gòu)的f_op字段。我們?cè)賮?lái)重溫下賦值過程:

staticstructfile*
__dentry_open(structdentry*dentry,
structvfsmount*mnt,
tructfile*f,
int(*open)(structinode*,structfile*),
conststructcred*cred)
{
...
//文件對(duì)應(yīng)的inode對(duì)象
inode=dentry->d_inode;
...
//使用inode結(jié)構(gòu)的i_fop字段賦值給file結(jié)構(gòu)的f_op字段
f->f_op=fops_get(inode->i_fop);
...
returnf;
}

總結(jié)

本文主要介紹了虛擬文件系統(tǒng)的基本原理,從分析中可以發(fā)現(xiàn),虛擬文件系統(tǒng)使用了類似于面向?qū)ο缶幊陶Z(yǔ)言中的接口概念。正是有了虛擬文件系統(tǒng),Linux 才能支持各種各樣的文件系統(tǒng)。







審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2952

    瀏覽量

    104489
  • UNIX操作系統(tǒng)
    +關(guān)注

    關(guān)注

    0

    文章

    13

    瀏覽量

    15292
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7595

    瀏覽量

    135871
  • LINUX內(nèi)核
    +關(guān)注

    關(guān)注

    1

    文章

    316

    瀏覽量

    21608

原文標(biāo)題:細(xì)說 Linux 虛擬文件系統(tǒng)原理

文章出處:【微信號(hào):LinuxHub,微信公眾號(hào):Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Linux平臺(tái)/proc虛擬文件系統(tǒng)詳解

    Linux 內(nèi)核提供了一種通過 /proc 文件系統(tǒng),在運(yùn)行時(shí)訪問內(nèi)核內(nèi)部數(shù)據(jù)結(jié)構(gòu)、改變內(nèi)核設(shè)置的機(jī)制。proc文件系統(tǒng)是一個(gè)偽文件系統(tǒng)(即虛擬文件系統(tǒng)),它只存在內(nèi)存當(dāng)中,而不占用外
    發(fā)表于 06-08 10:49 ?1426次閱讀
    Linux平臺(tái)/proc<b class='flag-5'>虛擬文件系統(tǒng)</b>詳解

    Linux虛擬文件系統(tǒng)的基礎(chǔ)知識(shí)

    虛擬文件系統(tǒng)是一個(gè)很龐大的架構(gòu),如果要分析的面面俱到,會(huì)顯得特別復(fù)雜而笨拙,讓人看著看著,就不知所云了(當(dāng)然主要還是筆者太菜),所以這篇博客,以 open() 函數(shù)為切入點(diǎn),來(lái)試著分析分析VFS文件系統(tǒng)的運(yùn)轉(zhuǎn)機(jī)理,本文的代碼來(lái)源于 linux3.4.2。
    發(fā)表于 08-25 12:17 ?318次閱讀
    Linux<b class='flag-5'>虛擬文件系統(tǒng)</b>的基礎(chǔ)知識(shí)

    STM32F429 sdio虛擬文件系統(tǒng)的相關(guān)資料推薦

    SD卡虛擬文件系統(tǒng)是在我之前的SPI虛擬文件系統(tǒng)的基礎(chǔ)上做的,所以只會(huì)介紹SD卡配置部分,DFS配置跟之前的一樣就不詳細(xì)介紹了。1.添加文件
    發(fā)表于 12-13 06:02

    VFS虛擬文件系統(tǒng)描述

    1.VFS——虛擬文件系統(tǒng),是文件系統(tǒng)對(duì)外的接口2.cache——高速緩沖存儲(chǔ)器3.linux的每個(gè)文件都是由 i 節(jié)點(diǎn)的結(jié)構(gòu)體表示,i 節(jié)點(diǎn)包含對(duì)文件的描述:
    發(fā)表于 12-22 06:56

    Linux虛擬文件系統(tǒng)實(shí)現(xiàn)技術(shù)探討

    文章論述了 Linux 文件系統(tǒng)的邏輯關(guān)系和邏輯結(jié)構(gòu),對(duì)VFS 中幾個(gè)主要的數(shù)據(jù)結(jié)構(gòu)進(jìn)行了分析,剖析了Linux 文件系統(tǒng) 中一個(gè)物理文件系統(tǒng)的安裝與注冊(cè)、VFS的產(chǎn)生,以及通過VFS管理和訪問
    發(fā)表于 06-08 17:51 ?32次下載
    Linux<b class='flag-5'>虛擬文件系統(tǒng)</b><b class='flag-5'>實(shí)現(xiàn)</b>技術(shù)探討

    玩轉(zhuǎn)Linux,先把文件系統(tǒng)搞懂

    引入了虛擬文件系統(tǒng) VFS(Virtual File System) ,為各類文件系統(tǒng)提供一個(gè)統(tǒng)一的操作界面和應(yīng)用編程接口。
    發(fā)表于 08-16 10:50 ?2058次閱讀
    玩轉(zhuǎn)Linux,先把<b class='flag-5'>文件系統(tǒng)</b>搞懂

    Xilinx Zynq制作修改根文件系統(tǒng)的方法

    proc文件系統(tǒng)是用來(lái)提供內(nèi)核和進(jìn)程信息的虛擬文件系統(tǒng),使用內(nèi)核自動(dòng)生成的文件,加載完成一定要能查到很多信息才對(duì)。
    發(fā)表于 07-13 08:31 ?3509次閱讀

    linux 虛擬文件可以系統(tǒng)實(shí)現(xiàn)

    虛擬文件系統(tǒng)(VFS)是linux內(nèi)核和具體I/O設(shè)備之間的封裝的一層共通訪問接口,通過這層接口,linux內(nèi)核可以以同一的方式訪問各種I/O設(shè)備。
    發(fā)表于 05-04 16:56 ?485次閱讀
    linux <b class='flag-5'>虛擬文件</b>可以<b class='flag-5'>系統(tǒng)</b><b class='flag-5'>實(shí)現(xiàn)</b>

    嵌入式Linux常用文件系統(tǒng)

    Linux支持很多文件系統(tǒng),在選擇時(shí)應(yīng)根據(jù)應(yīng)用的功能選擇文件系統(tǒng) 內(nèi)核只認(rèn)識(shí)VFS(虛擬文件系統(tǒng)),不同的文件系統(tǒng)實(shí)現(xiàn)的都是和VFS的
    發(fā)表于 05-04 17:19 ?2365次閱讀
    嵌入式Linux常用<b class='flag-5'>文件系統(tǒng)</b>

    簡(jiǎn)單介紹Linux虛擬文件系統(tǒng)–VFS

    Linux中可以支持多種文件系統(tǒng),而且支持各種文件系統(tǒng)之間相互訪問,這是因?yàn)橛幸粋€(gè)虛擬文件系統(tǒng)。虛擬文件系統(tǒng)也叫虛擬文件系統(tǒng)轉(zhuǎn)換(Virtu
    發(fā)表于 04-24 14:35 ?1323次閱讀

    嵌入式Linux文件系統(tǒng)詳細(xì)介紹

    Linux支持多種文件系統(tǒng),包括ext2、ext3、vfat、ntfs、iso9660、jffs、romfs和nfs等,為了對(duì)各類文件系統(tǒng)進(jìn)行統(tǒng)一管理,Linux引入了虛擬文件系統(tǒng)VFS(Virtual File System)
    發(fā)表于 04-27 19:23 ?3857次閱讀
    嵌入式Linux<b class='flag-5'>文件系統(tǒng)</b>詳細(xì)<b class='flag-5'>介紹</b>

    linux文件系統(tǒng)中的虛擬文件系統(tǒng)設(shè)計(jì)詳解

    Linux 中允許眾多不同的文件系統(tǒng)共存,如 ext2, ext3, vfat 等。通過使用同一套文件 I/O 系統(tǒng) 調(diào)用即可對(duì) Linux 中的任意文件進(jìn)行操作而無(wú)需考慮其所在的具體
    發(fā)表于 04-02 14:37 ?1786次閱讀
    linux<b class='flag-5'>文件系統(tǒng)</b>中的<b class='flag-5'>虛擬文件系統(tǒng)</b>設(shè)計(jì)詳解

    如何區(qū)別Linux文件系統(tǒng)呢?

    虛擬文件系統(tǒng)是一種神奇的抽象,它使得 “一切皆文件” 哲學(xué)在 Linux 中成為了可能。
    的頭像 發(fā)表于 08-09 18:00 ?3660次閱讀

    深入剖析Linux內(nèi)核虛擬文件系統(tǒng)

    虛擬文件系統(tǒng)(Virtual File System,簡(jiǎn)稱VFS)是Linux內(nèi)核的子系統(tǒng)之一,它為用戶程序提供文件文件系統(tǒng)操作的統(tǒng)一接口,屏蔽不同
    的頭像 發(fā)表于 05-14 15:53 ?3027次閱讀
    深入剖析Linux內(nèi)核<b class='flag-5'>虛擬文件系統(tǒng)</b>

    RT-Thread文檔_虛擬文件系統(tǒng)

    RT-Thread文檔_虛擬文件系統(tǒng)
    發(fā)表于 02-22 18:42 ?1次下載
    RT-Thread文檔_<b class='flag-5'>虛擬文件系統(tǒng)</b>