九色91_成人精品一区二区三区中文字幕_国产精品久久久久一区二区三区_欧美精品久久_国产精品99久久久久久久vr_www.国产视频

Hello! 歡迎來到小浪云!


細(xì)說|Linux虛擬文件系統(tǒng)原理


unix的世界里,有一句經(jīng)典的話:一切對(duì)象皆是文件。這句話的含義是,可以將unix操作系統(tǒng)中的所有對(duì)象都視為文件,并使用文件操作接口來處理它們。linux作為一個(gè)類unix操作系統(tǒng),也致力于實(shí)現(xiàn)這一理念。

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

為了實(shí)現(xiàn)“一切對(duì)象皆是文件”的理念,Linux內(nèi)核引入了一個(gè)中間層:虛擬文件系統(tǒng)(Virtual File System)。

如果你熟悉面向?qū)ο?/a>編程語言(如C++/Java等),你可能不陌生于“接口”這個(gè)概念。虛擬文件系統(tǒng)類似于面向?qū)ο?/a>中的接口,定義了一套標(biāo)準(zhǔn)的接口規(guī)范。開發(fā)者只需實(shí)現(xiàn)這套接口,就能夠通過文件操作接口來操作對(duì)象。如下圖所示:

細(xì)說|Linux虛擬文件系統(tǒng)原理

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

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

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

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

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

一個(gè)Java例子

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

public?interface?VFSFile?{ ??int?open(String?file,?int?mode); ??int?read(int?fd,?byte[]?buffer,?int?size); ??int?write(int?fd,?byte[]?buffer,?int?size); ??... } 

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

public?class?Ext3File?implements?VFSFile?{ ??@Override ??public?int?open(String?file,?int?mode)?{ ????... ??} ?? ??@Override ??public?int?read(int?fd,?byte[]?buffer,?int?size)?{ ????... ??} ?? ??@Override ??public?int?write(int?fd,?byte[]?buffer,?int?size)?{ ????... ??} ?? ??... } 

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

public?class?Main()?{ ??public?static?void?main(String[]?args)?{ ????VFSFile?file?=?new?Ext3File(); ???? ????int?fd?=?file.open("/tmp/file.txt",?0); ????... ??} } 

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

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

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

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

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

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

struct?file?{ ????... ????const?struct?file_operations?*f_op; ????... }; 

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

struct?file_operations?{ ????... ????loff_t?(*llseek)?(struct?file?*,?loff_t,?int); ????ssize_t?(*read)?(struct?file?*,?char?__user?*,?size_t,?loff_t?*); ????ssize_t?(*write)?(struct?file?*,?const?char?__user?*,?size_t,?loff_t?*); ????... ????int?(*open)?(struct?inode?*,?struct?file?*); ????... }; 

從 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),如下所示:

static?struct?file?* __dentry_open(struct?dentry?*dentry,? ??????????????struct?vfsmount?*mnt,? ??????????????truct?file?*f,? ??????????????int?(*open)(struct?inode?*,?struct?file?*),? ??????????????const?struct?cred?*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); ????... ????return?f; } 

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

細(xì)說|Linux虛擬文件系統(tǒng)原理

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  const?struct?file_operations?minix_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ù)來讀取文件的內(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)。如下圖所示:

細(xì)說|Linux虛擬文件系統(tǒng)原理

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

struct?file?{ ????... ????struct?path?f_path; ????... ????const?struct?file_operations?*f_op; ????... };  struct?path?{ ????... ????struct?dentry?*dentry; }; 

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

struct?dentry?{ ????... ????struct?dentry?*d_parent;??????????????//?父目錄指針 ????struct?qstr?d_name;???????????????????//?目錄名字 ????struct?inode?*d_inode;????????????????//?指向inode結(jié)構(gòu) ????... ????const?struct?dentry_operations?*d_op;?//?操作方法集 ????... }; 

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

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

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)了。如下圖所示:

細(xì)說|Linux虛擬文件系統(tǒng)原理

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

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

struct?inode?{ ????... ????uid_t???????????i_uid;???????????????//?文件所屬用戶 ????gid_t???????????i_gid;???????????????//?文件所屬組 ????... ????struct?timespec?i_atime;?????????????//?最后訪問時(shí)間 ????struct?timespec?i_mtime;?????????????//?最后修改時(shí)間 ????struct?timespec?i_ctime;?????????????//?文件創(chuàng)建時(shí)間 ????... ????unsigned?short??i_bytes;?????????????//?文件大小 ????... ????const?struct?file_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è)賮碇販叵沦x值過程:

static?struct?file?* __dentry_open(struct?dentry?*dentry,? ??????????????struct?vfsmount?*mnt,? ??????????????truct?file?*f,? ??????????????int?(*open)(struct?inode?*,?struct?file?*),? ??????????????const?struct?cred?*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); ????... ????return?f; } 

總結(jié)

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

相關(guān)閱讀

主站蜘蛛池模板: 国产三级精品视频 | 精品国产一区二区国模嫣然 | 亚洲精品日韩视频 | 国产精品成人品 | 草比av| 孰女乱色一区二区三区 | 国产清纯白嫩初高生在线播放视频 | 久久一热| 一级片在线播放 | 国产一级片久久久 | 免费一看一级毛片 | 国产亚洲精品美女久久久久久久久久 | 日韩欧美在线一区 | 韩国毛片一区二区三区 | 精品国产欧美一区二区三区成人 | 国产色婷婷精品综合在线播放 | 国产日韩欧美 | 日韩视频免费看 | 自拍视频在线观看 | 久久久一二三区 | 亚洲视频国产视频 | 国产一级大片 | 日韩免费一区 | 国产免费又黄又爽又刺激蜜月al | 国产99在线 | 欧美 | 黄视频在线网站 | 国内精品久久久久 | 久久机热 | 91电影在线播放 | 淫片一级国产 | 99re6在线视频精品免费 | 一色桃子av一区二区 | 国产精品成人久久久久a级 久久蜜桃av一区二区天堂 | 国产成人精品久久二区二区 | 精品一区二区视频 | 欧美激情国产日韩精品一区18 | 国产视频精品免费 | 一区二区在线看 | 日韩三级在线 | 福利电影在线 | 久久亚洲国产精品 |