1. 程式人生 > >vfs inode和磁碟inode

vfs inode和磁碟inode

在容易引起混淆的地方我將把把記憶體中的inode結構稱為VFS inode,而檔案
系統以EXT2為代表,把Ext2 inode作為磁碟上的inode代表。
首先需要分別對記憶體中的inode與磁碟上的inode做一下簡單的描述:
<記憶體中的inode結構:>
   VFS inode包含檔案訪問許可權、屬主、組、大小、生成時間、訪問時間、
最後修改時間等資訊。它是linux管理檔案系統的最基本單位,也是檔案系
統連線任何子目錄、檔案的橋樑。inode結構中的靜態資訊取自物理裝置上
的檔案系統,由檔案系統指定的函式填寫,它只存在於記憶體中,可以通過
inode快取訪問。雖然每個檔案都有相應的inode結點,但是隻有在需要的時
候系統才會在記憶體中為其建立相應的inode資料結構,建立的inode結構將形
成一個連結串列,我們可以通過遍歷這個連結串列去得到我們需要的檔案結點,VFS也
為已分配的inode構造快取和hash table,以提高系統性能。inode結構中的
struct inode_operations *iop為我們提供了一個inode操作列表,通過這個
列表提供的函式我們可以對VFS inode結點進行各種操作。每個inode結構都
有一個i結點號i_ino,在同一個檔案系統中每個i結點號是唯一的。

<磁碟上的inode:>
   EXT2通過使用inode來定義檔案系統的結構以及描述系統中每個檔案的
管理資訊,每個檔案都有一個inode且只有一個,即使檔案中沒有資料,其
索引結點也是存在的。每個檔案用一個單獨的Ext2 inode結構來描述,而且
每一個inode都有唯一的標誌號。Ext2 inode為記憶體中的inode結構提供了文
件的基本資訊,隨著記憶體中inode結構的變化,系統也將更新Ext2 inode中
相應的內容。Ext2 inode對應的是Ext2_inode結構。

從上面的描述,我們可以對記憶體中inode與磁碟中inode做出比較:
位置:VFS inode結構位於記憶體中,而Ext2_inode位於磁碟。
生存期:VFS inode在需要時才會被建立,如果系統斷電,此結構也隨之消失。
       而Ext2_inode的存在與系統是否上電無關,而且無論檔案是否包含
       資料,Ext2_inode都是存在的。
唯一性:兩者在自己的作用域中都是唯一的。
關係:VFS inode是Ext2 inode的抽象、對映與擴充,而後者是前者的靜態
     資訊部分,也是對前者的具體化、例項化和持久化。
操作:對VFS inode的操作具有通用性,對檔案系統inode的操作則是檔案系
     統相關的,依賴於特定的實現。
組織管理:系統通過VFS inode連結串列來對其進行組織,並且為了提高訪問效率
         相應地構造了inode構造快取和hash table。
         Ext2 inode的資訊位於EXT2檔案系統的劃分的塊組中,在每個塊組
         中包含相應的inode點陣圖、inode表指定具體的inode資訊,每個
         inode對應Ext2_inode結構。

上面是從原理上對記憶體中inode與磁碟中inode進行比較,實際上在程式碼上也體
現出它們的不同。在下面我把在核心中兩者對應的結構程式碼貼出來,雖然長了
一些,但是對進一步的比較還是很有好處。
struct inode {
struct list_headi_hash;
struct list_headi_list;
struct list_headi_dentry;

struct list_headi_dirty_buffers;

unsigned longi_ino;
atomic_ti_count;
kdev_ti_dev;
umode_ti_mode;
nlink_ti_nlink;
uid_ti_uid;
gid_ti_gid;
kdev_ti_rdev;
loff_ti_size;
time_ti_atime;
time_ti_mtime;
time_ti_ctime;
unsigned longi_blksize;
unsigned longi_blocks;
unsigned longi_version;
unsigned shorti_bytes;
struct semaphorei_sem;
struct rw_semaphorei_truncate_sem;
struct semaphorei_zombie;
struct inode_operations*i_op;
struct file_operations*i_fop;/* former ->i_op->default_file_ops */
struct super_block*i_sb;
wait_queue_head_ti_wait;
struct file_lock*i_flock;
struct address_space*i_mapping;
struct address_spacei_data;
struct dquot*i_dquot[MAXQUOTAS];
/* These three should probably be a union */
struct pipe_inode_info*i_pipe;
struct block_device*i_bdev;
struct char_device*i_cdev;

unsigned longi_dnotify_mask; /* Directory notify events */
struct dnotify_struct*i_dnotify; /* for directory notifications */

unsigned longi_state;

unsigned inti_flags;
unsigned chari_sock;

atomic_ti_writecount;
unsigned inti_attr_flags;
__u32i_generation;
union {
struct minix_inode_infominix_i;
struct ext2_inode_infoext2_i;
struct ext3_inode_infoext3_i;
struct hpfs_inode_infohpfs_i;
struct ntfs_inode_infontfs_i;
struct msdos_inode_infomsdos_i;
struct umsdos_inode_infoumsdos_i;
struct iso_inode_infoisofs_i;
struct sysv_inode_infosysv_i;
struct affs_inode_infoaffs_i;
struct ufs_inode_infoufs_i;
struct efs_inode_infoefs_i;
struct romfs_inode_inforomfs_i;
struct shmem_inode_infoshmem_i;
struct coda_inode_infocoda_i;
struct smb_inode_infosmbfs_i;
struct hfs_inode_infohfs_i;
struct adfs_inode_infoadfs_i;
struct qnx4_inode_infoqnx4_i;
struct reiserfs_inode_inforeiserfs_i;
struct bfs_inode_infobfs_i;
struct udf_inode_infoudf_i;
struct ncp_inode_infoncpfs_i;
struct proc_inode_infoproc_i;
struct socketsocket_i;
struct usbdev_inode_info        usbdev_i;
struct jffs2_inode_infojffs2_i;
void*generic_ip;
} u;
};

