Мне интересно понять, как du
подсчитываются блоки, используемые в файле.
Сценарий
dd bs=1 seek=2GiB if=/dev/null of=big
0+0 records in
0+0 records out
0 bytes (0 B) copied, 2.3324e-05 s, 0.0 kB/s
ls -lh big
-rw-r--r-- 1 roaima roaima 2.0G May 19 15:55 big
du -h big
0 big
Я всегда принимал тот факт, что он даст мне разные ответы ls
, и это нормально, потому что они измеряют разные вещи.
Теперь у меня есть облачная файловая система, где с меня взимается плата не только за хранение, но и за каждую загрузку данных, поэтому мне нужно минимизировать объем данных, к которым обращаются при выполнении общих действий по обслуживанию, таких как «сколько места на диске используется в этом дереве?»
Я не знаю о библиотечном/системном вызове, который бы сообщал мне количество используемых блоков, хотя он легко мог бы быть. Я не верю, что du
он просматривает каждый файл, который он рассматривает, потому что это не делает различий между файлом, заполненным нулями, и тем, который действительно разрежен.
Итак, как же du
используются блоки подсчета?
решение1
du
используетstat(2)
чтобы найти количество блоков, используемых файлом. Если вы запустите, stat big
вы должны увидеть, что количество блоков совпадает с числом, указанным в du
.
Вы можете принудительно du
подсчитать байты с помощью -b
опции ; тогда ее вывод будет соответствовать ls
's.
В обоих случаях используется stat(2)
(или, fstatat(2)
по крайней мере, в той версии, которая у меня есть):
$ strace du big|&grep big
execve("/usr/bin/du", ["du", "big"], [/* 57 vars */]) = 0
newfstatat(AT_FDCWD, "big", {st_mode=S_IFREG|0644, st_size=2147483648, ...}, AT_SYMLINK_NOFOLLOW) = 0
write(1, "0\tbig\n", 60 big
Разница в обработкевидно вdu.c
.