Наиболее эффективный подход, зная файловую систему, в которой вы ищете, состоит в том, чтобы открыть связанное блочное устройство и выполнить поиск (блок за блоком) таблицы инодов, а также проверить фактический размер по находящимся там инодам (откройте блочное устройство, поэтому вы получаете иноды из образов в памяти, а не с диска). Это позволяет вам быстро и просто получить все inode файловой системы нулевой длины. Недостатком является то, что вам сначала нужно получить информацию о файловой системе, а затем получить прямой доступ к блочному устройству, что обычно запрещено для процесса без полномочий root. После этого вам нужно выполнить поиск файловой системы, чтобы получить имена задействованных файлов, на тот случай, если вам нужно что-то сделать с этими файлами.
Кстати, ваше предположение о том, что не может использовать fstat(2)
в дескрипторе общего файла с другим потоком, неверно , так как системный вызов stat работает с дескриптором открытого файла и не ' ничего не делать с файлом - он неблокирующий - и система гарантирует, что индекс заблокирован при доступе к структуре статистики.
Подход с использованием lseek(2)
в этом случае недопустим, потому что он фактически перемещает указатель файла в конец файла, а затем обратно в сохраненное место, и для этого требуется два системных вызова, чтобы сделать и отмените ход , и существует множество сценариев гонки, которые могут произойти, если другой поток использует другой системный вызов (делает write(2)
, между двумя), пока у вас есть указатель файла в другом месте.
Unix (включая все системы posix linux, bsd и т. Д.) Гарантирует, что неблокирующий системный вызов (как stat(2)
) является атомарным по своей природе, блокируя inode файла во время выполнения процесса (или потока) системный вызов. Так что никакой другой поток не может использовать файл, пока ваш системный вызов stat(2)
получает данные. Даже при блокировке вызовов unix гарантирует, что для выполнения будет использован другой системный вызов, выполненный для того же дескриптора, и процессу / потоку придется ждать до завершения системного вызова stat(2)
.
Проблема в fstat(2)
заключается в том, что он должен решить все элементы пути, пока не доберется до конечного индекса файла (это место, где хранится длина файла), и это делается один за другим. основа. До тех пор, пока он не доберется до последнего инода, не будет заблокирована последняя инода (на самом деле, он неизвестен, пока мы не доберемся до него, поэтому мы не можем заблокировать его, пока не закончим разрешение namei()
), а затем он решается как оригинал stat(2)
.
ЗАКЛЮЧЕНИЕ
Используйте stat(2)
с другим потоком дескриптор файла, не опасаясь повреждения данных, это невозможно. Не стесняйтесь делать это, так как ничего не случится с inode файла, пока вы собираете информацию stat
.