現在我們的主流價值觀是社會和諧、世界和諧。同樣,Linux成功的關鍵因素之一是它具有與其他動作系統和諧共存的能力。你能夠透明地安裝具有其他動作系統檔案格式的磁碟或分區,這些作業系統如Windows、其他版本的Unix,甚至像Amiga那樣的市場佔有率很低的系統。通過所謂的虛擬檔案系統概念,Linux使用與其他Unix變體相同的方式設法支援多種檔案系統類型。
虛擬檔案系統所隱含的思想是把表示很多不同種類檔案系統的共同資訊放入核心;其中有一個欄位或函數來支援Linux所支援的所有實際檔案系統所提供的任何操作。對所調用的每個讀、寫或其他函數,核心都能把它們替換成支援本地Linux檔案系統、NTFS檔案系統,或者檔案所在的任何其他檔案系統的實際函數。 1 虛擬檔案系統概述
虛擬檔案系統(Virtual Filesystem)也可以稱之為虛擬檔案系統轉換(Virtual Filesystem Switch,VFS),是一個核心軟體層,用來處理與Unix標準檔案系統相關的所有系統調用。其健壯性表現在能為各種檔案系統提供一個通用的介面。
例如,假設一個使用者輸入以下shell命令:
$ cp /floppy/TEST /tmp/test
其中/floppy是MS-DOS磁碟的一個安裝點,而/tmp是一個標準的第二擴充檔案系統(second Extended Filesystom, Ext2)的目錄。正(a)所示,VFS是使用者的應用程式與檔案系統實現之間的抽象層。因此,cp程式並不需要知道/floppy/TEST 和 /tmp/test是什麼檔案系統類型。相反,cp程式直接與VFS互動,這是通過Unix程式設計人員都熟悉的普通系統調用來進行的。cp的執行代碼(b)所示:
VFS支援的檔案系統可以劃分為三種主要類型:
磁碟檔案系統
這些檔案系統管理在本地磁碟分割中可用的儲存空間或者其他可以起到磁碟作用的裝置(比如說一個USB快閃記憶體)。VFS支援的基於磁碟的某些著名檔案系統還有:
- Linux使用的檔案系統,如廣泛使用的第二擴充檔案系統(Ext2),新近的第三擴充檔案系統(Third Extended Filesystem,Ext3)及Reiser檔案系統(ReiserFS)
- Unix家族的檔案系統,如sysv檔案系統(System V、Coherent、Xenix)、UFS(BSD、Solaris、NEXTSTEP),MINIX檔案系統及VERITAS VxFS(SCO UnixWare)。
- 微軟公司的檔案系統,如MS-DOS、VFAT(Windows 95及隨後的版本)及NTFS(Windows NT以及隨後的版本)。
- IS09660 CD-ROM檔案系統(以前的High Sierra檔案系統)和國際磁碟格式(UDF)的DVD檔案系統。
- 其他有專利權的檔案系統,如HPFS(IBM公司的OS/2)、HFS(蘋果公司的Macintosh)、AFFS(Amiga公司的快速檔案系統)以及ADFS(Acorn 公司的磁碟檔案歸檔系統)。
- 起源於非Linux系統的其他記錄檔系統,如IBM的JFS和SGI的XFS。
網路檔案系統
這些檔案系統允許輕易地訪問屬於其他網路電腦的檔案系統所包含的檔案。虛擬檔案系統所支援的一些著名的網路檔案系統有:NFS、Coda、AFS(Andrew檔案系統)、CIFS(用於Microsoft Windows的通用網路檔案系統)以及NCP(Novell公司的NetWare Core Protocol)。
特殊檔案系統
這些檔案系統不管理本地或者遠程磁碟空間。/proc、/sys、/dev等檔案系統是特殊檔案系統的一個典型範例。
Unix的目錄建立了一棵根目錄為“/”的樹。根目錄包含在根檔案系統(root filesystem)中,在Linux中這個根檔案系統通常就是Ext2或Ext3類型。其他所有的檔案系統都可以被“安裝”在根檔案系統的子目中。
當一個檔案系統被安裝在某一個目錄上時,在父檔案系統中的目錄內容不再是可訪問的了,因為任何路徑(包括安裝點),都將引用已安裝的檔案系統。但是,當被安裝檔案系統卸載時,原目錄的內容又可再現。
==》mount 一個新的檔案系統的時候
所以,Unix檔案系統的一個重要特點就是可以由系統管理員用來隱藏檔案,他們只需把一個檔案系統安裝在要隱藏檔案的目錄中即可。
基於磁碟的檔案系統通常存放在塊裝置中,如硬碟、磁碟片或者CD-ROM。Linux VFS的一個有用特點是能夠處理如/dev/loop0這樣的虛擬塊裝置,這種裝置可以用來安裝普通檔案所在的檔案系統。作為一種可能的應用,使用者可以保護自己的私人檔案系統,因為可以通過把自己檔案系統的加密版本存放在一個普通檔案中來實現。
第一個虛擬檔案系統包含在1986年由Sun公司發布的SunOS作業系統中。從那時起,多數UNIX檔案系統都包含VFS。然而,Linux的VFS支援最廣泛的檔案系統。
2 通用檔案模型
VFS所隱含的主要思想在於引入了一個通用的檔案模型(common file model),這個模型能夠表示所有支援的檔案系統。該模型嚴格反映傳統Unix檔案系統提供的檔案模型。這並不奇怪,因為Linux希望以最小的額外開銷運行它的本地檔案系統。不過,要實現每個具體的檔案系統,必須將其物理組織圖轉換為虛擬檔案系統的通用檔案模型。
例如在通用檔案模型中,每個目錄被看作一個檔案,可以包含若干檔案和其他的子目錄。但是,存在幾個非Unix的基於磁碟的檔案系統,它們利用檔案配置表(File Allocation Table,FAT)存放每個檔案在分類樹中的位置,在這些檔案系統中,存放的是目錄而不是檔案。為了符合VFS的通用檔案模型,對上述基於FAT的檔案系統的實現,Linux必須在必要時能夠快速建立對應於目錄的檔案。這樣的檔案只作為核心記憶體的對象而存在。
從本質上說,Linux核心不能對一個特定的函數進行寫入程式碼來執行諸如read()或ioctl()這樣的操作,而是對每個操作都必須使用一個指標,指向要訪問的具體檔案系統的適當函數。
為了進一步說明這一概念,參見前面的那個圖,其中顯示了核心如何把read()轉換為專對MS-DOS檔案系統的一個調用。應用程式對read()的調用引起核心調用相應的sys_read()服務常式,這與其他系統調用完全類似。我們在本章後面會看到,檔案在核心記憶體中是由一個file資料結構來表示的。這種資料結構中包含一個稱為f_op的欄位,該欄位中包含一個指向專對MS-DOS檔案的函數指標,當然還包括讀檔案的函數。
sys_read()尋找到指向該函數的指標,並調用它。這樣一來,應用程式的read()就被轉化為相對間接的調用:
file->f_op->read(…);
與之類似,write()操作也會引發一個與輸出檔案相關的Ext2寫函數的執行。簡而言之,核心負責把一組合適的指標分配給與每個開啟檔案相關的file變數,然後負責調用針對每個具體檔案系統的函數(由f_op欄位指向)。
你可以把通用檔案模型看作是物件導向的,在這裡,對象是一個軟體結構,其中既定義了資料結構也定義了其上的操作方法。出於效率的考慮,Linux的編碼並未採用面向對像的程式設計語言(比如C++)。因此對象作為普通的C資料結構來實現,資料結構中指向函數的欄位就對應於對象的方法。
通用檔案模型由下列物件類型組成:
超級塊對象(superblock object):存放已安裝檔案系統的有關資訊。對基於磁碟的檔案系統,這類對象通常對應於存放在磁碟上的檔案系統控制塊(filesystem control block)。
索引節點對象(inode object):存放關於具體檔案的一般資訊。對基於磁碟的檔案系統,這類對象通常對應於在磁碟上的檔案控制區(file control block)。每個索引節點對象都有一個索引節點號,這個節點號唯一地標識檔案系統中的檔案。
檔案對象(file object):存放開啟檔案與進程之間進行互動的有關資訊。這類資訊僅當進程訪問檔案期間在於核心記憶體中。
目錄項對象(dentry object):存放目錄項(也就是檔案的特定名稱)與對應檔案進行連結的有關資訊。每個磁碟檔案系統都以自己特有的方式將該類資訊存在磁碟上。
所示是一個簡單的樣本,說明進程怎樣與檔案進行互動。
三個不同進程已經開啟同一個檔案,其中兩個進程使用同一個永久連結。在這種情況下,其中的每個進程都使用自己的檔案對象,但只需要兩個目錄項對象,每個永久連結對應一個目錄項對象。這兩個目錄項對象指向同一個索引節點對象,該索引節點對象標識超級塊對象,以及隨後的普通磁碟檔案。
VFS除了能為所有檔案系統的實現提供一個通用介面外,還具有另一個與系統效能相關的重要作用,那就是一些檔案相關資料結構的磁碟快取。例如最近最常使用的目錄項對象被放在所謂目錄項快取(dentry cache)的磁碟快取中,從而加速從檔案路徑名到最後一個路徑分量的索引節點的轉換過程。
一般說來,磁碟快取(disk cache)屬於軟體機制,它允許核心將原本存在磁碟上的某些資訊儲存在RAM中,以便對這些資料的進一步訪問能快速進行,而不必慢速訪問磁碟本身。
注意,磁碟快取不同於硬體快取或記憶體快取,後兩者都與磁碟或其他裝置無關。硬體快取是一個快速靜態RAM,它加快了直接對記憶體,這樣的慢速動態RAM的請求。記憶體快取是一種軟體機制,引入它是為了繞過核心記憶體 Clerk(slab分配器)。
除了目錄項快取和索引結點快取之外,Linux還使用其他磁碟快取。其中最重要的一種就是所謂的頁快取,我們將在本專題中中進行詳細介紹。
3 VFS所處理的系統調用
下表列出了VFS的系統調用,這些系統調用涉及檔案系統、普通檔案、目錄檔案以及符號連結檔案:
系統調用名 |
說明 |
mount( ) umount( ) umount2( ) |
安裝/卸載檔案系統 |
sysfs( ) |
擷取檔案系統資訊 |
statfs( ) fstatfs( ) statfs64( ) fstatfs64( ) ustat( ) |
擷取檔案系統統計資訊 |
chroot( ) pivot_root( ) |
更改根目錄 |
chdir( ) fchdir( ) getcwd( ) |
對目前的目錄進行操作 |
mkdir( ) rmdir( ) |
建立/刪除目錄 |
getdents( ) getdents64( ) readdir( ) link( ) unlink( ) rename( ) lookup_dcookie( ) |
對目錄項進行操作 |
readlink( ) symlink( ) |
對軟連結進行操作 |
chown( ) fchown( ) lchown( ) chown16( ) fchown16( ) lchown16( ) |
變更檔所有者性 |
chmod( ) fchmod( ) utime( ) |
變更檔屬性 |
stat( ) fstat( ) lstat( ) access( ) oldstat( ) oldfstat( ) oldlstat( ) stat64( ) lstat64( ) fstat64( ) |
讀取檔案狀態 |
open( ) close( ) creat( ) umask( ) |
開啟/關閉/建立檔案 |
dup( ) dup2( ) fcntl( ) fcntl64( ) |
對檔案描述符進行操作 |
select( ) poll( ) |
等待一組檔案描述符上發生的事件 |
truncate( ) ftruncate( ) truncate64( ) ftruncate64( ) |
變更檔長度 |
lseek( ) _llseek( ) |
變更檔指標 |
read( ) write( ) readv( ) writev( ) sendfile( ) sendfile64( ) readahead( ) |
進行檔案I/O 操作 |
io_setup( ) io_submit( ) io_getevents( ) io_cancel( ) io_destroy( ) |
非同步I/O (允許多個讀和寫請求) |
pread64( ) pwrite64( ) |
搜尋並訪問檔案 |
mmap( ) mmap2( ) munmap( ) madvise( ) mincore( ) remap_file_pages( ) |
處理檔案記憶體映射 |
fdatasync( ) fsync( ) sync( ) msync( ) |
同步檔案資料 |
flock( ) |
處理檔案鎖 |
setxattr( ) lsetxattr( ) fsetxattr( ) getxattr( ) lgetxattr( ) fgetxattr( ) listxattr( ) llistxattr( ) flistxattr( ) removexattr( ) lremovexattr( ) fremovexattr( ) |
處理檔案擴充屬性 |
另外還有少數幾個由VFS處理的其他系統調用,諸如ioperm()、ioctl()、pipe()和mknod(),涉及裝置檔案和管道檔案,這些將在後續博文中討論。最後一組由VFS處理的系統調用,諸如socket()、connect()和bind()屬於通訊端系統調用,並用於實現網路功能。與表中列出的系統調用還對應的一些核心服務常式,我們會在後面的博文中陸續進行討論。
前面我們已經提到,VFS是應用程式和具體檔案系統之間的一層。不過,在某些情況下,一個檔案操作可能由VFS本身去執行,無需調用低層函數。例如,當某個進程關閉一個開啟的檔案時,並不需要涉及磁碟上的相應檔案,因此VFS只需釋放對應的檔案對象。類似地,當系統調用lseek()修改一個檔案指標,而這個檔案指標是開啟檔案與進程互動所涉及的一個屬性時,VFS就只需修改對應的檔案對象,而不必訪問磁碟上的檔案,因此,無需調用具體檔案系統的函數。從某種意義上說,可以把VFS看成“通用”檔案系統,它在必要時依賴某種具體檔案系統。
虛擬檔案系統(Virtual Filesystem)也可以稱之為虛擬檔案系統轉換(Virtual Filesystem Switch,VFS),是一個核心軟體層,用來處理與Unix標準檔案系統相關的所有系統調用。其健壯性表現在能為各種檔案系統提供一個通用的介面。
例如,假設一個使用者輸入以下shell命令:
$ cp /floppy/TEST /tmp/test
其中/floppy是MS-DOS磁碟的一個安裝點,而/tmp是一個標準的第二擴充檔案系統(second Extended Filesystom, Ext2)的目錄。正(a)所示,VFS是使用者的應用程式與檔案系統實現之間的抽象層。因此,cp程式並不需要知道/floppy/TEST 和 /tmp/test是什麼檔案系統類型。相反,cp程式直接與VFS互動,這是通過Unix程式設計人員都熟悉的普通系統調用來進行的。cp的執行代碼(b)所示:
VFS支援的檔案系統可以劃分為三種主要類型:
磁碟檔案系統
這些檔案系統管理在本地磁碟分割中可用的儲存空間或者其他可以起到磁碟作用的裝置(比如說一個USB快閃記憶體)。VFS支援的基於磁碟的某些著名檔案系統還有:
- Linux使用的檔案系統,如廣泛使用的第二擴充檔案系統(Ext2),新近的第三擴充檔案系統(Third Extended Filesystem,Ext3)及Reiser檔案系統(ReiserFS)
- Unix家族的檔案系統,如sysv檔案系統(System V、Coherent、Xenix)、UFS(BSD、Solaris、NEXTSTEP),MINIX檔案系統及VERITAS VxFS(SCO UnixWare)。
- 微軟公司的檔案系統,如MS-DOS、VFAT(Windows 95及隨後的版本)及NTFS(Windows NT以及隨後的版本)。
- IS09660 CD-ROM檔案系統(以前的High Sierra檔案系統)和國際磁碟格式(UDF)的DVD檔案系統。
- 其他有專利權的檔案系統,如HPFS(IBM公司的OS/2)、HFS(蘋果公司的Macintosh)、AFFS(Amiga公司的快速檔案系統)以及ADFS(Acorn 公司的磁碟檔案歸檔系統)。
- 起源於非Linux系統的其他記錄檔系統,如IBM的JFS和SGI的XFS。
網路檔案系統
這些檔案系統允許輕易地訪問屬於其他網路電腦的檔案系統所包含的檔案。虛擬檔案系統所支援的一些著名的網路檔案系統有:NFS、Coda、AFS(Andrew檔案系統)、CIFS(用於Microsoft Windows的通用網路檔案系統)以及NCP(Novell公司的NetWare Core Protocol)。
特殊檔案系統
這些檔案系統不管理本地或者遠程磁碟空間。/proc、/sys、/dev等檔案系統是特殊檔案系統的一個典型範例。
Unix的目錄建立了一棵根目錄為“/”的樹。根目錄包含在根檔案系統(root filesystem)中,在Linux中這個根檔案系統通常就是Ext2或Ext3類型。其他所有的檔案系統都可以被“安裝”在根檔案系統的子目中。
當一個檔案系統被安裝在某一個目錄上時,在父檔案系統中的目錄內容不再是可訪問的了,因為任何路徑(包括安裝點),都將引用已安裝的檔案系統。但是,當被安裝檔案系統卸載時,原目錄的內容又可再現。
==》mount 一個新的檔案系統的時候
所以,Unix檔案系統的一個重要特點就是可以由系統管理員用來隱藏檔案,他們只需把一個檔案系統安裝在要隱藏檔案的目錄中即可。
基於磁碟的檔案系統通常存放在塊裝置中,如硬碟、磁碟片或者CD-ROM。Linux VFS的一個有用特點是能夠處理如/dev/loop0這樣的虛擬塊裝置,這種裝置可以用來安裝普通檔案所在的檔案系統。作為一種可能的應用,使用者可以保護自己的私人檔案系統,因為可以通過把自己檔案系統的加密版本存放在一個普通檔案中來實現。
第一個虛擬檔案系統包含在1986年由Sun公司發布的SunOS作業系統中。從那時起,多數UNIX檔案系統都包含VFS。然而,Linux的VFS支援最廣泛的檔案系統。
2 通用檔案模型
VFS所隱含的主要思想在於引入了一個通用的檔案模型(common file model),這個模型能夠表示所有支援的檔案系統。該模型嚴格反映傳統Unix檔案系統提供的檔案模型。這並不奇怪,因為Linux希望以最小的額外開銷運行它的本地檔案系統。不過,要實現每個具體的檔案系統,必須將其物理組織圖轉換為虛擬檔案系統的通用檔案模型。
例如在通用檔案模型中,每個目錄被看作一個檔案,可以包含若干檔案和其他的子目錄。但是,存在幾個非Unix的基於磁碟的檔案系統,它們利用檔案配置表(File Allocation Table,FAT)存放每個檔案在分類樹中的位置,在這些檔案系統中,存放的是目錄而不是檔案。為了符合VFS的通用檔案模型,對上述基於FAT的檔案系統的實現,Linux必須在必要時能夠快速建立對應於目錄的檔案。這樣的檔案只作為核心記憶體的對象而存在。
從本質上說,Linux核心不能對一個特定的函數進行寫入程式碼來執行諸如read()或ioctl()這樣的操作,而是對每個操作都必須使用一個指標,指向要訪問的具體檔案系統的適當函數。
為了進一步說明這一概念,參見前面的那個圖,其中顯示了核心如何把read()轉換為專對MS-DOS檔案系統的一個調用。應用程式對read()的調用引起核心調用相應的sys_read()服務常式,這與其他系統調用完全類似。我們在本章後面會看到,檔案在核心記憶體中是由一個file資料結構來表示的。這種資料結構中包含一個稱為f_op的欄位,該欄位中包含一個指向專對MS-DOS檔案的函數指標,當然還包括讀檔案的函數。
sys_read()尋找到指向該函數的指標,並調用它。這樣一來,應用程式的read()就被轉化為相對間接的調用:
file->f_op->read(…);
與之類似,write()操作也會引發一個與輸出檔案相關的Ext2寫函數的執行。簡而言之,核心負責把一組合適的指標分配給與每個開啟檔案相關的file變數,然後負責調用針對每個具體檔案系統的函數(由f_op欄位指向)。
你可以把通用檔案模型看作是物件導向的,在這裡,對象是一個軟體結構,其中既定義了資料結構也定義了其上的操作方法。出於效率的考慮,Linux的編碼並未採用面向對像的程式設計語言(比如C++)。因此對象作為普通的C資料結構來實現,資料結構中指向函數的欄位就對應於對象的方法。
通用檔案模型由下列物件類型組成:
超級塊對象(superblock object):存放已安裝檔案系統的有關資訊。對基於磁碟的檔案系統,這類對象通常對應於存放在磁碟上的檔案系統控制塊(filesystem control block)。
索引節點對象(inode object):存放關於具體檔案的一般資訊。對基於磁碟的檔案系統,這類對象通常對應於在磁碟上的檔案控制區(file control block)。每個索引節點對象都有一個索引節點號,這個節點號唯一地標識檔案系統中的檔案。
檔案對象(file object):存放開啟檔案與進程之間進行互動的有關資訊。這類資訊僅當進程訪問檔案期間在於核心記憶體中。
目錄項對象(dentry object):存放目錄項(也就是檔案的特定名稱)與對應檔案進行連結的有關資訊。每個磁碟檔案系統都以自己特有的方式將該類資訊存在磁碟上。
所示是一個簡單的樣本,說明進程怎樣與檔案進行互動。
三個不同進程已經開啟同一個檔案,其中兩個進程使用同一個永久連結。在這種情況下,其中的每個進程都使用自己的檔案對象,但只需要兩個目錄項對象,每個永久連結對應一個目錄項對象。這兩個目錄項對象指向同一個索引節點對象,該索引節點對象標識超級塊對象,以及隨後的普通磁碟檔案。
VFS除了能為所有檔案系統的實現提供一個通用介面外,還具有另一個與系統效能相關的重要作用,那就是一些檔案相關資料結構的磁碟快取。例如最近最常使用的目錄項對象被放在所謂目錄項快取(dentry cache)的磁碟快取中,從而加速從檔案路徑名到最後一個路徑分量的索引節點的轉換過程。
一般說來,磁碟快取(disk cache)屬於軟體機制,它允許核心將原本存在磁碟上的某些資訊儲存在RAM中,以便對這些資料的進一步訪問能快速進行,而不必慢速訪問磁碟本身。
注意,磁碟快取不同於硬體快取或記憶體快取,後兩者都與磁碟或其他裝置無關。硬體快取是一個快速靜態RAM,它加快了直接對記憶體,這樣的慢速動態RAM的請求。記憶體快取是一種軟體機制,引入它是為了繞過核心記憶體 Clerk(slab分配器)。
除了目錄項快取和索引結點快取之外,Linux還使用其他磁碟快取。其中最重要的一種就是所謂的頁快取,我們將在本專題中中進行詳細介紹。
3 VFS所處理的系統調用
下表列出了VFS的系統調用,這些系統調用涉及檔案系統、普通檔案、目錄檔案以及符號連結檔案:
系統調用名 |
說明 |
mount( ) umount( ) umount2( ) |
安裝/卸載檔案系統 |
sysfs( ) |
擷取檔案系統資訊 |
statfs( ) fstatfs( ) statfs64( ) fstatfs64( ) ustat( ) |
擷取檔案系統統計資訊 |
chroot( ) pivot_root( ) |
更改根目錄 |
chdir( ) fchdir( ) getcwd( ) |
對目前的目錄進行操作 |
mkdir( ) rmdir( ) |
建立/刪除目錄 |
getdents( ) getdents64( ) readdir( ) link( ) unlink( ) rename( ) lookup_dcookie( ) |
對目錄項進行操作 |
readlink( ) symlink( ) |
對軟連結進行操作 |
chown( ) fchown( ) lchown( ) chown16( ) fchown16( ) lchown16( ) |
變更檔所有者性 |
chmod( ) fchmod( ) utime( ) |
變更檔屬性 |
stat( ) fstat( ) lstat( ) access( ) oldstat( ) oldfstat( ) oldlstat( ) stat64( ) lstat64( ) fstat64( ) |
讀取檔案狀態 |
open( ) close( ) creat( ) umask( ) |
開啟/關閉/建立檔案 |
dup( ) dup2( ) fcntl( ) fcntl64( ) |
對檔案描述符進行操作 |
select( ) poll( ) |
等待一組檔案描述符上發生的事件 |
truncate( ) ftruncate( ) truncate64( ) ftruncate64( ) |
變更檔長度 |
lseek( ) _llseek( ) |
變更檔指標 |
read( ) write( ) readv( ) writev( ) sendfile( ) sendfile64( ) readahead( ) |
進行檔案I/O 操作 |
io_setup( ) io_submit( ) io_getevents( ) io_cancel( ) io_destroy( ) |
非同步I/O (允許多個讀和寫請求) |
pread64( ) pwrite64( ) |
搜尋並訪問檔案 |
mmap( ) mmap2( ) munmap( ) madvise( ) mincore( ) remap_file_pages( ) |
處理檔案記憶體映射 |
fdatasync( ) fsync( ) sync( ) msync( ) |
同步檔案資料 |
flock( ) |
處理檔案鎖 |
setxattr( ) lsetxattr( ) fsetxattr( ) getxattr( ) lgetxattr( ) fgetxattr( ) listxattr( ) llistxattr( ) flistxattr( ) removexattr( ) lremovexattr( ) fremovexattr( ) |
處理檔案擴充屬性 |
另外還有少數幾個由VFS處理的其他系統調用,諸如ioperm()、ioctl()、pipe()和mknod(),涉及裝置檔案和管道檔案,這些將在後續博文中討論。最後一組由VFS處理的系統調用,諸如socket()、connect()和bind()屬於通訊端系統調用,並用於實現網路功能。與表中列出的系統調用還對應的一些核心服務常式,我們會在後面的博文中陸續進行討論。
前面我們已經提到,VFS是應用程式和具體檔案系統之間的一層。不過,在某些情況下,一個檔案操作可能由VFS本身去執行,無需調用低層函數。例如,當某個進程關閉一個開啟的檔案時,並不需要涉及磁碟上的相應檔案,因此VFS只需釋放對應的檔案對象。類似地,當系統調用lseek()修改一個檔案指標,而這個檔案指標是開啟檔案與進程互動所涉及的一個屬性時,VFS就只需修改對應的檔案對象,而不必訪問磁碟上的檔案,因此,無需調用具體檔案系統的函數。從某種意義上說,可以把VFS看成“通用”檔案系統,它在必要時依賴某種具體檔案系統。