自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

存儲基礎 | 神奇!我的文件有個“洞”

存儲 存儲軟件
英文是“punch hole”,就是在保證文件其他屬性不變(比如,文件大小,inode 編號,權限等等)的條件下,主動釋放一段文件所占的物理空間。

[[422793]]

本文轉載自微信公眾號「奇伢云存儲」,作者奇伢 。轉載本文請聯(lián)系奇伢云存儲公眾號。

 

聊聊背景

文件還能打洞?

支持稀疏文件語義的文件系統(tǒng)就可以。

支持稀疏語義的文件系統(tǒng)有什么基本特征?

  • 實現(xiàn) fallocate 接口,能夠滿足文件空間預分配和打洞;
  • 實現(xiàn) fiemap 的功能,返回文件的具體物理塊分配信息;

打洞是什么意思?

英文是“punch hole”,就是在保證文件其他屬性不變(比如,文件大小,inode 編號,權限等等)的條件下,主動釋放一段文件所占的物理空間。

關于承諾的語義?

文件系統(tǒng):punch hole 成功,文件系統(tǒng)可能釋放,也可能沒釋放這部分空間,此結果不對用戶承諾。

程序猿:反而是程序猿要遵守承諾,一旦 puhch hole 成功,用戶將不能對這部分數(shù)據(jù)做任何假設,要當它已經沒了,無論它是不是真的沒了。

創(chuàng)建實分配的文件

為了打洞,我們需要先創(chuàng)建一個實際占用 4M 的文件,用 dd 命令如下:

  1. root@ubuntu:~/temp# dd if=/dev/urandom of=./test.txt.4M bs=1M count=4 

可以用 du 命令看一下實際的物理空間:

  1. root@ubuntu:~/temp# du -sh ./test.txt.4M 
  2. 4.0M ./test.txt.4M 

確實是 4M,再用 stat 命令看一下:

  1. root@ubuntu:~/temp# stat ./test.txt.4M 
  2.   File: './test.txt.4M' 
  3.   Size: 4194304    Blocks: 8192       IO Block: 4096   regular file 
  4. Device: fc00h/64512d Inode: 1335860     Links: 1 
  5. Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root) 

文件 Size 4194304 字節(jié),物理占用 Blocks 數(shù)是 8192,這里每個 Block 單位是 512 字節(jié),所以物理占用也是 4194304 字節(jié),剛好 4M。

文件打個洞

原材料準備好了,Go 程序怎么給文件打個洞呢 ?

關鍵在于 fallocate 系統(tǒng)調用。

這是一個跟平臺強相關的系統(tǒng)調用,非系統(tǒng)兼容的,下面以 Linux 為例。

由于這個非系統(tǒng)兼容的,類似于這類調用,一般都是用 syscall 這個標準庫,直接下發(fā)系統(tǒng)調用。

完整程序示例如下:

代碼關鍵幾個事項:

  1. 文件頭部要加上 // +build linux ;
  2. 調用的是 syscall.Fallocate 接口;

好了,編譯一下吧:

  1. go build -gcflags "-N -l" ./punchhole.go 

把編譯出的二進制 punchhole 和 test.txt.4M 這兩個放在一個目錄下,實驗一下效果:

  1. root@ubuntu:~/temp# ./punchhole  
  2. 2021/09/08 22:22:21 punch hole success. 

du 看下文件結果:

  1. root@ubuntu:~/temp# du -sh ./test.txt.4M 
  2. 2.0M ./test.txt.4M 

嗷,確實變成了 2M,stat 再看一下:

  1. root@ubuntu:~/temp# stat ./test.txt.4M 
  2.   File: './test.txt.4M' 
  3.   Size: 4194304    Blocks: 4096       IO Block: 4096   regular file 
  4. Device: fc00h/64512d Inode: 1335860     Links: 1 
  5. Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root) 
  6. Access: 2021-07-26 15:39:06.672000000 +0800 

文件大小還是 4M,實際物理空間變成了 2M( 4096 * 512 ),inode 編號、權限都沒變。完美,一個空洞文件就誕生了。