struct ext2_inode {
__u16i_mode;/* File mode */
__u16i_uid;/* Low 16 bits of Owner Uid */
__u32i_size;/* Size in bytes */
__u32i_atime;/* Access time */
__u32i_ctime;/* Creation time */
__u32i_mtime;/* Modification time */
__u32i_dtime;/* Deletion Time */
__u16i_gid;/* Low 16 bits of Group Id */
__u16i_links_count;/* Links count */
__u32i_blocks;/* Blocks count */
__u32i_flags;/* File flags */
union {
struct {
__u32  l_i_reserved1;
} linux1;
struct {
__u32  h_i_translator;
} hurd1;
struct {
__u32  m_i_reserved1;
} masix1;
} osd1;/* OS dependent 1 */
__u32i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
__u32i_generation;/* File version (for NFS) */
__u32i_file_acl;/* File ACL */
__u32i_dir_acl;/* Directory ACL */
__u32i_faddr;/* Fragment address */
union {
struct {
__u8l_i_frag;/* Fragment number */
__u8l_i_fsize;/* Fragment size */
__u16i_pad1;
__u16l_i_uid_high;/* these 2 fields    */
__u16l_i_gid_high;/* were reserved2[0] */
__u32l_i_reserved2;
} linux2;
struct {
__u8h_i_frag;/* Fragment number */
__u8h_i_fsize;/* Fragment size */
__u16h_i_mode_high;
__u16h_i_uid_high;
__u16h_i_gid_high;
__u32h_i_author;
} hurd2;
struct {
__u8m_i_frag;/* Fragment number */
__u8m_i_fsize;/* Fragment size */
__u16m_pad1;
__u32m_i_reserved2[2];
} masix2;
} osd2;/* OS dependent 2 */
};

從結構的定義中可以看出來inode(VFS inode)與ext2_inode的差別是很大的,怎麼說呢,
除了相同的都是不同。它們都包含動態資訊和靜態資訊,通過union指定的內容那一定
是動態的了。inode結構中的union u實際上反映了VFS支援的檔案系統。
可以看出inode結構與ext2_inode結構有些內容是相似的,如inode定義的
       unsigned longi_ino;
umode_ti_mode;
nlink_ti_nlink;
uid_ti_uid;
gid_ti_gid;
loff_ti_size;
time_ti_atime;
time_ti_mtime;
time_ti_ctime;
unsigned longi_blksize;
unsigned longi_blocks;
和ext2_inode定義的定義部分
       __u16i_mode;/* File mode */
__u16i_uid;/* Low 16 bits of Owner Uid */
__u32i_size;/* Size in bytes */
__u32i_atime;/* Access time */
__u32i_ctime;/* Creation time */
__u32i_mtime;/* Modification time */
__u32i_dtime;/* Deletion Time */
__u16i_gid;/* Low 16 bits of Group Id */
__u16i_links_count;/* Links count */
__u32i_blocks;/* Blocks count */
__u32i_flags;/* File flags */
這些都可以對應上,當然還有一些不同的地方,如inode中定義的
kdev_ti_rdev;
kdev_ti_dev;
kdev_ti_dev;
unsigned shorti_bytes;
struct semaphorei_sem;
在ext2_inode中沒有體現,不過這部分對ext2_inode是沒有用途而且無法確定的。
類似的,可以推廣到兩個結構的其餘部分,最終在程式碼中的區別還是與原理中分析的
區別相關的,也是原理的具體體現。