精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Linux 的虛擬文件系統(真正理解“一切皆文件”)

云計算 虛擬化
Linux 中允許眾多不同的文件系統共存,如 ext2, ext3, vfat 等。通過使用同一套文件 I/O 系統 調用即可對 Linux 中的任意文件進行操作而無需考慮其所在的具體文件系統格式;更進一步,對文件的 操作可以跨文件系統而執行。

[[268044]]

 1,引言

Linux 中允許眾多不同的文件系統共存,如 ext2, ext3, vfat 等。通過使用同一套文件 I/O 系統 調用即可對 Linux 中的任意文件進行操作而無需考慮其所在的具體文件系統格式;更進一步,對文件的 操作可以跨文件系統而執行。如圖 1 所示,我們可以使用 cp 命令從 vfat 文件系統格式的硬盤拷貝數據到 ext3 文件系統格式的硬盤;而這樣的操作涉及到兩個不同的文件系統。

圖 1. 跨文件系統的文件操作

 

 

Linux 的虛擬文件系統(真正理解“一切皆文件”)

 

“一切皆是文件”是 Unix/Linux 的基本哲學之一。不僅普通的文件,目錄、字符設備、塊設備、 套接字等在 Unix/Linux 中都是以文件被對待;它們雖然類型不同,但是對其提供的卻是同一套操作界面。

圖 2. 一切皆是文件

Linux 的虛擬文件系統(真正理解“一切皆文件”)

而虛擬文件系統正是實現上述兩點 Linux 特性的關鍵所在。虛擬文件系統(Virtual File System, 簡稱 VFS), 是 Linux 內核中的一個軟件層,用于給用戶空間的程序提供文件系統接口;同時,它也提供了內核中的一個 抽象功能,允許不同的文件系統共存。系統中所有的文件系統不但依賴 VFS 共存,而且也依靠 VFS 協同工作。

為了能夠支持各種實際文件系統,VFS 定義了所有文件系統都支持的基本的、概念上的接口和數據 結構;同時實際文件系統也提供 VFS 所期望的抽象接口和數據結構,將自身的諸如文件、目錄等概念在形式 上與VFS的定義保持一致。換句話說,一個實際的文件系統想要被 Linux 支持,就必須提供一個符合VFS標準 的接口,才能與 VFS 協同工作。實際文件系統在統一的接口和數據結構下隱藏了具體的實現細節,所以在VFS 層和內核的其他部分看來,所有文件系統都是相同的。圖3顯示了VFS在內核中與實際的文件系統的協同關系。

圖3. VFS在內核中與其他的內核模塊的協同關系

 

Linux 的虛擬文件系統(真正理解“一切皆文件”)

 

我們已經知道,正是由于在內核中引入了VFS,跨文件系統的文件操作才能實現,“一切皆是文件” 的口號才能承諾。而為什么引入了VFS,就能實現這兩個特性呢?在接下來,我們將以這樣的一個思路來切入

文章的正題:我們將先簡要介紹下用以描述VFS模型的一些數據結構,總結出這些數據結構相互間的關系;然后 選擇兩個具有代表性的文件I/O操作sys_open()和sys_read()來詳細說明內核是如何借助VFS和具體的文件系統打 交道以實現跨文件系統的文件操作和承諾“一切皆是文件”的口號。

2 VFS數據結構

2.1 一些基本概念

從本質上講,文件系統是特殊的數據分層存儲結構,它包含文件、目錄和相關的控制信息。為了描述 這個結構,Linux引入了一些基本概念:

文件 一組在邏輯上具有完整意義的信息項的系列。在Linux中,除了普通文件,其他諸如目錄、設備、套接字等 也以文件被對待??傊?,“一切皆文件”。

目錄 目錄好比一個文件夾,用來容納相關文件。因為目錄可以包含子目錄,所以目錄是可以層層嵌套,形成 文件路徑。在Linux中,目錄也是以一種特殊文件被對待的,所以用于文件的操作同樣也可以用在目錄上。

目錄項 在一個文件路徑中,路徑中的每一部分都被稱為目錄項;如路徑/home/source/helloworld.c中,目錄 /, home, source和文件 helloworld.c都是一個目錄項。

索引節點 用于存儲文件的元數據的一個數據結構。文件的元數據,也就是文件的相關信息,和文件本身是兩個不同 的概念。它包含的是諸如文件的大小、擁有者、創建時間、磁盤位置等和文件相關的信息。

超級塊 用于存儲文件系統的控制信息的數據結構。描述文件系統的狀態、文件系統類型、大小、區塊數、索引節點數等,存放于磁盤的特定扇區中。

如上的幾個概念在磁盤中的位置關系如圖4所示。

圖4. 磁盤與文件系統

 

Linux 的虛擬文件系統(真正理解“一切皆文件”)

 

關于文件系統的三個易混淆的概念:

創建 以某種方式格式化磁盤的過程就是在其之上建立一個文件系統的過程。創建文現系統時,會在磁盤的特定位置寫入 關于該文件系統的控制信息。

注冊 向內核報到,聲明自己能被內核支持。一般在編譯內核的時侯注冊;也可以加載模塊的方式手動注冊。注冊過程實 際上是將表示各實際文件系統的數據結構struct file_system_type 實例化。

