搜尋
首頁系統教程Linux細說 Linux 虛擬檔案系統原理

細說 Linux 虛擬檔案系統原理

Feb 15, 2024 am 09:21 AM
linuxlinux教程linux系統linux指令shell腳本嵌入式linuxlinux入門linux學習

在 Unix 的世界中,有一句經典的話:一切皆文件。這句話的意思是,在 Unix 作業系統中,所有的物件都可以被視為文件,並使用操作文件的介面來操作它們。作為一個類別 Unix 作業系統,Linux 也努力實現這個目標。

虛擬檔案系統簡介

#為了實現 一切皆檔案 這個目標,Linux 核心提供了一個中間層:虛擬檔案系統(Virtual File System)

如果您曾經使用過物件導向程式語言(如 C /Java 等),那麼您應該對 介面 這個概念並不陌生。虛擬檔案系統類似於物件導向程式設計中的接口,它定義了一套標準的介面。開發人員只需實現這套接口,就可以使用操作文件的接口來操作對象。如下圖所示:

细说 Linux 虚拟文件系统原理

上圖中的藍色部分就是虛擬檔案系統所在位置。

從上圖可以看出,虛擬檔案系統為上層應用提供了統一的介面。如果某個檔案系統實作了虛擬檔案系統的接口,那麼上層應用程式就能夠使用諸如open()read()write() 等函數來操作它們。

今天,我們就來介紹虛擬檔案系統的原理與實作。

虛擬檔案系統原理

#在闡述虛擬檔案系統的原理前,我們先來介紹一個 Java 範例。透過這個 Java 例子,我們能夠更容易理解虛擬檔案系統的原理。

一個Java範例

#如果大家使用過 Java 寫程式的話,那就很容易理解虛擬檔案系統了。我們使用 Java 的介面來模擬虛擬檔案系統的定義:

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);
  ...
}

上面定義了一個名為VFSFile 的接口,接口中定義了一些方法,如open()read() write() 等。現在我們來定義一個名為 Ext3File 的物件來實作這個介面:

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) {
    ...
  }
  
  ...
}

現在我們就能使用 VFSFile 介面來操作 Ext3File 物件了,如下程式碼:

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

从上面的例子可以看出,底层对象只需要实现 VFSFile 接口,就可以使用 VFSFile 接口相关的方法来操作对象,用户完全不需要了解底层对象的实现过程。

虚拟文件系统原理

上面的 Java 例子已经大概说明虚拟文件系统的原理,但由于 Linux 是使用 C 语言来编写的,而 C 语言并没有接口这个概念。所以,Linux 内核使用了一些技巧来模拟接口这个概念。

下面来介绍一下 Linux 内核是如何实现的。

1. file结构

为了模拟接口,Linux 内核定义了一个名为 file 的结构体,其定义如下:

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

在 file 结构中,最为重要的一个字段就是 f_op,其类型为 file_operations 结构。而 file_operations 结构是由一组函数指针组成,其定义如下:

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 结构的定义可以隐约看到接口的影子,所以可以猜想出,如果实现了 file_operations 结构中的方法,应该就能接入到虚拟文件系统中。

在 Linux 内核中,file 结构代表着一个被打开的文件。所以,只需要将 file 结构的 f_op 字段设置成不同文件系统实现好的方法集,那么就能够使用不同文件系统的功能。

这个过程在 __dentry_open() 函数中实现,如下所示:

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;
    ...
    // 设置file结构的f_op字段为底层文件系统实现的方法集
    f->f_op = fops_get(inode->i_fop);
    ...
    return f;
}

设置好 file 结构的 f_op 字段后,虚拟文件系统就能够使用通用的接口来操作此文件了。调用过程如下:

细说 Linux 虚拟文件系统原理

2. file_operations结构

底层文件系统需要实现虚拟文件系统的接口,才能被虚拟文件系统使用。也就是说,底层文件系统需要实现 file_operations 结构中的方法集。

一般底层文件系统会在其内部定义好 file_operations 结构,并且填充好其方法集中的函数指针。如 minix文件系统 就定义了一个名为 minix_file_operationsfile_operations 结构。其定义如下:

// 文件: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,
};

也就是说,如果当前使用的是 minix 文件系统,当使用 read() 函数读取其文件的内容时,那么最终将会调用 do_sync_read() 函数来读取文件的内容。

3. dentry结构

到这里,虚拟文件系统的原理基本分析完毕,但还有两个非常重要的结构要介绍一下的:dentryinode

dentry 结构表示一个打开的目录项,当我们打开文件 /usr/local/lib/libc.so 文件时,内核会为文件路径中的每个目录创建一个 dentry 结构。如下图所示:

细说 Linux 虚拟文件系统原理

由于 /usr/local/lib/libc.so/tmp/libc.so 指向同一个文件,所以它们都使用同一个 inode 对象。

