我有一个包含 18 个文件的目录,但stat
其他工具将其大小报告为0
. 这怎么可能?
$ \stat $PWD
File: `/home/users/gholl/checkouts_local/FCDR_HIRS/FCDR_HIRS/analysis'
Size: 0 Blocks: 0 IO Block: 524288 directory
Device: 14h/20d Inode: 62487444829821592 Links: 1
Access: (0755/drwxr-xr-x) Uid: (35063/ gholl) Gid: (26030/ users)
Access: 2018-04-09 11:38:43.574427000 +0100
Modify: 2018-04-09 11:38:43.574427000 +0100
Change: 2018-04-09 11:38:43.575000000 +0100
~/checkouts_local/FCDR_HIRS/FCDR_HIRS/analysis$ \ls -1 | wc -l
18
$ mount | grep homeusers
172.26.72.131:/homeusers on /home/users type nfs (rw,tcp,hard,intr,timeo=50,addr=172.26.72.131)
该机器是 Red Hat Enterprise Linux Server 版本 6.9 (Santiago)。根据df -T
,文件系统类型是nfs
:
$ df -hT .
Filesystem Type Size Used Avail Use% Mounted on
172.26.72.131:/homeusers
nfs 200T 3.5T 197T 2% /home/users
我认为目录的大小与其中的文件数量有关,因为它存储了它们的元数据。那么非空目录怎么可能为零呢?
注意:我无权访问服务器,也没有超级用户权限,因此我无法调查服务器端发生的情况。
它取决于 NFS 服务器上的底层文件系统。最终,这归结为 POSIX 语义的一个有点奇怪且不为人知的位,即
st_blocks
返回的字段stat()
不包括分配为元数据的块,仅包括分配为数据的块。这种区别起源于 UNIX 系统上的标准文件系统使用静态分配的 inode 表时,这意味着每个文件系统对象都有固定数量的空间用于元数据(因此不必担心将其计入文件大小,因为它对文件的总空间使用没有贡献(因为 inode 表是静态分配的,该空间已被保留)文件系统(IOW,目录条目被视为文件内容,而不是元数据)。这就是为什么旧 UNIX 系统上的大多数目录大小是 4kB 的倍数,因为这是大多数 UNIX 文件系统的块大小,这也是为什么
stat()
和使用它的工具在不考虑元数据的情况下报告文件大小。然而,在许多较新的文件系统上,情况却大不相同。元数据的空间是动态分配的,而不是固定大小条目的静态表,并且目录条目被视为元数据。因此,根据确切的系统和文件系统,目录可能显示为零表观大小,或者可能显示零磁盘使用量(由
stat
或报告du
)但由 报告的较小的亚 kB 表观大小ls
。BTRFS 是属于第二类的文件系统的一个很好的例子,目录的表观大小是其中有多少条目以及它们的名称有多长的函数,而您从中获得的报告的磁盘大小stat()
是始终为零。