有人在其他网站上问我这个问题,即一个名为“abc.dat”的文件的文件大小为0,但有8个块,这是我要求他给我的输出(有些文本已从中文翻译成英文):
$ cp abc.dat abc2.dat; ls -ls abc2.dat #try to copy, it still 8 blocks but 0 byte
8 -rw-rw-r-- 1 rokeabbey rokeabbey 0 Feb 27 19:39 abc2.dat
8 -rw-rw-r-- 1 rokeabbey rokeabbey 0 Sep 18 19:11 abc.dat #sorry,这可能是他添加的额外错误输出
$ stat abc.dat
File: 'abc.dat'
Size: 0 Blocks: 16 IO Block: 4096 regular empty file
Device: 32h/50d Inode: 3715853 Links: 1
Access: (0664/-rw-rw-r--) Uid:( 1000/rokeabbey) Gid:( 1000/rokeabbey)
Access: 2018-02-26 21:13:57.640639992 +0800
Modify: 2017-09-18 19:11:42.221533011 +0800
Change: 2017-09-18 19:11:42.221533011 +0800
Birth: -
$ touch abc3.dat ; ls -sl | grep abc #try to create new empty file, it still 8 blocks by default
8 -rw-rw-r-- 1 rokeabbey rokeabbey 0 Feb 27 19:39 abc2.dat
8 -rw-rw-r-- 1 rokeabbey rokeabbey 0 Feb 27 19:40 abc3.dat
8 -rw-rw-r-- 1 rokeabbey rokeabbey 0 Sep 18 19:11 abc.dat
我了解了一些关于稀疏文件、文件元数据、符号链接情况的知识,但这些情况都不会导致 0 字节文件大小与 8 个块。是否有任何文件系统设置,例如最小块大小任何文件 ?
他告诉我他的系统是Ubuntu 16.04和ext4。
[更新]
$ df -Th /home/rokeabbey
/home/rokeabbey/.Private ecryptfs 138G 39G 92G 30% /home/rokeabbey
[更新]我可以用 ecryptfs 重现
xb@dnxb:/tmp/test$ sudo mkdir /opt/data
xb@dnxb:/tmp/test$ sudo apt-get install ecryptfs-utils
...
xb@dnxb:/tmp/test$ sudo mount -t ecryptfs /opt/data /opt/data
Passphrase:
...
Selection [aes]: 1
...
Selection [16]: 1
Enable plaintext passthrough (y/n) [n]: y
Enable filename encryption (y/n) [n]: y
...
Would you like to proceed with the mount (yes/no)? : yes
...
in order to avoid this warning in the future (yes/no)? : no
Not adding sig to user sig cache file; continuing with mount.
Mounted eCryptfs
xb@dnxb:/tmp/test$ l /opt/data
total 8.0K
52953089 drwxr-xr-x 9 root root ? 4.0K Feb 27 23:16 ../
56369402 drwxr-xr-x 2 root root ? 4.0K Feb 27 23:16 ./
xb@dnxb:/tmp/test$ sudo touch /opt/data/testing
xb@dnxb:/tmp/test$ less /opt/data/testing
xb@dnxb:/tmp/test$ sudo umount /opt/data
xb@dnxb:/tmp/test$ ls -ls /opt/data
total 8
8 -rw-r--r-- 1 root root 8192 Feb 27 23:42 ECRYPTFS_FNEK_ENCRYPTED.FWbECDhE0C37e-Skw2B2pnQpP9gB.b3yDfkVU5wk7WhvMreg8yVnuEaMME--
xb@dnxb:/tmp/test$ less /opt/data/ECRYPTFS_FNEK_ENCRYPTED.FWbECDhE0C37e-Skw2B2pnQpP9gB.b3yDfkVU5wk7WhvMreg8yVnuEaMME--
"/opt/data/ECRYPTFS_FNEK_ENCRYPTED.FWbECDhE0C37e-Skw2B2pnQpP9gB.b3yDfkVU5wk7WhvMreg8yVnuEaMME--" may be a binary file. See it anyway?
xb@dnxb:/tmp/test$ sudo mount -t ecryptfs /opt/data /opt/data
Passphrase:
Select cipher:
...
Selection [aes]: 1
...
Selection [16]: 1
Enable plaintext passthrough (y/n) [n]: y
Enable filename encryption (y/n) [n]: y
...
Would you like to proceed with the mount (yes/no)? : yes
...
in order to avoid this warning in the future (yes/no)? : no
Not adding sig to user sig cache file; continuing with mount.
Mounted eCryptfs
xb@dnxb:/tmp/test$ ls -ls /opt/data
total 8
8 -rw-r--r-- 1 root root 0 Feb 27 23:42 testing
xb@dnxb:/tmp/test$
答案1
如果文件系统被加密,就会发生这种情况; FS需要为文件存储额外的元数据,即使它是空的。
由于我碰巧有一台带有普通 ecryptfs 挂载的机器(Ubuntu 12.04-LTS),我可以确认一个空文件将获得 8 个块:
$ touch test
$ ls -ls test
8 -rw-rw-r-- 1 admin admin 0 feb 27 16:45 test
答案2
如果文件上有扩展属性,则可以获得带有块的零大小文件,超过 inode 本身所能容纳的属性:
$ touch abc
$ setfattr -n user.test -v xyz abc # this doesn't do it
$ ls -s abc # since the data fits in the inode
0 abc
$ setfattr -n user.test -v "$(printf %100s " ")" abc
$ ls -s abc
4 abc
但是,我不明白你如何以这种方式获得 8 kB,根据xattr
手册页,大小受限于ext2/3/4上的块大小,而块大小又受限于系统页面大小,所以x86上为4 kB。此外,新创建的文件不应具有任何扩展属性,除非您正在运行 SELinux,但在这种情况下,ls -l
应在权限位末尾显示点以指示 SELinux 标记的存在。