安裝 也就是我們熟悉的mount操作,將文件系統加入到Linux的根文件系統的目錄樹結構上;這樣文件系統才能被訪問。

2.2 VFS數據結構

VFS依靠四個主要的數據結構和一些輔助的數據結構來描述其結構信息,這些數據結構表現得就像是對象; 每個主要對象中都包含由操作函數表構成的操作對象,這些操作對象描述了內核針對這幾個主要的對象可以進行的操作。

2.2.1 超級塊對象

存儲一個已安裝的文件系統的控制信息,代表一個已安裝的文件系統;每次一個實際的文件系統被安裝時, 內核會從磁盤的特定位置讀取一些控制信息來填充內存中的超級塊對象。一個安裝實例和一個超級塊對象一一對應。 超級塊通過其結構中的一個域s_type記錄它所屬的文件系統類型。

根據第三部分追蹤源代碼的需要,以下是對該超級塊結構的部分相關成員域的描述,(如下同):

清單1. 超級塊

  1. struct super_block { //超級塊數據結構 
  2.  struct list_head s_list; /*指向超級塊鏈表的指針*/ 
  3.  …… 
  4.  struct file_system_type *s_type; /*文件系統類型*/ 
  5.  struct super_operations *s_op; /*超級塊方法*/ 
  6.  …… 
  7.  struct list_head s_instances; /*該類型文件系統*/ 
  8.  …… 
  9. }; 
  10. struct super_operations { //超級塊方法 
  11.  …… 
  12.  //該函數在給定的超級塊下創建并初始化一個新的索引節點對象 
  13.  struct inode *(*alloc_inode)(struct super_block *sb); 
  14.  …… 
  15.  //該函數從磁盤上讀取索引節點,并動態填充內存中對應的索引節點對象的剩余部分 
  16.  void (*read_inode) (struct inode *); 
  17.  …… 
  18. }; 

2.2.2 索引節點對象

索引節點對象存儲了文件的相關信息,代表了存儲設備上的一個實際的物理文件。當一個 文件***被訪問時,內核會在內存中組裝相應的索引節點對象,以便向內核提供對一個文件進行操 作時所必需的全部信息;這些信息一部分存儲在磁盤特定位置,另外一部分是在加載時動態填充的。

清單2. 索引節點

struct inode {//索引節點結構 …… struct inode_operations *i_op; /*索引節點操作表*/ struct file_operations *i_fop; /*該索引節點對應文件的文件操作集*/ struct super_block *i_sb; /*相關的超級塊*/ ……};struct inode_operations { //索引節點方法 …… //該函數為dentry對象所對應的文件創建一個新的索引節點,主要是由open()系統調用來調用 int (*create) (struct inode *,struct dentry *,int, struct nameidata *); //在特定目錄中尋找dentry對象所對應的索引節點 struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); ……};

2.2.3 目錄項對象

引入目錄項的概念主要是出于方便查找文件的目的。一個路徑的各個組成部分,不管是目錄還是 普通的文件,都是一個目錄項對象。如,在路徑/home/source/test.c中,目錄 /, home, source和文件 test.c都對應一個目錄項對象。不同于前面的兩個對象,目錄項對象沒有對應的磁盤數據結構,VFS在遍 歷路徑名的過程中現場將它們逐個地解析成目錄項對象。

清單3. 目錄項

  1. struct inode {//索引節點結構 
  2.  …… 
  3.  struct inode_operations *i_op; /*索引節點操作表*/ 
  4.  struct file_operations *i_fop; /*該索引節點對應文件的文件操作集*/ 
  5.  struct super_block *i_sb; /*相關的超級塊*/ 
  6.  …… 
  7. }; 
  8. struct inode_operations { //索引節點方法 
  9.  …… 
  10.  //該函數為dentry對象所對應的文件創建一個新的索引節點,主要是由open()系統調用來調用 
  11.  int (*create) (struct inode *,struct dentry *,int, struct nameidata *); 
  12.  //在特定目錄中尋找dentry對象所對應的索引節點 
  13.  struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); 
  14.  …… 
  15. }; 

2.2.4 文件對象

文件對象是已打開的文件在內存中的表示,主要用于建立進程和磁盤上的文件的對應關系。它由sys_open() 現場創建,由sys_close()銷毀。文件對象和物理文件的關系有點像進程和程序的關系一樣。當我們站在用戶空間來看 待VFS,我們像是只需與文件對象打交道,而無須關心超級塊,索引節點或目錄項。因為多個進程可以同時打開和操作 同一個文件,所以同一個文件也可能存在多個對應的文件對象。文件對象僅僅在進程觀點上代表已經打開的文件,它 反過來指向目錄項對象(反過來指向索引節點)。一個文件對應的文件對象可能不是惟一的,但是其對應的索引節點和 目錄項對象無疑是惟一的。

清單4. 文件對象

  1. struct file { 
  2.  …… 
  3.  struct list_head f_list; /*文件對象鏈表*/ 
  4.  struct dentry *f_dentry; /*相關目錄項對象*/ 
  5.  struct vfsmount *f_vfsmnt; /*相關的安裝文件系統*/ 
  6.  struct file_operations *f_op; /*文件操作表*/ 
  7.  …… 
  8. }; 
  9. struct file_operations { 
  10.  …… 
  11.  //文件讀操作 
  12.  ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); 
  13.  …… 
  14.  //文件寫操作 
  15.  ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); 
  16.  …… 
  17.  int (*readdir) (struct file *, void *, filldir_t); 
  18.  …… 
  19.  //文件打開操作 
  20.  int (*open) (struct inode *, struct file *); 
  21.  …… 
  22. }; 

