VFS之基本資料結構

2021-07-26 17:27:08 字數 3996 閱讀 4949

檔案系統

是一種儲存和組織計算機中檔案資料的一系列抽象資料型別,它們用來實現資料的儲存、管理、檢視、等功能。在

linux

系統中,所有的裝置、程序都是以檔案的形式存在,字元裝置、塊裝置以及這些裝置的驅動均要依靠檔案系統來實現,裝置管理的基礎框架也要以來檔案系統(sysfs),所以檔案系統在linux

作業系統

中擔任著重大的作用。

linux核心通過虛擬檔案系統(virtual file system,vfs)管理檔案系統。vfs對所有的檔案系統(如ext3、ext2等)提供了乙個統一的介面,它在linux檔案系統中擔任著及其重要的角色,是乙個不可或缺的基礎設施;在檔案系統的訪問操作中,必須通過虛擬檔案系統提供的介面才能實現正常的檔案操作。同時,在linux作業系統中,對於所有的檔案系統都要遵循虛擬檔案系統vfs定義的方式實現。

vfs與具體檔案系統的關係

vfs支援三種型別的檔案系統:基於磁碟的檔案系統、特殊的檔案系統和網路檔案系統。

vfs通用檔案模型包含有4種基本的資料結構,通過這幾個資料結構實現將硬碟上的檔案抽象到記憶體中:

這四個資料結構的關係如圖所示:

超級塊代表了整個檔案系統本身。super_block儲存了linux檔案系統設定的操作函式還有檔案塊的大小等資訊;super_block是檔案系統自己的控制塊結構,它的煉表頭鏈結來檔案系統中的所有inode。由於控制塊對於乙個具體的檔案系統來說,有可能還包含其它的資訊;想要找到這些資訊,我們就可以通過超級塊super_block物件進行查詢。

由於超級塊super_block是具體物理檔案系統super_block超級塊在記憶體的抽象,因而需要物理檔案系統的超級塊來獲取超級快的內容。

super_operations 提供了最重要的超級塊操作。例如super_operation 的成員函式read_inode提供了讀取inode 資訊的功能。vfs虛擬檔案系統提供了檔案系統的架構,具體的物理檔案系統就要遵循這個定義好的架構來實現。super_operations函式是每個檔案系統都要提供的乙個函式,因為要通過它來獲取inode的資訊。

struct super_block ;
inode代表乙個檔案。inode記錄了檔案的基本資訊,包括檔案建立時間、大小、使用者、塊大小等引數,以及對檔案的讀寫快取和讀寫函式等資訊。由於考慮到檔案系統中存在檔案的鏈結,所以說乙個物理檔案系統可能會有多個目錄項dentry,指向多個檔案的路徑;而inode就只有乙個。

索引節點inode的資料結構非常龐大,下邊介紹介個比較重要的結構成員。inode的結構定義如下:

inode的**資料結構

struct inode ;

__u32 i_generation; /* inode版本號(由某些檔案系統使用) */

#ifdef config_fsnotify

__u32 i_fsnotify_mask; /* all events this inode cares about */

struct hlist_head i_fsnotify_mark_entries; /* fsnotify mark entries */

#endif

#ifdef config_inotify

struct list_head inotify_watches; /* watches on this inode */

struct mutex inotify_mutex; /* protects the watches list */

#endif

unsigned long i_state; /* inode的狀態標誌 */

unsigned long dirtied_when; /* jiffies of first dirtying */

unsigned int i_flags; /* 檔案系統的安裝標誌 */

atomic_t i_writecount; /* 用於寫程序的引用計數器 */

#ifdef config_security

void *i_security; /* 指向inode安全結構的指標 */

#endif

#ifdef config_fs_posix_acl

struct posix_acl *i_acl;

struct posix_acl *i_default_acl;

#endif

void *i_private; /* fs or device private pointer */

};

dentry的中文名是目錄項,它是linux中索引節點的鏈結。直觀一點來看,大多數的檔案系統都是以樹狀結構儲存;目錄遞迴儲存,一層一層的,從樹根目錄開始,直到目錄的最底層檔案;而在linux系統中dentry就反應了檔案系統中目錄和檔案的樹狀關係。

在linux系統中所有的東西都是以檔案的形式存在,同樣在虛擬檔案系統中,目錄也相當於乙個檔案。根目錄有乙個目錄項結構,並且每乙個檔案也都至少有乙個目錄項,一層一層遞迴,下級目錄或檔案鏈結到上級目錄的dentry,二級目錄、**目錄同樣如此,從而形成乙個樹狀結構,並且可以通過根目錄項遍歷所有的檔案和目錄。

在linux中有乙個稱為dentry cache的東西,是核心使用雜湊表對dentry進行快取,以便加快系統對dentry的查詢。由於目錄項的查詢經常都是先在dentry cache中進行的,所以dentry cache在檔案的操作中是經常會被用到的。

dentry目錄項和super_block的結構定義類似,很複雜,下邊會列出一些比較重要的部分。簡化後的dentry結構定義如下:

dentry架構的簡化定義

struct dentry  d_u;

struct list_head d_subdirs; /* our children */

struct list_head d_alias; /* inode alias list */

unsigned

long d_time; /* used by d_revalidate */

const

struct dentry_operations *d_op;

struct super_block *d_sb; /* the root of the dentry tree */

void *d_fsdata; /* fs-specific data */

unsigned

char d_iname[dname_inline_len_min]; /* 存放短檔名的空間 */

};

對dentry結構的成員解釋如下。

描述檔案和程序互動的關係就是檔案物件的作用。實際上,在硬碟上就不存在乙個檔案結構。對於同乙個檔案,在不一樣的程序中就有不一樣的檔案物件;在使用者程序開啟乙個檔案時,系統核心就會動態的建立乙個對應的檔案物件。

檔案的資料結構

struct file  ;
在使用者態使用read函式時,核心會根據具體系統呼叫來選擇對應的處理函式(即就是read函式)。

syscall_define3(read, unsigned int, fd, char __user *, buf, size_t, count)

return ret;

}

vfs_read函式根據file物件當前操作指標的位置得到f_op(file_operations結構體)的指標,從而獲得file_operations結構體中的read操作函式,對檔案進行read操作,將核心讀取的檔案內容存入char __user* buf指向的記憶體位址

inc_syscr(current);

}return ret;}

redis基本資料結構之ZSet

zset資料結構類似於set結構,只是zset結構中,每個元素都會有乙個分值,然後所有元素按照分值的大小進行排列,相當於是乙個進行了排序的鍊錶。如果zset是乙個鍊錶,而且內部元素是有序的,在進行元素插入和刪除,以及查詢的時候,就必須要遍歷鍊錶才行,時間複雜度就達到了o n 這個在以單執行緒處理的r...

Redis基本資料結構之ZSet

zset保留了集合不能有重複成員的特性,但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下標作為排序依據不同的是,它給每個元素設定乙個分數 score 作為排序的依據。有序集合中的元素不能重複,但是score可以重複,就和乙個班裡的同學學號不能重複,但是考試成績可以相同。新增元素 命令為 ...

Redis基本資料結構之List

列表 list 型別是用來儲存多個有序的字串。在 redis 中,可以對列表的兩端進行插入 push 和彈出 pop 操作,還可以獲取指定範圍的元素列表 獲取指定索引下標的元素等。列表是一種比較靈活的資料結構,它可以充當棧和佇列的角色,在實際開發上有很多應用場景。如圖所示,a b c d e 五個元...