LINUX 的EXT2檔案系統的組織方式

gaopengtttt發表於2016-01-25
LINUX 的EXT2檔案系統學習理解


檔案系統的構架非常複雜,在學習中使用了EXT2進行分析和學習,EXT3,EXT4雖然有改進但是基本原理一致
結合學習的東西必須記錄一下。


磁碟的塊分佈情況,預設的我們的一個塊是4K,在磁碟中塊被劃分成成組的形式。記為GROUP 0-GROUP N。
使用dumpe2fs 命令可以看到block group的使用情況。

塊的組織方式:

磁碟第一個塊:啟動塊 (boot block)
組0:(假設I個塊)
組第一個塊:超級塊 (SUPER BLOCK)
組第二到第N個塊:塊組描述符表(GDT)
組第N+1個塊:塊點陣圖塊(block bit map)
組第N+2個塊:Inode 點陣圖塊(Inode bit map block)
組第N+3到M個塊:Inode 表塊 (Inode table block)
組第M+1個塊到I個塊:data block 

組1:也是如組0進行組織
組2:也是如組0進行組織
....
組N:也是如組0進行組織


接下來我們進行每個塊的分開討論:
1、啟動塊 (boot block):這是一個磁碟只有一個的塊用來記錄磁碟的分割槽和啟動資訊,這是不歸入檔案系統的一個塊
2、超級塊 (SUPER BLOCK):
描述整個分割槽的檔案系統資訊,例如塊大小、檔案系統版本號、上次mount的時間等等。超級塊在每個塊組的開頭都有一份複製。
3、塊組描述符表(GDT):每個塊組描述符(Group Descriptor)儲存一個
塊組的描述資訊,例如在這個塊組中從哪裡開始是inode表,從哪裡開始是資料塊,空閒的
inode和資料塊還有多少個等等。和超級塊類似,塊組描述符表在每個塊組的開頭也都有一
份複製,這些資訊是非常重要的,一旦超級塊意外損壞就會丟失整個分割槽的資料,一旦塊組
描述符意外損壞就會丟失整個塊組的資料,因此它們都有多份複製
4、塊點陣圖塊(block bit map):
這裡面的一位表示了塊是否可用,沒有使用記為0,使用了標記為1,考慮到這裡ORACLE 11G的
一個資料檔案的前128個塊也是用於這個作用,而這裡如果一個塊為4K,那麼一個塊一共有
4096*8=32768個bit位,那麼也就算出來一個組的最大大小為 32768*4096。使用dumpe2fs /sda1
也能有這樣的顯示:
Block size:               4096  
Blocks per group:         32768 
5、Inode 點陣圖塊(Inode bit map block):
同樣為Inode的使用情況,沒有使用記為0,使用了標記為1,同樣也是佔用一個塊。如果透過計算發現
4096*8=32768個位是用不完的。見後面INODE分析
6、Inode 表塊 (Inode table block)
每個檔案都有一個Inode,而這些Inode記錄實際是記錄在Inode表中的,形成一行一行的Inode記錄
Inode用於記錄檔案的基本資訊,而不是檔案真正的資料資訊,如下:
root@bogon:~# stat log.log
  File: ‘log.log’
  Size: 35848           Blocks: 72         IO Block: 4096   regular file
Device: 801h/2049d      Inode: 1332077     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-01-17 21:31:00.359863946 +0800
Modify: 2016-01-17 21:30:56.995864067 +0800
Change: 2016-01-17 21:30:56.995864067 +0800
Birth: -
可以看到這裡資訊非常多,
例如檔案型別(常規、目錄、符號連結等),許可權,檔案大小,建立/修改/訪
問時間等 ,這其實在核心中是一個資料結構。
 23 struct stat {
 24     unsigned long   st_dev;     /* Device.  */
 25     unsigned long   st_ino;     /* File serial number.  */
 26     unsigned int    st_mode;    /* File mode.  */
 27     unsigned int    st_nlink;   /* Link count.  */
 28     unsigned int    st_uid;     /* User ID of the file's owner.  */
 29     unsigned int    st_gid;     /* Group ID of the file's group. */
 30     unsigned long   st_rdev;    /* Device number, if device.  */
 31     unsigned long   __pad1;
 32     long        st_size;    /* Size of file, in bytes.  */
 33     int     st_blksize; /* Optimal block size for I/O.  */
 34     int     __pad2;
 35     long        st_blocks;  /* Number 512-byte blocks allocated. */
 36     long        st_atime;   /* Time of last access.  */
 37     unsigned long   st_atime_nsec;
 38     long        st_mtime;   /* Time of last modification.  */
 39     unsigned long   st_mtime_nsec;
 40     long        st_ctime;   /* Time of last status change.  */
 41     unsigned long   st_ctime_nsec;
 42     unsigned int    __unused4;
 43     unsigned int    __unused5;
 44 };