inode 结构保存了文件的所有属性值,如文件的创建时间、文件所属用户和文件的大小等。其定义如下所示:

struct inode {
    ...
    uid_t           i_uid;               // 文件所属用户
    gid_t           i_gid;               // 文件所属组
    ...
    struct timespec i_atime;             // 最后访问时间
    struct timespec i_mtime;             // 最后修改时间
    struct timespec i_ctime;             // 文件创建时间
    ...
    unsigned short  i_bytes;             // 文件大小
    ...
    const struct file_operations *i_fop; // 文件操作方法集(用于设置file结构)
    ...
};

我们注意到 inode 结构有个类型为 file_operations 结构的字段 i_fop,这个字段保存了文件的操作方法集。当用户调用 open() 系统调用打开文件时,内核将会使用 inode 结构的 i_fop 字段赋值给 file 结构的 f_op 字段。我们再来重温下赋值过程:

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对象
    inode = dentry->d_inode;
    ...
    // 使用inode结构的i_fop字段赋值给file结构的f_op字段
    f->f_op = fops_get(inode->i_fop);
    ...
    return f;
}

总结

本文主要介绍了 虚拟文件系统 的基本原理,从分析中可以发现,虚拟文件系统使用了类似于面向对象编程语言中的接口概念。正是有了 虚拟文件系统,Linux 才能支持各种各样的文件系统。

以上是細說 Linux 虛擬檔案系統原理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:良许Linux教程网。如有侵權,請聯絡admin@php.cn刪除
如何使用Next' Linux中的尷尬命令 - 第6部分如何使用Next' Linux中的尷尬命令 - 第6部分May 15, 2025 am 10:43 AM

在我們的尷尬系列的第六部分中,我們將探索下一個命令,該命令可以通過跳過冗餘處理步驟來提高腳本執行的效率。下一個命令是什麼? awk instruc中的下一個命令

如何在Linux中有效傳輸文件如何在Linux中有效傳輸文件May 15, 2025 am 10:42 AM

在Linux系統中傳輸文件是一項常見任務,每個系統管理員都應掌握,尤其是涉及本地或遠程系統間的網絡傳輸。 Linux提供了兩種常用的工具來完成此任務:SCP(安全複製)和Rsync。兩者都提供了一種安全且便捷的方式,用於在本地或遠程機器之間傳輸文件。本文將詳細介紹如何使用SCP和Rsync命令來傳輸文件,包括本地和遠程文件傳輸。了解Linux中的scp(安全複製協議)scp命令是一個命令行程序,用於在兩個主機之間通過SSH(安全 Shell)安全地複製文件和目錄,這意味著在文件通過互聯網傳輸時,數

有史以來最受歡迎的Linux桌面環境有史以來最受歡迎的Linux桌面環境May 15, 2025 am 10:35 AM

與Windows和Mac OS X相比,Linux的一個引人入勝的功能是對各種桌面環境的支持。這使桌面用戶可以根據其計算要求選擇最合適且最合適的桌面環境。 A

如何在Linux桌面中安裝Libreoffice 24.8如何在Linux桌面中安裝Libreoffice 24.8May 15, 2025 am 10:15 AM

Libreoffice脫穎而出,是一個健壯的開源辦公室套件,適用於Linux,Windows和Mac平台。它擁有一系列用於處理Word文檔,電子表格,演示,圖紙,計算和Mathematica的高級功能

如何使用linux中的僅限文件來處理PDF文件如何使用linux中的僅限文件來處理PDF文件May 15, 2025 am 09:58 AM

管理PDF文件的Linux用戶可以使用各種程序。具體來說,有許多專門為各種功能設計的專業PDF工具。

如何使用AWK和STDIN過濾命令輸出如何使用AWK和STDIN過濾命令輸出May 15, 2025 am 09:53 AM

在AWK命令系列的較早部分中,我們的重點主要是從文件中讀取輸入。但是,如果您需要從stdin中讀取輸入怎麼辦?在Awk系列的第7部分中,我們將探索幾個示例,您可以在其中使用O的OF O的輸出。

CLIFM- Linux的Lightning -Fast終端文件管理器CLIFM- Linux的Lightning -Fast終端文件管理器May 15, 2025 am 09:45 AM

Clifm是一個獨特而令人難以置信的迅速命令行文件管理器,在類似殼的界面的基礎上設計。這意味著用戶可以使用他們已經熟悉的命令與他們的文件系統互動。

如何從Linux Mint 21.3升級到Linux Mint 22如何從Linux Mint 21.3升級到Linux Mint 22May 15, 2025 am 09:44 AM

如果您不想執行Linux Mint 22 Wilma的新安裝,則可以選擇從以前的版本中升級。在本指南中,我們將詳細介紹從Linux Mint 21.3升級的過程(21.x系列的最新次要版本

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具