稀疏(Sparse)檔案的建立
在EXT2/EXT3檔案系統上可以使用dd建立稀疏檔案:

$ dd if=/dev/zero of=fs.img bs=1M seek=1024 count=0

0+0 records in

0+0 records out

$ ls -lh fs.img

-rw-rw-r-- 1 zhigang zhigang 1.0G Feb 5 19:50 fs.img

$ du -sh fs.img

0 fs.img

使用C語言來建立一個稀疏檔案的方法如下:

$ cat sparse.c

#include sys/types.h>

#include sys/stat.h>

#include fcntl.h>

#include unistd.h>


int main(int argc, char *argv[])
{
int fd = open("sparse.file", O_RDWR|O_CREAT);
lseek(fd, 1024, SEEK_CUR);
write(fd, "\0", 1);
return 0;
}


$ gcc -o sparse sparse.c

$ ./sparse

$ ls -l sparse.file

-r-x--x--- 1 zhigang zhigang 1025 Feb 5 23:12 sparse.file

]$ du sparse.file

4 sparse.file

使用python來建立一個稀疏檔案的方法如下:

$ cat sparse.py

#!/usr/bin/env python


f = open('fs.img', 'w')

f.seek(1023)

f.write('\n')


$ python sparse.py

$ ls -l fs.img

-rw-rw-r-- 1 zhigang zhigang 1024 Feb 5 20:15 fs.img

$ du fs.img

4 fs.img

檔案稀疏化(sparsify)
下面的方法都可以将一個檔案稀疏化。
1. cp:

$ cp --sparse=always file file.sparse
cp預設使用--sparse=auto,會自動探測源檔案中是否有空洞,以決定目标檔案是否為稀疏檔案;使用--sparse=never會禁止建立稀疏檔案。
2. cpio:

$ find file |cpio -pdmuv --sparse /tmp
如果不加--sparse參數,稀疏檔案中的空洞将被填滿。
3. tar:

$ tar cSf - file | (cd /tmp/tt; tar xpSf -)

如果不加 -S --sparse參數,稀疏檔案中的空洞将被填滿。
檔案稀疏化(sparsify)效率比較
下面我們建立一個500M的稀疏檔案,比較一下幾種檔案稀疏化方法的效率。

$ dd if=/dev/zero of=file count=100 bs=1M seek=400

100+0 records in

100+0 records out

$ time cp --sparse=always file file.sparse

real 0m0.626s

user 0m0.205s

sys 0m0.390s


$ time tar cSf - file | (cd /tmp; tar xpSf -)

real 0m2.732s

user 0m1.706s

sys 0m0.915s


$ time find file |cpio -pdmuv --sparse /tmp

/tmp/file

1024000 blocks

real 0m2.763s

user 0m1.793s

sys 0m0.946s

由此可見,上面幾種檔案稀疏化的方法中,cp的效率最高;tar和cpio由于使用管道,效率下降。
使EXT2/EXT3檔案系統稀疏化(sparsify)

$ gcc -o zerofree zerofree.c -lext2fs

$ ./zerofree fs.img
2.使用cp指令使映像檔案稀疏化:

$ cp --sparse=always fs.img fs_sparse.img
EXT2/EXT3檔案系統的sparse_super參數
這個參數與EXT2/EXT3是否支援Sparse檔案無關;當打開該參數時,檔案系統将使用更少的超級塊(Super block)備份,以節省空間。
如下的指令可以檢視該參數:

# echo stats | debugfs /dev/hda2 | grep -i features

Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery sparse_super large_file
或者:

# tune2fs -l /dev/hda2 |grep "Filesystem features"

可以通過使用:

# tune2fs -O sparse_super

# tune2fs -s [0|1]
來設定該參數。
參考資料
Keeping filesystem images sparse: