Ch9
The Ext4 Filesystem
bob.fu
2014/10/14
● Block Layout
● Indirect/Extent
● Mount Flow
● Operations
● Journal
superblock
group descriptors
reserved gdt blocks
block bitmaps(all groups)
inode bitmaps(all groups)
inode table(group 0)
inode table(group 1)
inode table(group 15)
Block Layout
meta blocks
data blocks
block group(32768 blocks = 128M)
Block Layout
block group #0 #1 #15#2 #3
flex group
128M * 16 = 2G
Block Layout
#1 #3
flex group
#0 #15#2
#17 #19
flex group
#31#18#16
#33 #35
flex group
#47#34#32
#49 #51
flex group
#50#48
data
data
blk#
blk#
blk#
blk#
blk#
blk#
Indirect/Extent
ei
data
blk#
blk#
blk#
data
1024
blk#
blk#
blk#
blk#
blk#
blk#
data
blk#
blk#
blk#
blk#
blk#
blk#
blk#
blk#
blk#
data
data
data
blk#
blk#
blk#
blk#
blk#
blk#
data
data
data
data
12
max = 12 + 1024 + 1024^2 + 1024^3
blk#
blk#
blk#
indirect
double
indirect
triple
indirect
1024^2
Indirect/Extent
ei
idx
idx
hdr
idx
hdr
ext
hdr
ext
hdr
ext
hdr
data
data
data
data
data
data
data
data
mi
n n n
page page page page page page page page
storage memory
Indirect/Extent
ei
idx
idx
hdr
idx
hdr
ext
hdr
ext
hdr
ext
hdr
data
data
data
data
data
data
data
data
storage
file
dir
abcde
dirent dirent
dirent dirent
dirent dirent
file/dir 都可以有多個 block
不保證連續
各自紀錄 data/dirent
Mount Flow
memory
ext4@storage
*. 建 mountext4m
s i i i i i i
root journal
i i
Mount Flow
memory
ext4@storage
*. 建 mount
*. 建 sb/sbi, 根據讀入的 es 設定
ext4m
s
s i i i i i i
root journal
i i
Mount Flow
memory
ext4@storage
*. 建 mount
*. 建 sb/sbi, 根據讀入的 es 設定
*. 為 sb 安裝 sops
ext4m
s sop
s i i i i i i
root journal
i i
Mount Flow
memory
ext4@storage
*. 建 mount
*. 建 sb/sbi, 根據讀入的 es 設定
*. 為 sb 安裝 sops
*. 載入 journal
ext4m
s sop
s i i i i i i
root journal
journal
i i
Mount Flow
memory
ext4@storage
*. 建 mount
*. 建 sb/sbi, 根據讀入的 es 設定
*. 為 sb 安裝 sops
*. 載入 journal
*. 建 root inode/dentry
fop
iopi
d “/”
ext4m
s sop
s i i i i i i
root journal
journal
i i
Mount Flow
memory
ext4@storage
*. 建 mount
*. 建 sb/sbi, 根據讀入的 es 設定
*. 為 sb 安裝 sops
*. 載入 journal
*. 建 root inode/dentry
*. 串入 parent mount
s i i i i i i
root journal
journal
i i
fopiopi
“/”d
rootfsm
fopiopi
d “aaa”
ext4m
fopiopi
d “/”
Operations(lookup)
e.g. /home/pi/Desktop
memory
ext4@storage
s
pi
dirent dirent
dirent dirent
dirent dirent
pi
d “pi”
fop
iopi
Operations(lookup)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
memory
ext4@storage
s
pi
dirent dirent
dirent dirent
dirent dirent
pi
d “pi”
fop
iopi
d “Desktop”
Operations(lookup)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
*. 執行 dir(pi) 自帶 ext4_lookup
memory
ext4@storage
s
pi
dirent dirent
dirent dirent
dirent dirent
pi
d “pi”
fop
iopi ext4_lookup
d “Desktop”
Operations(lookup)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
*. 執行 dir(pi) 自帶 ext4_lookup
*. 根據 name 找 dirent( 獲取 ino)
memory
ext4@storage
s
pi
dirent dirent
dirent dirent
dirent dirent
pi
.inode = #
.name = “Desktop”
d “pi”
fop
iopi ext4_lookup
d “Desktop”
Operations(lookup)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
*. 執行 dir(pi) 自帶 ext4_lookup
*. 根據 name 找 dirent( 獲取 ino)
*. 根據 ino 對應 ext4 inode 建 inode
memory
ext4@storage
s i
pi
dirent dirent
dirent dirent
dirent dirent
pi
Desktop
.inode = #
.name = “Desktop”
d “pi”
fop
iopi ext4_lookup
fop
iopi
d “Desktop”
Operations(lookup)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
*. 執行 dir(pi) 自帶 ext4_lookup
*. 根據 name 找 dirent( 獲取 ino)
*. 根據 ino 對應 ext4 inode 建 inode
*. 關聯 dentry & inode
*. 把 dentry 加入 table
memory
ext4@storage
s i
pi
dirent dirent
dirent dirent
dirent dirent
pi
Desktop
.inode = #
.name = “Desktop”
d “pi”
fop
iopi ext4_lookup
fop
iopi
d “Desktop”
Operations(mkdir)
e.g. /home/pi/Desktop
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
Desktop
d “pi”
fop
iopi
d “Desktop”
s sop
Operations(mkdir)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
Desktop
d “pi”
fop
iopi
d “Desktop”
s sop
Operations(mkdir)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
*. 執行 dir(pi) 自帶 ext4_lookup, 找無
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
Desktop
d “pi”
fop
iopi ext4_lookup
d “Desktop”
s sop
Operations(mkdir)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
*. 執行 dir(pi) 自帶 ext4_lookup, 找無
*. 執行 dir(pi) 自帶 ext4_mkdir
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
Desktop
d “pi”
fop
iopi ext4_lookup
d “Desktop”
s sop
ext4_mkdir
Operations(mkdir)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
*. 執行 dir(pi) 自帶 ext4_lookup, 找無
*. 執行 dir(pi) 自帶 ext4_mkdir
+. 執行 sb 自帶 ext4_alloc_inode
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
Desktop
d “pi”
fop
iopi ext4_lookup
i
d “Desktop”
s sop ext4_alloc_inode
ext4_mkdir
Operations(mkdir)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
*. 執行 dir(pi) 自帶 ext4_lookup, 找無
*. 執行 dir(pi) 自帶 ext4_mkdir
+. 執行 sb 自帶 ext4_alloc_inode
+. 為 inode 安裝 fop/iop
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
Desktop
d “pi”
fop
iopi ext4_lookup
fop
iopi
d “Desktop”
s sop ext4_alloc_inode
ext4_mkdir
Operations(mkdir)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
*. 執行 dir(pi) 自帶 ext4_lookup, 找無
*. 執行 dir(pi) 自帶 ext4_mkdir
+. 執行 sb 自帶 ext4_alloc_inode
+. 為 inode 安裝 fop/iop
+. 準備 Desktop/ 內容
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
dirent dirent
Desktop
d “pi”
fop
iopi ext4_lookup
fop
iopi
d “Desktop”
s sop ext4_alloc_inode
ext4_mkdir
Operations(mkdir)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
*. 執行 dir(pi) 自帶 ext4_lookup, 找無
*. 執行 dir(pi) 自帶 ext4_mkdir
+. 執行 sb 自帶 ext4_alloc_inode
+. 為 inode 安裝 fop/iop
+. 準備 Desktop/ 內容
+. 加入 pi/
memory
ext4@storage
s i
pi
dirent dirent
dirent dirent
dirent dirent
pi
Desktop
dirent dirent
Desktop
d “pi”
fop
iopi ext4_lookup
fop
iopi
d “Desktop”
s sop ext4_alloc_inode
ext4_mkdir
Operations(mkdir)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
*. 執行 dir(pi) 自帶 ext4_lookup, 找無
*. 執行 dir(pi) 自帶 ext4_mkdir
+. 執行 sb 自帶 ext4_alloc_inode
+. 為 inode 安裝 fop/iop
+. 準備 Desktop/ 內容
+. 加入 pi/
+. 關連 dentry & inode
memory
ext4@storage
s i
pi
dirent dirent
dirent dirent
dirent dirent
pi
Desktop
dirent dirent
Desktop
d “pi”
fop
iopi ext4_lookup
fop
iopi
d “Desktop”
s sop ext4_alloc_inode
ext4_mkdir
Operations(touch)
e.g. /home/pi/Desktop
*. 在 table 找無 , 新建 dentry
*. 執行 dir(pi) 自帶 ext4_lookup, 找無
*. 執行 dir(pi) 自帶 ext4_create
+. 執行 sb 自帶 ext4_alloc_inode
+. 為 inode 安裝 fop/iop/aop
+. 準備 Desktop/ 內容
+. 加入 pi/
+. 關連 dentry & inode
*. open & release
memory
ext4@storage
s i
pi
dirent dirent
dirent dirent
dirent dirent
pi
Desktop
dirent dirent
Desktop
d “pi”
fop
iopi ext4_lookup
iopi
d “Desktop”
s sop ext4_alloc_inode
ext4_mkdir
aop fop
ext4_file_open
ext4_release_file
fop
Operations(rm/rmdir)
e.g. /home/pi/Desktop
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
Desktop
d “pi”
fop
iopi
iopi
d “Desktop”
s sop
dirent dirent
dirent
fop
Operations(rm/rmdir)
e.g. /home/pi/Desktop
*. 執行 dir(pi) 自帶 unlink 或 rmdir
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
Desktop
d “pi”
fop
iopi ext4_unlink
iopi
d “Desktop”
s sop
ext4_rmdir
dirent dirent
dirent
fop
Operations(rm/rmdir)
e.g. /home/pi/Desktop
*. 執行 dir(pi) 自帶 unlink 或 rmdir
+. 從 dir(pi) 移除 de(Desktop)
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
Desktop
d “pi”
fop
iopi ext4_unlink
iopi
d “Desktop”
s sop
ext4_rmdir
dirent dirent
fop
Operations(rm/rmdir)
e.g. /home/pi/Desktop
*. 執行 dir(pi) 自帶 unlink 或 rmdir
+. 從 dir(pi) 移除 de(Desktop)
*. 執行 sb 自帶 ext4_evict_inode
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
Desktop
d “pi”
fop
iopi ext4_unlink
iopi
d “Desktop”
s sop ext4_evict_inode
ext4_rmdir
dirent dirent
fop
Operations(rm/rmdir)
e.g. /home/pi/Desktop
*. 執行 dir(pi) 自帶 unlink 或 rmdir
+. 從 dir(pi) 移除 de(Desktop)
*. 執行 sb 自帶 ext4_evict_inode
+. 歸還 ext4 inode 的 data block
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
Desktop
d “pi”
fop
iopi ext4_unlink
iopi
d “Desktop”
s sop ext4_evict_inode
ext4_rmdir
fop
Operations(rm/rmdir)
e.g. /home/pi/Desktop
*. 執行 dir(pi) 自帶 unlink 或 rmdir
+. 從 dir(pi) 移除 de(Desktop)
*. 執行 sb 自帶 ext4_evict_inode
+. 歸還 ext4 inode 的 data block
+. 歸還 ext4 inode 本身
memory
ext4@storage
s
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
d “pi”
fop
iopi ext4_unlink
iopi
d “Desktop”
s sop ext4_evict_inode
ext4_rmdir
fop
Journal
e.g. /home/pi/Desktop
*. 執行 dir(pi) 自帶 unlink 或 rmdir
+. 從 dir(pi) 移除 de(Desktop)
*. 執行 sb 自帶 ext4_evict_inode
+. 歸還 ext4 inode 的 data block
+. 歸還 ext4 inode 本身
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
Desktop
d “pi”
fop
iopi ext4_unlink
iopi
d “Desktop”
s sop ext4_evict_inode
ext4_rmdir
abcde
o
x
未歸還 block/inode 造成 storage leak
fop
Journal
e.g. /home/pi/Desktop
*. 執行 dir(pi) 自帶 unlink 或 rmdir
+. 從 dir(pi) 移除 de(Desktop)
*. 執行 sb 自帶 ext4_evict_inode
+. 歸還 ext4 inode 的 data block
+. 歸還 ext4 inode 本身
memory
ext4@storage
s i
pi
dirent dirent
dirent
dirent dirent
pi
Desktop
Desktop
d “pi”
fop
iopi ext4_unlink
iopi
d “Desktop”
s sop ext4_evict_inode
ext4_rmdir
abcde
x
o
ext4 inode 被當 free, 配給新 file
Journal
memory
ext4@storage
1
2
journal
*. 把 1st meta 寫入 journal
*. 把 2nd meta 寫入 journal
*. 把 3rd meta 寫入 journal
*. 把 1st meta 寫入 target
*. 把 2nd meta 寫入 target
*. 把 3rd meta 寫入 target
都未寫入 , 沒 consistent 問題
crash
Journal
memory
ext4@storage
1
2
journal
*. 把 1st meta 寫入 journal
*. 把 2nd meta 寫入 journal
*. 把 3rd meta 寫入 journal
*. 把 1st meta 寫入 target
*. 把 2nd meta 寫入 target
*. 把 3rd meta 寫入 target
寫入部份 , 有 consistent 問題
*. 1st meta
--> 捨棄 , 沒 consistent 問題
crash
crash
Journal
memory
ext4@storage
1
2
journal
*. 把 1st meta 寫入 journal
*. 把 2nd meta 寫入 journal
*. 把 3rd meta 寫入 journal
*. 把 1st meta 寫入 target
*. 把 2nd meta 寫入 target
*. 把 3rd meta 寫入 target
全部寫入 , 沒 consistent 問題
*. 1st meta
*. 2nd meta
*. 3rd meta
--> 寫入 target, 也稱為 replay
crash
crash
crash
Journal
memory
ext4@storage
1
2
journal
*. 把 1st meta 寫入 journal
*. 把 2nd meta 寫入 journal
*. 把 3rd meta 寫入 journal
*. 把 1st meta 寫入 target
*. 把 2nd meta 寫入 target
*. 把 3rd meta 寫入 target
全部寫入 , revoke
*. 1st meta
*. 2nd meta
*. 3rd meta
--> revoke( 之後不會 replay)
crash
Journal
memory
ext4@storage
physical journal
(journal@ext4)
logical journal
(writeback@ext4) (ordered@ext4)
1
2
1
2
journal
1
2
journal
1
2
journal
在 meta 前寫入

ch9-pv1-the-extended-filesystem-family