1、首先了解下block,對於ext2(ext3)文件系統而言,硬盤分區首先被劃分爲一個個的block,同一個ext2文件系統上的每個block大小都是一樣的。但是對於不同的ext2文件系統,block的大小可以有區別。典型的block大小是1024 bytes或者4096 bytes。這個大小在創建ext2、ext3文件系統的時候被決定,mkfs –t ext2/3 –b xx就可以設定塊大小了!一個硬盤分區上的block計數是從0開始的,總的來說,block這個概念好理解。
2、理解了block的概念後,接着就是對block group的理解,硬盤分區上所有的block被聚在一起分成幾個大的block group。其中每個block group中有多少個block是固定的。從上面的圖可以看出來!每個block group都相對應一個group descriptor,每個group descriptor當中有幾個重要的block指針,指向block group中的inode table、block bitmap和inode bitmap。
以上三個結構記載了其所屬block group的許多信息。
3、下面就是對super block的理解了
Super block即爲超級塊,它是硬盤分區開頭——開頭的第一個byte是byte 0,從 byte 1024開始往後的一部分數據。由於block size最小是 1024 bytes,所以super block可能是在block 1中(此時block 的大小正好是 1024 bytes)
超級塊中的數據其實就是文件卷的控制信息部分,也可以說它是卷資源表,有關文件卷的大部分信息都保存在這裏。例如:硬盤分區中每個block的大小、硬盤分區上一共有多少個block group、以及每個block group中有多少個inode。
對於super block的結構和涵義可以通過查看/usr/include/linux/ext3_fs.h文件:
通過set number:
386 struct ext3_super_block {
386 struct ext3_super_block {
387 /*00*/ __le32 s_inodes_count; /* Inodes count */
388 __le32 s_blocks_count; /* Blocks count */
389 __le32 s_r_blocks_count; /* Reserved blocks count */
390 __le32 s_free_blocks_count; /* Free blocks count */
391 /*10*/ __le32 s_free_inodes_count; /* Free inodes count */
392 __le32 s_first_data_block; /* First Data Block */
393 __le32 s_log_block_size; /* Block size */
394 __le32 s_log_frag_size; /* Fragment size */
395 /*20*/ __le32 s_blocks_per_group; /* # Blocks per group */
396 __le32 s_frags_per_group; /* # Fragments per group */
397 __le32 s_inodes_per_group; /* # Inodes per group */
398 __le32 s_mtime; /* Mount time */
399 /*30*/ __le32 s_wtime; /* Write time */
400 __le16 s_mnt_count; /* Mount count */
401 __le16 s_max_mnt_count; /* Maximal mount count */
402 __le16 s_magic; /* Magic signature */
403 __le16 s_state; /* File system state */
404 __le16 s_errors; /* Behaviour when detecting errors */
405 __le16 s_minor_rev_level; /* minor revision level */
406 /*40*/ __le32 s_lastcheck; /* time of last check */
407 __le32 s_checkinterval; /* max. time between checks */
408 __le32 s_creator_os; /* OS */
409 __le32 s_rev_level; /* Revision level */
410 /*50*/ __le16 s_def_resuid; /* Default uid for reserved blocks */
411 __le16 s_def_resgid; /* Default gid for reserved blocks */
struct vfsmount {
struct list_head mnt_hash;struct vfsmount *mnt_parent; /* fs we are mounted on */
struct dentry *mnt_mountpoint; /* dentry of mountpoint */
struct dentry *mnt_root; /* root of the mounted tree */
struct super_block *mnt_sb; /* pointer to superblock */
struct list_head mnt_mounts; /* list of children, anchored here */
struct list_head mnt_child; /* and going through their mnt_child */
int mnt_flags;
/* 4 bytes hole on 64bits arches */
const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
struct list_head mnt_list;
struct list_head mnt_expire; /* link in fs-specific expiry list */
struct list_head mnt_share; /* circular list of shared mounts */
struct list_head mnt_slave_list;/* list of slave mounts */
struct list_head mnt_slave; /* slave list entry */
struct vfsmount *mnt_master; /* slave is on master->mnt_slave_list */
struct mnt_namespace *mnt_ns; /* containing namespace */
atomic_t __mnt_writers;
...
};
1 vfsmount結構描述的是一個獨立文件系統的掛載信息,每個不同掛載點對應一個獨立的vfsmount結構,屬於同一文件系統的所有目錄和文件隸屬於同一個vfsmount,該vfsmount結構對應於該文件系統頂層目錄,即掛載目錄
2 比如對於mount /dev/sdb1 /media/Kingston,掛載點爲/media/Kingston,對於Kingston這個目錄,其產生新的vfsmount,獨立於根文件系統掛載點/所在的vfsmount;
3 所有的vfsmount掛載點通過mnt_list雙鏈表掛載於mnt_namespace->list鏈表中,該mnt命名空間可以通過任意進程獲得
4 子vfsmount掛載點結構通過mnt_mounts掛載於父vfsmount的mnt_child鏈表中,並且mnt_parent直接指向父親fs的vfsmount結構,從而形成層次結構
5 vfsmount的super_block結構->statfs函數可以獲得該文件系統中空間的使用情況
6 對於掛載點/media/Kingston來講,其vfsmount->mnt_root->f_dentry->d_name.name = '/';而vfsmount->mnt_mountpoint->f_dentry->d_name.name = 'Kingston'。對於/media/Kingston下的所有目錄和文件而言,都是這樣的。
進程每打開一個文件,就會有一個file結構與之對應。同一個進程可以多次打開同一個文件而得到多個不同的file結構,file結構描述了被打開文件的屬性,讀寫的偏移指針等等當前信息。
兩個不同的file結構可以對應同一個dentry結構。進程多次打開同一個文件時,對應的只有一個dentry結構。Dentry結構存儲目錄項和對應文件(inode)的信息。
在存儲介質中,每個文件對應唯一的inode結點,但是,每個文件又可以有多個文件名。即可以通過不同的文件名訪問同一個文件。這裏多個文件名對應一個文件的關係在數據結構中表示就是dentry和inode的關係。
Inode中不存儲文件的名字,它只存儲節點號;而dentry則保存有名字和與其對應的節點號,所以就可以通過不同的dentry訪問同一個inode。
不同的dentry則是同個文件鏈接(ln命令)來實現的。
目錄項對象
每個文件除了有一個索引節點inode數據結構外,還有一個目錄項dentry(directory enrty)數據結構。dentry 結構中有個d_inode指針指向相應的inode結構。讀者也許會問,既然inode結構和dentry結構都是對文件各方面屬性的描述,那爲什麼不把這兩個結構“合而爲一”呢?這是因爲二者所描述的目標不同,dentry結構代表的是邏輯意義上的文件,所描述的是文件邏輯上的屬性,因此,目錄項對象在磁盤上並沒有對應的映像;而inode結構代表的是物理意義上的文件,記錄的是物理上的屬性,對於一個具體的文件系統(如Ext2),Ext2_ inode結構在磁盤上就有對應的映像。所以說,一個索引節點對象可能對應多個目錄項對象。
下面對dentry結構給出進一步的解釋。
一個有效的dentry結構必定有一個inode結構,這是因爲一個目錄項要麼代表着一個文件,要麼代表着一個目錄,而目錄實際上也是文件。