2.2.5 其他VFS對象

2.2.5.1 和文件系統相關

根據文件系統所在的物理介質和數據在物理介質上的組織方式來區分不同的文件系統類型的。 file_system_type結構用于描述具體的文件系統的類型信息。被Linux支持的文件系統,都有且僅有一 個file_system_type結構而不管它有零個或多個實例被安裝到系統中。

而與此對應的是每當一個文件系統被實際安裝,就有一個vfsmount結構體被創建,這個結構體對應一個安裝點。

清單5. 和文件系統相關

  1. struct file_system_type { 
  2.  const char *name; /*文件系統的名字*/ 
  3.  struct subsystem subsys; /*sysfs子系統對象*/ 
  4.  int fs_flags; /*文件系統類型標志*/ 
  5.  /*在文件系統被安裝時,從磁盤中讀取超級塊,在內存中組裝超級塊對象*/ 
  6.  struct super_block *(*get_sb) (struct file_system_type*,  
  7.  int, const char*, void *); 
  8.   
  9.  void (*kill_sb) (struct super_block *); /*終止訪問超級塊*/  
  10.  struct module *owner; /*文件系統模塊*/ 
  11.  struct file_system_type * next; /*鏈表中的下一個文件系統類型*/ 
  12.  struct list_head fs_supers; /*具有同一種文件系統類型的超級塊對象鏈表*/ 
  13. }; 
  14. struct vfsmount 
  15.  struct list_head mnt_hash; /*散列表*/ 
  16.  struct vfsmount *mnt_parent; /*父文件系統*/ 
  17.  struct dentry *mnt_mountpoint; /*安裝點的目錄項對象*/ 
  18.  struct dentry *mnt_root; /*該文件系統的根目錄項對象*/ 
  19.  struct super_block *mnt_sb; /*該文件系統的超級塊*/ 
  20.  struct list_head mnt_mounts; /*子文件系統鏈表*/ 
  21.  struct list_head mnt_child; /*子文件系統鏈表*/ 
  22.  atomic_t mnt_count; /*使用計數*/ 
  23.  int mnt_flags; /*安裝標志*/ 
  24.  char *mnt_devname; /*設備文件名*/ 
  25.  struct list_head mnt_list; /*描述符鏈表*/ 
  26.  struct list_head mnt_fslink; /*具體文件系統的到期列表*/ 
  27.  struct namespace *mnt_namespace; /*相關的名字空間*/ 
  28. }; 

2.2.5.2 和進程相關

清單6. 打開的文件集

  1. struct files_struct {//打開的文件集 
  2.  atomic_t count; /*結構的使用計數*/ 
  3.  …… 
  4.  int max_fds; /*文件對象數的上限*/ 
  5.  int max_fdset; /*文件描述符的上限*/ 
  6.  int next_fd; /*下一個文件描述符*/ 
  7.  struct file ** fd; /*全部文件對象數組*/ 
  8.  …… 
  9.  }; 
  10. struct fs_struct {//建立進程與文件系統的關系 
  11.  atomic_t count; /*結構的使用計數*/ 
  12.  rwlock_t lock; /*保護該結構體的鎖*/ 
  13.  int umask; /*默認的文件訪問權限*/ 
  14.  struct dentry * root; /*根目錄的目錄項對象*/ 
  15.  struct dentry * pwd; /*當前工作目錄的目錄項對象*/ 
  16.  struct dentry * altroot; /*可供選擇的根目錄的目錄項對象*/ 
  17.  struct vfsmount * rootmnt; /*根目錄的安裝點對象*/ 
  18.  struct vfsmount * pwdmnt; /*pwd的安裝點對象*/ 
  19.  struct vfsmount * altrootmnt;/*可供選擇的根目錄的安裝點對象*/ 
  20. }; 

2.2.5.3 和路徑查找相關

清單7. 輔助查找

  1. struct nameidata { 
  2.  struct dentry *dentry; /*目錄項對象的地址*/ 
  3.  struct vfsmount *mnt; /*安裝點的數據*/ 
  4.  struct qstr last; /*路徑中的***一個component*/ 
  5.  unsigned int flags; /*查找標識*/ 
  6.  int last_type; /*路徑中的***一個component的類型*/ 
  7.  unsigned depth; /*當前symbolic link的嵌套深度,不能大于6*/ 
  8.  char *saved_names[MAX_NESTED_LINKS + 1];/ 
  9.  /*和嵌套symbolic link 相關的pathname*/ 
  10.  union { 
  11.  struct open_intent open; /*說明文件該如何訪問*/ 
  12.  } intent; /*專用數據*/ 
  13. }; 

2.2.6 對象間的聯系

如上的數據結構并不是孤立存在的。正是通過它們的有機聯系,VFS才能正常工作。如下的幾張圖是對它們之間的聯系的描述。