文件解析:

這個文件 [ 0,2M ] 的位置是空洞,不占物理空間,讀出來會是 0 數(shù)據(jù);

[ 2M,4M ] 的數(shù)據(jù)還是原來從 /dev/urandom 設備讀出來的數(shù)據(jù),占用實際物理空間;

思考題

拋出幾個關鍵的思考問題,大家可以自行驗證。

如果 punchhole 傳參是非 4k 對齊的,會怎么樣?

劃重點:由于文件系統(tǒng)內部都是按照 4k 的單位管理空間的,所以非 4k 對齊的空間是釋放不掉的。 punch hole 一定要注意按照 4k 對齊。

特別還要注意一點,雖然非 4k 對齊釋放不掉,但是 fallocate 調用也不會報錯,這點很重要。最開始就提過,文件系統(tǒng)沒給你承諾過啥時候釋放啥。

大家可以手動驗證下。

文件 test.txt.4M 的 [ 0,2M ] 被打洞之后,這個區(qū)域會是什么數(shù)據(jù)?

**全 0 數(shù)據(jù),這個是稀疏文件系統(tǒng)給你的語義。**這個上面也提到過了。

奇伢教你快速用 hexdump 命令看一下:

  1. root@ubuntu:~/temp# hexdump ./test.txt.4M|more 
  2. 0000000 0000 0000 0000 0000 0000 0000 0000 0000 
  3. 0200000 80e3 2c11 f8d8 256b 23b5 a191 fb80 eb5e 
  4. 0200010 f454 e3e2 cb8b 664a a893 6f5a 2df0 99dd 
  5. 0200020 9d30 4f19 144f b4f1 f2cd 7312 c16c 719f 
  6. 0200030 2ef7 3195 48a1 b2c0 03f1 a08a aff3 a022 
  7. ................. 
  8. ................. 

看到了嗎?

0x0000000 - 0x0200000 這個區(qū)域都是 0 數(shù)據(jù)。這是 16 進制表示,換算成 10 進制,就是 [ 0 ,2M ] 的區(qū)域。

大家也可以用程序去 read 驗證下。

總結

總結幾個關鍵點:

文件打洞用的是系統(tǒng)調用 fallocate ;

文件打洞的時候要注意 4k 對齊,不然非對齊部分釋放不掉,并且不會報錯;

文件系統(tǒng)沒承諾什么,所以當沒 4k 對齊的時候,雖然沒釋放空間,也不會報錯;

程序猿要遵守承諾,一旦聲明了某段空間要釋放,以后不能對此空間內容做假設; 

文件打洞的位置,不占物理空間,后續(xù)讀是返回 0 數(shù)據(jù);

 

責任編輯:武曉燕 來源: 奇伢云存儲
相關推薦

2020-08-04 08:44:08

HashCode

2018-08-21 11:44:00

人工智能

2020-06-08 07:52:31

Python開發(fā)工具

2020-06-16 09:46:17

App安卓應用

2021-09-29 08:23:56

項目css

2014-02-13 17:22:08

2019-12-02 19:28:00

華為Mate X

2020-07-22 10:30:35

機器人人工智能系統(tǒng)

2019-10-15 15:15:31

Python大數(shù)據(jù)函數(shù)

2024-04-01 05:00:00

GUIpythonDearPyGui

2024-07-21 15:33:02

2020-06-03 11:00:34

戴爾

2009-04-13 08:46:07

蓋茨慈善夢想

2009-07-24 10:17:07

2021-04-20 19:15:51

瀏覽器網絡URL

2020-04-03 11:24:50

LinuxUnix進程

2020-06-23 07:50:13

Python開發(fā)技術

2019-08-07 15:08:48

開發(fā)者技能工具

2018-07-24 15:22:30

區(qū)塊鏈數(shù)字貨幣比特幣

2021-05-08 17:05:39

計算機程序操作系統(tǒng)
點贊
收藏

51CTO技術棧公眾號