Как `du` подсчитывает используемые блоки

Как `du` подсчитывает используемые блоки

Мне интересно понять, как 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.

Связанный контент