除了記錄這些結構資料,剩下就是指向資料塊的指標一個指標為4BYTES,每個檔案的inode的索引項一共有15 個,
從 Blocks[0] 到Blocks[14],0-11個塊指標可以直接指向資料塊,叫做直接定址,而第12個塊指標指向的實際是一個新的指標
塊,那麼如果一個塊為4K那麼這個塊又可以指向4096/4=1024個塊,這叫一級定址這樣一級定址能夠建立的最大檔案
為11*4+1024*4 這樣就上MB了,如果這樣還不夠還有 13 指標還可以使用二級定址,甚至還有14號指標使用三級定址,
如果啟用三級定址那麼最大檔案大小是:11*4+1024*4+1024*4096/4+1024*4096/4*4096/4=44+4096+1048576+1073741824=1074794540 個塊
如果算上4K 1074794540*4/1024/1024~4T。

在格式化的時候INODE就進行了分配,那麼一個GROUP到底分配多少個INODE合適呢,LINUX用一個小檔案來
預設的作業系統認為一個檔案為8K,那麼如果一個group有多少個8K就分配多少個INODE,
這樣算下:
32768*4/8=16384 個Inode
檢視

Inodes per group:         16384 
Inode blocks per group:   512

但是我檢視新的Ubuntu 14.04.3 中這個改變了
Inodes per group:         8192
Inode blocks per group:   512


那麼我們很容易的算出 這個他認為檔案為16K,那麼也就是說,如果大量的檔案小於16K那麼會出現 Inode耗盡的情況,
如果是以前是如果大量的檔案小於8k。

理論上rm 一個檔案只是將他的block bit map,inode bit map進行反轉為0同時可能的釋放指標指向的資料塊,實際資料並沒有真正刪除,所以刪除非常快,這個和資料庫中的DROP有一樣的原理。



除此以外我們需要理解我們的目錄
目錄實際上也是一個需要一個inode的檔案,而初始Inode指向一個資料庫為4096,同樣他的各種資訊
如例如檔案型別(常規、目錄、符號連結等),許可權,檔案大小,建立/修改/訪
問時間等 
如下:
  Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: 801h/2049d      Inode: 1330599     Links: 2
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-01-19 12:19:56.896204445 +0800
Modify: 2016-01-16 13:56:06.586658881 +0800
Change: 2016-01-16 13:56:06.586658881 +0800


而在這個資料塊中存放著關於檔案的記錄
包含檔名、Inode、記錄長度、檔案型別,檔名實際數存在目錄的記錄中的,而他又包含了Inode。


大家都知道在檔案系統中都有一個/ 根目錄,這個/ 目錄的Inode固定而2,這樣我們就能找到/目錄的資料塊,然後就能
進行依次定位了,比如我們方位/home/oracle/log.log檔案那麼找到log.log檔案的次序如下:
1、先找到inode 2,然後透過 Inode 2的資料指標找到/根目錄的資料塊。
2、在根目錄的資料塊中尋找到home目錄在 /目錄資料塊中的記錄項,其中包含了
   檔名、Inode、記錄長度、檔案型別
   那麼檔名就是HOME ,Inode指向的資料塊就是Home目錄實際的資料塊
3、找到Home目錄的資料塊,定位ORACLE目錄在Home目錄資料塊的記錄項,同樣包含
   檔名、Inode、記錄長度、檔案型別
    那麼檔名就是oracle Inode指向的資料塊就是oralce目錄實際的資料塊
4、在ORACLE目錄的資料塊中找到LOG.LOG的記錄專案,同樣為
   檔名、Inode、記錄長度、檔案型別
   檔名為LOG.LOG Inode指向的資料塊就是log.log檔案實際的資料塊
 那麼我們歸納一下
 /根目錄的Inode 為2------》/根目錄的資料塊------》找到Home目錄的記錄項
 --------》透過Inode定位到HOME目錄的資料塊-----》找到ORACLE目錄的記錄項
 -------》根據Inode定位到ORACLE目錄的資料塊-----》找到LOG.LOG檔案的記錄專案
 ------》根據Inode定位到LOG.LOG的檔案塊
 如此資料就找到了Inode也找到了
 
 所以我們可以簡單的認為目錄越深,查詢的代價越大

最後記錄一下這幾個時間
Access: 2016-01-24 19:57:38.228325273 +0800  訪問時間
Modify: 2016-01-24 19:56:36.140325137 +0800  修改資料塊時間
Change: 2016-01-25 04:56:58.941460486 +0800 修改Inode資訊時間,換句話說比如修改了檔案許可權



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-1981902/,如需轉載,請註明出處,否則將追究法律責任。

相關文章