如圖5所示,被Linux支持的文件系統,都有且僅有一個file_system_type結構而不管它有零個或多個實例被安裝到系統 中。每安裝一個文件系統,就對應有一個超級塊和安裝點。超級塊通過它的一個域s_type指向其對應的具體的文件系統類型。具體的 文件系統通過file_system_type中的一個域fs_supers鏈接具有同一種文件類型的超級塊。同一種文件系統類型的超級塊通過域s_instances鏈 接。

圖5. 超級塊、安裝點和具體的文件系統的關系

 

Linux 的虛擬文件系統(真正理解“一切皆文件”)

 

從圖6可知:進程通過task_struct中的一個域files_struct files來了解它當前所打開的文件對象;而我們通常所說的文件 描述符其實是進程打開的文件對象數組的索引值。文件對象通過域f_dentry找到它對應的dentry對象,再由dentry對象的域d_inode找 到它對應的索引結點,這樣就建立了文件對象與實際的物理文件的關聯。***,還有一點很重要的是, 文件對象所對應的文件操作函數 列表是通過索引結點的域i_fop得到的。圖6對第三部分源碼的理解起到很大的作用。

圖6. 進程與超級塊、文件、索引結點、目錄項的關系

 

Linux 的虛擬文件系統(真正理解“一切皆文件”)

 

3 基于VFS的文件I/O

到目前為止,文章主要都是從理論上來講述VFS的運行機制;接下來我們將深入源代碼層中,通過闡述兩個具有代表性的系統 調用sys_open()和sys_read()來更好地理解VFS向具體文件系統提供的接口機制。由于本文更關注的是文件操作的整個流程體制,所以我 們在追蹤源代碼時,對一些細節性的處理不予關心。又由于篇幅所限,只列出相關代碼。本文中的源代碼來自于linux-2.6.17內核版本。

在深入sys_open()和sys_read()之前,我們先概覽下調用sys_read()的上下文。圖7描述了從用戶空間的read()調用到數據從 磁盤讀出的整個流程。當在用戶應用程序調用文件I/O read()操作時,系統調用sys_read()被激發,sys_read()找到文件所在的具體文件 系統,把控制權傳給該文件系統,***由具體文件系統與物理介質交互,從介質中讀出數據。

圖7. 從物理介質讀數據的過程

Linux 的虛擬文件系統(真正理解“一切皆文件”)

3.1 sys_open()

sys_open()系統調用打開或創建一個文件,成功返回該文件的文件描述符。圖8是sys_open()實現代碼中主要的函數調用關系圖。

圖8. sys_open函數調用關系圖

 

Linux 的虛擬文件系統(真正理解“一切皆文件”)

 

由于sys_open()的代碼量大,函數調用關系復雜,以下主要是對該函數做整體的解析;而對其中的一些關鍵點,則列出其關鍵代碼。

a. 從sys_open()的函數調用關系圖可以看到,sys_open()在做了一些簡單的參數檢驗后,就把接力棒傳給do_sys_open():

1)、首先,get_unused_fd()得到一個可用的文件描述符;通過該函數,可知文件描述符實質是進程打開文件列表中對應某個文件對象的索引值;

2)、接著,do_filp_open()打開文件,返回一個file對象,代表由該進程打開的一個文件;進程通過這樣的一個數據結構對物理文件進行讀寫操作。

3)、***,fd_install()建立文件描述符與file對象的聯系,以后進程對文件的讀寫都是通過操縱該文件描述符而進行。

b. do_filp_open()用于打開文件,返回一個file對象;而打開之前需要先找到該文件:

1)、open_namei()用于根據文件路徑名查找文件,借助一個持有路徑信息的數據結構nameidata而進行;

2)、查找結束后將填充有路徑信息的nameidata返回給接下來的函數nameidata_to_filp()從而得到最終的file對象;當達到目的后,nameidata這個數據結構將會馬上被釋放。

c.open_namei()用于查找一個文件:

1)、path_lookup_open()實現文件的查找功能;要打開的文件若不存在,還需要有一個新建的過程,則調用 path_lookup_create(),后者和前者封裝的是同一個實際的路徑查找函數,只是參數不一樣,使它們在處理細節上有所偏差;

2)、當是以新建文件的方式打開文件時,即設置了O_CREAT標識時需要創建一個新的索引節點,代表創建一個文件。在vfs_create()里的一句 核心語句dir->i_op->create(dir, dentry, mode, nd)可知它調用了具體的文件系統所提供的創建索引節點的方法。注意:這邊的索引節點的概念,還只是位于內存之中,它和磁盤上的物理的索引節點的關系就像 位于內存中和位于磁盤中的文件一樣。此時新建的索引節點還不能完全標志一個物理文件的成功創建,只有當把索引節點回寫到磁盤上才是一個物理文件的真正創 建。想想我們以新建的方式打開一個文件,對其讀寫但最終沒有保存而關閉,則位于內存中的索引節點會經歷從新建到消失的過程,而磁盤卻始終不知道有人曾經想 過創建一個文件,這是因為索引節點沒有回寫的緣故。

3)、path_to_nameidata()填充nameidata數據結構;

