А бывают ли ФС, которые хранят (поддерживают в актуальном состоянии) размер всех директорий рядом с самой директорией, чтобы du -s например очень быстро работала?
Не слышал... Реализация имеет по крайней мере одну очевидную проблему: хардлинки. Представьте себе, что у вас один и тот же файл существует под разными именами в десятке каталогов, как тогда менять счётчик у всех у них? Получается, что надо хранить список каталогов, которые на каждый файл ссылаются, ну положим не пути, а только inode, но все равно.
Опять же, файлы имеют тенденцию расти маленькими порциями, для каждого write придется делать по нескольку обновлений счетчиков -- это значит, что любой лог-файл на такой ФС приведет к жестоким тормозам.
В общем, игра не стоит свеч, потому, видимо, и не делают.
>Опять же, файлы имеют тенденцию расти маленькими порциями
Ну так для /var/tmp mount -o nodirsize, а, например, для /var/www или /var/lib было бы полезно :) У меня сейчас подсчёт объёма, чтобы понять, кто ещё место сожрал, занимает по полчаса :)
Тогда идейнее было бы что-то вроде службы индексирования (как в случае find vs locate), которая давала бы приблизительную информацию, зато быстро. ИМХО незачем пихать такой функционал в ядро.
Кстати, вот если бы заставить locate помимо имён хранить ещё номера инодов и всякие размеры, права и пр...
Под Амигу SFS и PFS это умели (или, ЕМНИП, это умела каждая родная амижная ФС).
Там в "finder"-е в окошке был градусник с размером, и все копирования/перемещения поддерживали их в актуальном состоянии.
Под BeOS -- не помню, BFS изначально этого умела или не умела. Но можно было что-то сгородить самому, через дополнительные атрибуты+ live queries.
Любую ФС с дополнительными аттрибутами вроде xattr можно доработать до требуемого. Правда, понадобится как-то цепляться событиями через Inotify/Dnotify к какому-то демону, который будет сидеть в фоне и отслеживать. Демон должен быть достаточно производительный (дёргаться будет часто) и умный (не дёргаться слишком часто, например, понимать если делается mv в пределах директории, что "сумма слагаемых" не изменится, но если двигаем с dir1/dir2 в dir1/dir3 , что это транзакция dir1=const;dir2-=N;dir3+=N; не вызываться слишком часто , "по отдельности" для каждой такой dir4/dir5/dir6, если их двигаем все вместе, а и обновлять все "метаданные" скопом, для dir4/5/6.)
В общем виде, от ФС требуется поддержка транзакционности (и для не журналируемых ФС будет сделать сложновато), поддержка доп. атрибутов, достаточно быстрая работа связки (ФС-ядро-демон обновления), разумная структура "итоговых" данных, чтобы не пришлось при перем. 1000 файлов делать 1000 обновлений в метаданных (то есть, какой-то индекс).
Ещё если раскатать губу, то хочется ведь не только 'du -s', а навесить любую команду. И чтобы она работала быстро, то есть, чтобы поддерживались 'live queries'.
> Реализация имеет по крайней мере одну очевидную проблему: хардлинки. Представьте себе, что у вас один и тот же файл существует под разными именами в десятке каталогов, как тогда менять счётчик у всех у них? Получается, что надо хранить список каталогов, которые на каждый файл ссылаются, ну положим не пути, а только inode, но все равно
N хардлинков = 1 inode, счётчик у файла нужен только 1. Счётчик у директорий тут да, получается довольно хитрым.
> для каждого write придется делать по нескольку обновлений счетчиков
счётчики должны быть более разумными. Грубо говоря, нужно уметь понимать, какая транзакция проходит, cp/mv/что-то ещё, и выбирать счётчики для минимизации количество обновлений. В крайнем предельном случае, что будет страшного, если одни "часто употребляемые" счётчики будут представлены как значения (индексы), а другие -- как лениво отложенные запросы (и вызываться только если запрос требует именно их, а не вышестоящие индексы)?
Алсо, по-моему, стоит рассмотреть, как работало (в ядрах 2.24) rlocate/mlocate. Там был хитрый индекс, который не дёргался слишком часто. И обновлялся он на лету, по "мелким изменениям" файлов.
1000 обновлений для 1000 файлов, грубо говоря, не понадобится. Если поддерживать какой-то кеш с размерами файлов и директорий (счётчиков), всё, что нужно -- это продумать грамотную схему изменения/кеширования счётчиков. Например, размер директории можно хранить значением (актуальным на какую-то транзакцию ФС), или ленивым вычислением типа "взять старое значение счётчика, скорректировать его на N", где N -- значение другого, достаточно высокоуровнего, крупного счётчика. То есть, счётчики являются типа индексами для такого рода запросов, и конкретный набор счётчиков подбирается с учётом транзакций (транзакция "перемещение 1000 файлов" -- это одна транзакция с изменением на N), а при вычислении такого "ленивого запроса" используется что-то вроде memoizing для обновления значения, кеширования и индексации в других запросах. Вопрос собственно в поиске баланса между тем, что хранить как значения (как индексы в БД, и мириться с изменением индексов каскадной цепочкой триггеров), а что -- как скешированные лениво вычисляемые значение(тоже теже индексы).
все это нах не надо.
Если директория содержит много файлов и часто надо проверять disk usage, то проще выделить отдельный раздел и смотреть df или квотами мерять потребление per user (при учете что 1юзер == 1директория)