problemy z XFS

W trakcie testów odkryłem, że na RedHacie oraz Centosie 7 nie działa funkcja kasująca katalog zawierający pliki witryny. Szybki reaserch wykazał, że wspólnym mianownikiem jest używany na tych systemach filesystem XFS. Okazuje się, że struktura dirent zwracana przez funkcję readdir(3) na tym systemie plików zwraca niepoprawne dane.

if(entry->d_type == 4) {
   strcat(buff, entry->d_name);
   strcat(buff, "/");
   printf("type: %u, name: %s\n", entry->d_type, buff);
   printdir(buff);
}

w d_type w każdym przypadku pojawia się 0 (zero). Okazuje się, że problem jest powszechnie znany co najmniej od roku 🙂 Oczywiście jest na to sposób. Polega on na użyciu funkcji stat(2), która jest kompatybilna z XFS oraz system plików EXT. Funkcja stat(2) używa struktury o nazwie stat i posiada zestaw makr, którymi można m.in. rozpoznać, czy dany node jest plikiem czy katalogiem.

Kluczowy fragment kodu wygląda następująco:

strcat(buff, entry->d_name);
stat(buff, &n);
if(S_ISDIR(n.st_mode)) {
   strcat(buff, "/");
   printf("type: %ld, name: %s\n", (unsigned long) n.st_mode & S_IFMT, buff);
   printdir(buff);
 }

Jest to fragment funkcji rekurencyjnej, która się wywołuje w momencie, kiedy dany node za pomocą makra S_ISDIR rozpoznany zostaje jako katalog.