4)、may_open()檢查是否可以打開該文件;一些文件如鏈接文件和只有寫權限的目錄是不能被打開的,先檢查 nd->dentry->inode所指的文件是否是這一類文件,是的話則錯誤返回。還有一些文件是不能以TRUNC的方式打開的,若 nd->dentry->inode所指的文件屬于這一類,則顯式地關閉TRUNC標志位。接著如果有以TRUNC方式打開文件的,則更新 nd->dentry->inode的信息

3.1.1__path_lookup_intent_open()

不管是path_lookup_open()還是path_lookup_create()最終都是調用 __path_lookup_intent_open()來實現查找文件的功能。 查找時,在遍歷路徑的過程中,會逐層地將各個路徑組成部分解析成目錄項對象,如果此目錄項對象在目錄項緩存中,則直接從緩存中獲得;如果該目錄項在緩存中 不存在,則進行一次實際的讀盤操作,從磁盤中讀取該目錄項所對應的索引節點。得到索引節點后,則建立索引節點與該目錄項的聯系。如此循環,直到最終找到目 標文件對應的目錄項,也就找到了索引節點,而由索引節點找到對應的超級塊對象就可知道該文件所在的文件系統的類型。 從磁盤中讀取該目錄項所對應的索引節點;這將引發VFS和實際的文件系統的一次交互。從前面的VFS理論介紹可知,讀索引節點方法是由超級塊來提供的。而 當安裝一個實際的文件系統時,在內存中創建的超級塊的信息是由一個實際文件系統的相關信息來填充的,這里的相關信息就包括了實際文件系統所定義的超級塊的 操作函數列表,當然也就包括了讀索引節點的具體執行方式。 當繼續追蹤一個實際文件系統ext3的ext3_read_inode()時,可發現這個函數很重要的一個工作就是為不同的文件類型設置不同的索引節點操 作函數表和文件操作函數表。

