为什么一个47字节的文件,占用了2个Block?

发表于2012 年 05 月 29 日 | 标签: , ,

在debian lenny上,为什么一个47字节的文件,占用了2个Block?而每个Block的大小为默认的1K,即1024字节。这是个有趣的问题。

 

先来看一组数据:

$ ls -l

总计 2
-rwxr-xr-x 1 root root 47 06-25 16:54 test.sh
$ du -a

2 ./test.sh
4 .
$ dumpe2fs -h /dev/sda1 | grep Block

dumpe2fs 1.41.3 (12-Oct-2008)
Block count: 345364
Block size: 1024
Blocks per group: 8192

由上可见,例子中操作系统的Block size是1K,test.sh文件大小是47bytes,但诡异的是,它占用了2个block!?

理论上,保存文件内容的是内容的data block,保存文件名字的是该文件所在的目录对应的data block。在inode默认是128个体bytes的年代,它有12个直接指向data block的地址符(即可以直接访问12个块)。当然文件大于12个block时,它就分别继续使用singly indirect pointer, doubly indirect pointer 和triply indirect pointer来扩展空间(单个文件的大小限制就是这样来的) 。那么一个只有几十个字节的文件,inode只需使用一个direct pointer指向一个data block就ok了,因为它没有超出block size。如果系统默认的data block是1k的,那么du -a 我们看到的,应该只是1个块。

现在问题是,为什么上面看到的情况,不符合我们的推测呢?

 

经过研究,发现是旧的inode的大小,已满足不了现代文件系统的属性存储要求,所以每次新建一个文件的时候,都需要一个额外的block来存储这些属性,提供一个验证,如下:
使用不同inode size(128 和 256)来建fs,然后挂载fs,在这个fs上创建一个小文件,得到不同的结果:

---------------------------------------
$mkfs.ext3 -b 1024 -I 128 /dev/sde1   
...
$ du -a

2 ./test.sh
4 .


---------------------------------------
$ mkfs.ext3 -b 1024 -I 256 /dev/sde1
...
$ du -a

1 ./test.sh
2 .

查到的资料证明这个现象,是因为当系统启用SELinux时,128个bytes的inode不足以存储SELinux XATTR,所以需要一个单独的data block来存储这些SELinux XATTR。这解释了为何ext4默认建议为256个bytes的inode(因为未来linux系统可能会加入的SELinux, samba, beagle等程序,设置是Oracle数据引擎,都要使用文件扩展属性为自己的文件添加额外属性)。把SELinux关了后,在inode为128个bytes的filesystem上建立小文件,du -a查看,果然发现这个文件只占用了1个block,文件夹也是。

可以想象,如果当inode size为128,block size为4096时,一个几个字节的文件由于上述的原因,仍然会占用两个block,也就是8192 bytes的空间,那可真是浪费。

结论:

对于现代的linux,默认的inode size,至少要设置为256才好(debian下在/etc/mke2fs.conf),高效。

 

发表评论

*

  

icon_wink.gificon_neutral.gificon_mad.gificon_twisted.gificon_smile.gificon_eek.gificon_sad.gificon_rolleyes.gificon_razz.gificon_redface.gificon_surprised.gificon_mrgreen.gificon_lol.gificon_idea.gificon_biggrin.gificon_evil.gificon_cry.gificon_cool.gificon_arrow.gificon_confused.gificon_question.gificon_exclaim.gif