Por que meu tipo find está executando fstat em todos os arquivos de uma pasta?

3

Estou executando find . -type d em uma árvore de diretórios bastante grande. Eu só estou interessado em encontrar diretórios dentro desta árvore, mas quando corri um strace contra o processo para ter certeza de que estava fazendo o que eu esperava, percebi que há uma enorme quantidade de operações sendo desperdiçadas executando o fstat contra arquivos dentro da árvore.

newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0600, st_size=7690, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "file2", {st_mode=S_IFREG|0600, st_size=7696, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "file3", {st_mode=S_IFREG|0600, st_size=7687, ...}, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(AT_FDCWD, "file4", {st_mode=S_IFREG|0600, st_size=10455, ...}, AT_SYMLINK_NOFOLLOW) = 0

Está ciente de que um inode está apontando para um diretório até que ele execute um fstat? Se for esse o caso, isso levará muito tempo. Alguns desses diretórios provavelmente têm milhões de itens dentro deles, mas eu realmente me preocupo com diretórios.

Em última análise, gostaria de um relatório do dirsize e caminho de cada um dos diretórios na minha árvore de arquivos. Qual é a maneira mais rápida / mais eficiente de fazer isso?

    
por Nathan 25.10.2014 / 05:44

2 respostas

4

Sim, parece que realmente é o caso de encontrar fstat para determinar o tipo do arquivo. Isso é levemente surpreendente, considerando que o dirent contém as informações desde o kernel 2.6.4.

Nem todos os sistemas de arquivos têm suporte para o comportamento do dirent estendido, portanto, isso é verdadeiro no seu caso ou o find não o utiliza. Sem conhecer o seu tipo de sistema de arquivos, não podemos decidir.

    
por 25.10.2014 / 09:27
1

Como eu tenho certeza que você sabe, um diretório é um tipo especial de arquivo no paradigma do UNIX. Para determinar se algo é um diretório ou outro tipo de arquivo, ele deve ser interrogado e fstat () é uma boa maneira de fazer isso.

Acredito que sistemas de arquivos e fs-drivers posteriores mantenham uma tabela separada apenas dos diretórios, mas o comando find data há décadas e provavelmente não está adaptado a sistemas de arquivos mais novos ou mantém a compatibilidade com versões anteriores.

Você pode fingir executando um trabalho recorrente a partir do CRON (com um bom valor > 0 se quiser ser fácil na utilização do IO para outros processos) que faz um:

find ${DIRECTORY} -type d -print >${DIRECTORY}/.only_folders

Então, quando você precisar disso, use o conteúdo do arquivo que você pré-construiu, em vez de percorrer o diretório novamente.

cat "${DIRECTORY}/.only_folders" |while read FOLDER ; do
  do_work.sh ${FOLDER} ;
done

em vez de algo como

find ${DIRECTORY} -type d |xargs do_work.sh
    
por 25.10.2014 / 17:26