清單8. ext3_read_inode

  1. void ext3_read_inode(struct inode * inode) 
  2.  { 
  3.  …… 
  4.  //是普通文件  
  5.  if (S_ISREG(inode->i_mode)) { 
  6.  inode->i_op = &ext3_file_inode_operations; 
  7.  inode->i_fop = &ext3_file_operations; 
  8.  ext3_set_aops(inode); 
  9.  } else if (S_ISDIR(inode->i_mode)) { 
  10.  //是目錄文件 
  11.  inode->i_op = &ext3_dir_inode_operations; 
  12.  inode->i_fop = &ext3_dir_operations; 
  13.  } else if (S_ISLNK(inode->i_mode)) { 
  14.  // 是連接文件  
  15.  …… 
  16.  } else {  
  17.  // 如果以上三種情況都排除了,則是設備驅動 
  18.  //這里的設備還包括套結字、FIFO等偽設備  
  19.  ……  

3.1.2 nameidata_to_filp子函數:__dentry_open

這是VFS與實際的文件系統聯系的一個關鍵點。從3.1.1小節分析中可知,調用實際文件系統讀取索引節點的方法讀取索引節點時,實際文件系統會根據文件 的不同類型賦予索引節點不同的文件操作函數集,如普通文件有普通文件對應的一套操作函數,設備文件有設備文件對應的一套操作函數。這樣當把對應的索引節點 的文件操作函數集賦予文件對象,以后對該文件進行操作時,比如讀操作,VFS雖然對各種不同文件都是執行同一個read()操作界面,但是真正讀時,內核 卻知道怎么區分對待不同的文件類型。

清單9. __dentry_open

  1. static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, 
  2.  int flags, struct file *f, 
  3.  int (*open)(struct inode *, struct file *)) 
  4.  { 
  5.  struct inode *inode; 
  6.  …… 
  7.  //整個函數的工作在于填充一個file對象 
  8.  …… 
  9.  f->f_mapping = inode->i_mapping;  
  10.  f->f_dentry = dentry; 
  11.  f->f_vfsmnt = mnt; 
  12.  f->f_pos = 0;  
  13.  //將對應的索引節點的文件操作函數集賦予文件對象的操作列表 
  14.  <span class="boldcode">f->f_op = fops_get(inode->i_fop); </span> 
  15.  ……  
  16.  //若文件自己定義了open操作,則執行這個特定的open操作。 
  17.  if (!open && f->f_op) 
  18.  open = f->f_op->open;  
  19.  if (open) { 
  20.  error = open(inode, f); 
  21.  if (error) 
  22.  goto cleanup_all; 
  23.  …… 
  24.  return f; 

3.2 sys_read()

sys_read()系統調用用于從已打開的文件讀取數據。如read成功,則返回讀到的字節數。如已到達文件的尾端,則返回0。圖9是sys_read()實現代碼中的函數調用關系圖。

圖9. sys_read函數調用關系圖

 

Linux 的虛擬文件系統(真正理解“一切皆文件”)

 

對文件進行讀操作時,需要先打開它。從3.1小結可知,打開一個文件時,會在內存組裝一個文件對象,希望對該文件執行的操作方法已在文件對象設置好。所以 對文件進行讀操作時,VFS在做了一些簡單的轉換后(由文件描述符得到其對應的文件對象;其核心思想是返回 current->files->fd[fd]所指向的文件對象),就可以通過語句 file->f_op->read(file, buf, count, pos)輕松調用實際文件系統的相應方法對文件進行讀操作了。

4 解決問題

4.1 跨文件系統的文件操作的基本原理

到此,我們也就能夠解釋在Linux中為什么能夠跨文件系統地操作文件了。舉個例子,將vfat格式的磁盤上的一個文件a.txt拷貝到ext3格式的磁 盤上,命名為b.txt。這包含兩個過程,對a.txt進行讀操作,對b.txt進行寫操作。讀寫操作前,需要先打開文件。由前面的分析可知,打開文件 時,VFS會知道該文件對應的文件系統格式,以后操作該文件時,VFS會調用其對應的實際文件系統的操作方法。所以,VFS調用vfat的讀文件方法將 a.txt的數據讀入內存;在將a.txt在內存中的數據映射到b.txt對應的內存空間后,VFS調用ext3的寫文件方法將b.txt寫入磁盤;從而 實現了最終的跨文件系統的復制操作。

4.2“一切皆是文件”的實現根本

不論是普通的文件,還是特殊的目錄、設備等,VFS都將它們同等看待成文件,通過同一套文件操作界面來對它們進行操作。操作文件時需先打開;打開文件 時,VFS會知道該文件對應的文件系統格式;當VFS把控制權傳給實際的文件系統時,實際的文件系統再做出具體區分,對不同的文件類型執行不同的操作。這 也就是“一切皆是文件”的根本所在。

5 總結

VFS即虛擬文件系統是Linux文件系統中的一個抽象軟件層;因為它的支持,眾多不同的實際文件系統才能在Linux中共存,跨文件系統操作才能實現。 VFS借助它四個主要的數據結構即超級塊、索引節點、目錄項和文件對象以及一些輔助的數據結構,向Linux中不管是普通的文件還是目錄、設備、套接字等 都提供同樣的操作界面,如打開、讀寫、關閉等。只有當把控制權傳給實際的文件系統時,實際的文件系統才會做出區分,對不同的文件類型執行不同的操作。由此 可見,正是有了VFS的存在,跨文件系統操作才能執行,Unix/Linux中的“一切皆是文件”的口號才能夠得以實現。

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2023-12-06 09:32:35

Linux系統

2020-07-22 14:53:06

Linux系統虛擬文件

2019-05-29 16:33:32

Linux虛擬系統

2019-05-22 09:00:16

Linux虛擬文件系統

2020-10-12 17:40:44

lsofLinux虛擬文件

2022-04-21 14:09:17

lsofLinux虛擬文件

2020-01-09 09:13:34

UnixLinux協議

2018-08-24 10:10:25

Linux文件系統技術

2019-09-20 10:04:45

Linux系統虛擬文件

2013-10-09 14:30:36

2009-07-21 10:49:26

ASP.NET虛擬文件

2024-01-01 16:01:22

Python函數

2024-02-02 10:38:06

虛擬文件系統VFS

2025-03-28 09:19:11

2020-09-16 11:46:05

AI

2010-03-02 14:21:30

Linux操作系統

2011-01-11 10:29:35

Linux文件

2021-05-31 07:50:59

Linux文件系統

2020-04-08 12:50:29

Python編程語言開發

2017-02-06 16:18:57

微軟GitGVFS
點贊
收藏

51CTO技術棧公眾號

91精品国产色综合久久不卡粉嫩| 黄色av网站在线看| 99在线|亚洲一区二区| 亚洲性视频网址| 欧洲美女亚洲激情| 僵尸再翻生在线观看| 国产精品国产a级| 久精品国产欧美| 亚洲天堂2021av| 亚洲另类自拍| 久热99视频在线观看| 天堂久久久久久| 国产激情综合| 色婷婷久久久综合中文字幕| 国产a级黄色大片| 二人午夜免费观看在线视频| 成人午夜视频免费看| 国产精品免费视频xxxx| 日韩欧美性视频| 伊人情人综合网| 亚洲一级片在线看| 好男人香蕉影院| 日韩三级精品| 欧美人动与zoxxxx乱| 日韩激情免费视频| 欧美6一10sex性hd| √…a在线天堂一区| 日本成人看片网址| 亚洲人成色777777老人头| 激情五月婷婷综合网| 国产脚交av在线一区二区| xxxxxx国产| 欧美国产日本| 久久激情视频久久| a级黄色免费视频| 欧美日韩国产一区二区三区不卡 | 精品久久久中文字幕人妻| 日韩高清一区在线| 全球成人中文在线| 欧美日韩乱国产| 亚洲东热激情| 久久欧美在线电影| 伊人国产在线观看| 激情成人综合| 久久久久久久久国产精品| 免费在线观看国产精品| 欧美国产91| 欧美大胆在线视频| 日本在线一级片| 亚洲激情中文在线| 欧美精品中文字幕一区| 欧美黄色免费观看| 亚洲欧美一级二级三级| 欧美日韩第一页| 妺妺窝人体色www聚色窝仙踪| 欧美成人午夜| 午夜精品一区二区三区在线视| 精品肉丝脚一区二区三区| 激情欧美日韩| 91精品国产91久久久久久| 久久9999久久免费精品国产| 亚洲激情不卡| 日本久久久久久久久久久| 天堂网中文字幕| 久久久久久久波多野高潮日日| 日韩av免费网站| 国产精品午夜一区二区| 在线观看日韩电影| 中国丰满熟妇xxxx性| 色呦呦在线观看视频| 亚洲国产欧美在线人成| 国产成人黄色片| 美女写真久久影院| 777午夜精品免费视频| 国产吃瓜黑料一区二区| 好吊妞国产欧美日韩免费观看网站 | 国产一区美女在线| 成人欧美一区二区三区黑人| 国产乱码精品一区二区| 国产成人精品免费| 久久精品中文字幕一区二区三区| 韩国免费在线视频| 久久午夜电影网| 一区二区三区四区不卡| 先锋影音在线资源站91| 五月天精品一区二区三区| 国产成人无码一二三区视频| 色999久久久精品人人澡69| 日韩欧美黄色影院| 中文人妻一区二区三区| 久久国产电影| 久久久久国色av免费观看性色| 你懂的国产视频| 久久精品72免费观看| 国产精华一区二区三区| jizz在线观看视频| 亚洲图片自拍偷拍| 黄色手机在线视频| 久久精品色播| 久久伊人精品视频| 日韩综合在线观看| 丁香婷婷综合五月| 一本一生久久a久久精品综合蜜| 蜜臀av在线| 欧美日韩中字一区| 北岛玲一区二区| 欧美a级在线| 国产精品久久久久久久久久| 蜜桃视频在线观看www| 国产精品免费视频观看| 噜噜噜久久亚洲精品国产品麻豆| 蜜桃精品视频| 欧美xoxoxo| 国内精品在线播放| 久久大片网站| 哥也色在线视频| 欧美激情亚洲另类| 香港三级日本三级| 97精品国产| 78色国产精品| 国产毛片毛片毛片毛片| 国产又大又黑又粗| 97久久精品人人澡人人爽| 亚洲精品无人区| 欧美一级鲁丝片| 日韩一区二区在线播放| 性の欲びの女javhd| 99在线热播精品免费99热| 日产午夜精品一线二线三线| 精品福利在线观看| 五月天中文字幕在线| 色愁久久久久久| 亚洲一级Av无码毛片久久精品| 99re91这里只有精品| 91碰在线视频| 免费的av在线| 国产一区二区三区四区五区3d| 日韩av中文字幕在线播放| caoporn91| 久久狠狠婷婷| 欧美aaaaa喷水| 日韩伦理在线| 亚洲精品久久久久中文字幕欢迎你| 日本a级片视频| 精品无人区卡一卡二卡三乱码免费卡 | 免费在线视频一区二区| 国产成人亚洲综合色影视| 警花观音坐莲激情销魂小说| 国产精品**亚洲精品| 久久精品国产96久久久香蕉| 亚洲一区精品在线观看| 中文一区二区在线观看| 日韩高清第一页| 99精品全国免费观看视频软件| 国产精品美乳一区二区免费| 香蕉视频网站在线观看| 欧美精品高清视频| 神马久久精品综合| 国产精品乡下勾搭老头1| av动漫在线免费观看| 高清精品xnxxcom| 6080yy精品一区二区三区| 深夜福利免费在线观看| 91福利视频在线| av在线免费播放网址| 经典一区二区三区| 日韩精品一区二区在线视频| 思热99re视热频这里只精品| 国产精品678| 最新国产在线观看| 日韩欧美国产午夜精品| 日韩三级免费看| 91婷婷韩国欧美一区二区| 日韩av资源在线| 欧美日一区二区| 亚洲xxxx在线| 欧美男男tv网站在线播放| 亚洲欧美国产精品专区久久| 6—12呦国产精品| 亚洲一区二区三区视频在线| 插吧插吧综合网| 国产麻豆欧美日韩一区| jizzjizz国产精品喷水| 98精品久久久久久久| 国产精选一区二区| 日本黄色一区| 欧美激情久久久| 黄色在线网站| 精品日韩99亚洲| 国产成人a v| 亚洲第一搞黄网站| 可以免费看av的网址| 成av人片一区二区| 三级一区二区三区| 亚洲专区在线| 免费日韩在线观看| 不卡一区2区| 国产一区二区自拍| 婷婷久久免费视频| 欧美一级免费视频| 影音先锋在线播放| 中文字幕亚洲天堂| 蜜臀久久99精品久久久| 欧美三级电影在线看| 日韩成人av毛片| 亚洲欧美自拍偷拍色图| 国产肥白大熟妇bbbb视频| 国产成人aaa| 天堂av8在线| 三级欧美韩日大片在线看| 人妻少妇精品无码专区二区| 婷婷综合亚洲| 日韩av电影免费在线观看| 久久99精品国产自在现线| 国产欧美久久久久久| 中文字幕色婷婷在线视频| 久久久视频在线| 91香蕉在线观看| 日韩中文字幕亚洲| 国产在线一在线二| 亚洲欧美激情四射在线日| 污视频软件在线观看| 精品区一区二区| 国产伦理一区二区| 欧美午夜片在线看| 无码人妻精品一区二区50| 图片区日韩欧美亚洲| 久久久久无码国产精品不卡| 亚洲图片激情小说| 免费精品在线视频| 国产精品免费视频观看| 亚洲一二三精品| 国产日韩欧美一区二区三区综合| 国产精品无码久久久久久| 99视频精品免费视频| 中国特级黄色大片| 成人午夜私人影院| 亚洲一级av无码毛片精品| 成人免费av在线| www.四虎在线| 成人福利视频网站| 亚洲欧美在线不卡| 久久众筹精品私拍模特| 久久久久亚洲AV成人无码国产| 成人动漫中文字幕| 伊人网综合视频| 99精品偷自拍| 97伦伦午夜电影理伦片| 国产欧美日韩一区二区三区在线观看 | 欧美 日韩 国产 高清| 亚洲美女色禁图| 国产日韩一区二区在线| 狂野欧美一区| 国产原创精品在线| 国产一区二区三区在线观看精品 | 亚洲第一二区| 国产精品一区二区三区在线| 欧美电影在线观看免费| 欧美日韩精品一区| 大片网站久久| 日韩一二区视频| 99精品国产一区二区青青牛奶| 国产男女在线观看| 日本不卡123| www激情五月| 波多野结衣亚洲一区| wwwwww日本| 国产精品成人网| 国产一级视频在线| 一本到高清视频免费精品| 伊人久久亚洲综合| 日韩欧美国产综合一区| 欧美偷拍视频| 久久精视频免费在线久久完整在线看| 日本欧美电影在线观看| 欧美孕妇毛茸茸xxxx| 久久福利在线| 国产伦精品一区二区三区视频黑人| 中文字幕精品影院| 国产一二三四区在线观看| 亚洲精品视频啊美女在线直播| 999在线免费视频| 国产精品888| 国产成人福利在线| 亚洲精品v日韩精品| 欧产日产国产69| 欧美一区二区三区免费视频| 日韩精品视频在线观看一区二区三区| 日韩在线不卡视频| 美女高潮在线观看| 91久久精品久久国产性色也91| 噜噜噜天天躁狠狠躁夜夜精品 | 亚洲欧洲一区| 国产乱女淫av麻豆国产| ww亚洲ww在线观看国产| 欧美波霸videosex极品| 亚洲va国产va欧美va观看| 一区二区三区免费观看视频| 亚洲男人天堂2023| 牛牛电影国产一区二区| 国产精品吴梦梦| 少妇精品导航| 日本大胆人体视频| 青椒成人免费视频| 99久久国产精| 亚洲国产精品麻豆| 中文字幕自拍偷拍| 精品一区二区亚洲| 波多一区二区| 亚洲综合在线小说| 国产精品传媒精东影业在线| 日本精品免费在线观看| 成人一区二区视频| 久久国产美女视频| 精品视频一区二区不卡| 免费av在线电影| 欧美夫妻性生活视频| 99久热在线精品视频观看| 色婷婷精品国产一区二区三区| 一区二区三区高清视频在线观看| 美女网站视频在线观看| 亚洲黄色免费网站| 国产99视频在线| 久久亚洲精品中文字幕冲田杏梨| 欧美xnxx| 日韩中文不卡| 日日嗨av一区二区三区四区| 亚洲天堂网一区二区| 香蕉乱码成人久久天堂爱免费| 国产成人精品一区二三区四区五区 | 日韩欧美一起| 亚洲自拍偷拍区| 小小影院久久| 亚洲色图欧美自拍| 亚洲色图欧洲色图婷婷| 一级全黄裸体免费视频| 伊人青青综合网站| 午夜av成人| 日韩国产精品一区二区三区| 丝袜脚交一区二区| 人妻一区二区视频| 在线观看国产日韩| av在线日韩国产精品| 国产精品美女久久久免费| 精品一区电影| 日本肉体xxxx裸体xxx免费| 国产精品日产欧美久久久久| 伊人色综合久久久| 久久精品人人爽| 玖玖精品一区| 丁香色欲久久久久久综合网| 成人午夜激情在线| 91蜜桃视频在线观看| 亚洲精品在线不卡| 另类中文字幕国产精品| 一区二区三区视频| 国产99精品国产| 亚洲精品视频在线观看免费视频| 日韩精品在线免费观看| 亚洲综合在线电影| 亚洲自拍的二区三区| 国产成人99久久亚洲综合精品| 国产一级在线播放| 亚洲人成欧美中文字幕| 午夜精品久久久久久毛片| 97超碰免费观看| av在线这里只有精品| 自拍偷拍色综合| 美女少妇精品视频| 日韩欧美黄色| 中文字幕久久av| 婷婷久久综合九色综合绿巨人| 韩日视频在线| 91九色偷拍| 久色成人在线| 97成人资源站| 日韩精品中文字幕在线观看| 成人国产精品| 精品国产av无码一区二区三区| 久久久久一区二区三区四区| 一级做a爰片久久毛片16| 欧美精品xxx| 国内成人自拍| 亚洲精品一二三四| 91豆麻精品91久久久久久| 伊人春色在线观看| 欧美一区少妇| 国产成人午夜精品5599| 性色av免费观看| 欧美精品久久久久久久久| 日韩欧美中字| 特级西西人体wwwww| 欧美一区午夜视频在线观看 | 精品不卡视频| 天天操天天舔天天射| 精品欧美一区二区在线观看| 中文字幕日本一区二区| 国产伦精品一区二区三区四区视频_| 国产精品久久久久国产精品日日| 天天射,天天干|