If I have the following contents in a directory:
empty_dir
: Empty directory.empty_file
: Empty file.one_char
: File consisting of one character.several_blocks
: File consisting of several blocks (but not "too" large or "sparse").
Then, ls
will display the following †:
$ ls -Gghs
total 152K
8,0K drwxr-xr-x 2 4,0K dec 21 23:34 empty_dir
4,0K -rw-r--r-- 1 0 dec 21 23:21 empty_file
8,0K -rw-r--r-- 1 1 dec 21 23:22 one_char
132K -rw-r--r-- 1 127K dec 22 00:14 several_blocks
Secondly, stat
displays the following:
$ stat empty_dir/
File: empty_dir/
Size: 4096 Blocks: 16 IO Block: 4096 directory
...
$ stat empty_file
File: empty_file
Size: 0 Blocks: 8 IO Block: 4096 regular empty file
...
$ stat one_char
File: one_char
Size: 1 Blocks: 16 IO Block: 4096 regular file
...
$ stat several_blocks
File: several_blocks
Size: 129760 Blocks: 264 IO Block: 4096 regular file
...
Thirdly, du
displays the following:
$ du -h empty_dir/
8,0K empty_dir/
$ du -h empty_file
4,0K empty_file
$ du -h one_char
8,0K one_char
$ du -h several_blocks
132K several_blocks
Lastly:
$ tune2fs /dev/nvme0n1p2 -l
...
Block size: 4096
...
Inode size: 256
...
The size of the blocks reported by stat
is 512 B, which means that the output between stat
, ls
, and du
is consistent:
empty_dir
: 16 * 512 / 1024 = 4096 + 4096 = 8 KiB.empty_file
: 8 * 512 / 1024 = 0 + 4096 = 4 KiB.one_char
: 16 * 512 / 1024 = 4096 + 4096 = 8 KiB.several_blocks
: 264 * 512 / 1024 = 129760 + 5408 = 129760 + 1312 + 4096 = 131072 + 4096 = 32 * 4096 + 4096 = 132 KiB.
Questions
- Why is the allocated size for
empty_dir
andone_char
two blocks (of size 4096 B) and not one? - Why is the allocated size for
empty_file
one block and not zero? - Why is the allocated size for
several_blocks
(and larger files in general) more than one block larger than the apparent size ((264 * 512) – 129760 = 5408 > 4096)?
I suspect the additional block is the one containing the inode
, like this questioner asks (but goes unanswered). Similarly this questioner has observed the double size, but it is incorrectly formulated in the question and receives an answer to the other part of the question. However, this answer to a different question, suggests that there should be no additional blocks (which was my intuition).
- Are our systems incorrectly configured?
- Assuming the block containing the
inode
is counted: When usingdu
on multiple files, does it compensate for counting theinode
block several times, should multipleinodes
be in the same block (since one block can contain 16inodes
(4096 / 256 = 16))?
Appendix
@WumpusQ.Wumbley speculated that it could be extended attributes and this turned out to be the case!
getfattr
returns user.com.dropbox.attributes
. Turns out the testing directory was a subdirectory deep down in a directory that was symbolically linked into my Dropbox folder. See the accepted answer below.
† This uses GNU Core Utilities 8.30 on GNU/Linux with kernel 4.19.1 (Manjaro) on ext4 on a NVME SSD.
Best Answer
@WumpusQ.Wumbley pointed out the cause in a comment: extended attributes.
For completeness sake the answers are presented below.
Extended attributes, in this case applied by Dropbox (
getfattr
returnsuser.com.dropbox.attributes
), uses additional blocks for storage. Without these extended attributesls
(and the other commands) returns:As expected.
In addition,
stat
for the only interesting case ofseveral_blocks
returns:Which is also as expected, since 256 * 512 - 129760 = 1312 < 4096, i.e., no extra block used.