Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf trace: Handle DT_UNKNOWN on filesystems that don't support d_type

Some filesystems like xfs and reiserfs will return DT_UNKNOWN for the
d_type. Handle this case by calling stat() to determine the type.

Cc: Andreas Schwab <schwab@linux-m68k.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1290355779-3276-1-git-send-email-sbohrer@rgmadvisors.com>
Signed-off-by: Shawn Bohrer <sbohrer@rgmadvisors.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Shawn Bohrer and committed by
Arnaldo Carvalho de Melo
008f29d3 9d1faba5

+25 -8
+25 -8
tools/perf/builtin-trace.c
··· 301 301 return 0; 302 302 } 303 303 304 - #define for_each_lang(scripts_dir, lang_dirent, lang_next) \ 304 + /* Helper function for filesystems that return a dent->d_type DT_UNKNOWN */ 305 + static int is_directory(const char *base_path, const struct dirent *dent) 306 + { 307 + char path[PATH_MAX]; 308 + struct stat st; 309 + 310 + sprintf(path, "%s/%s", base_path, dent->d_name); 311 + if (stat(path, &st)) 312 + return 0; 313 + 314 + return S_ISDIR(st.st_mode); 315 + } 316 + 317 + #define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\ 305 318 while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \ 306 319 lang_next) \ 307 - if (lang_dirent.d_type == DT_DIR && \ 320 + if ((lang_dirent.d_type == DT_DIR || \ 321 + (lang_dirent.d_type == DT_UNKNOWN && \ 322 + is_directory(scripts_path, &lang_dirent))) && \ 308 323 (strcmp(lang_dirent.d_name, ".")) && \ 309 324 (strcmp(lang_dirent.d_name, ".."))) 310 325 311 - #define for_each_script(lang_dir, script_dirent, script_next) \ 326 + #define for_each_script(lang_path, lang_dir, script_dirent, script_next)\ 312 327 while (!readdir_r(lang_dir, &script_dirent, &script_next) && \ 313 328 script_next) \ 314 - if (script_dirent.d_type != DT_DIR) 329 + if (script_dirent.d_type != DT_DIR && \ 330 + (script_dirent.d_type != DT_UNKNOWN || \ 331 + !is_directory(lang_path, &script_dirent))) 315 332 316 333 317 334 #define RECORD_SUFFIX "-record" ··· 483 466 if (!scripts_dir) 484 467 return -1; 485 468 486 - for_each_lang(scripts_dir, lang_dirent, lang_next) { 469 + for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { 487 470 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 488 471 lang_dirent.d_name); 489 472 lang_dir = opendir(lang_path); 490 473 if (!lang_dir) 491 474 continue; 492 475 493 - for_each_script(lang_dir, script_dirent, script_next) { 476 + for_each_script(lang_path, lang_dir, script_dirent, script_next) { 494 477 script_root = strdup(script_dirent.d_name); 495 478 str = ends_with(script_root, REPORT_SUFFIX); 496 479 if (str) { ··· 531 514 if (!scripts_dir) 532 515 return NULL; 533 516 534 - for_each_lang(scripts_dir, lang_dirent, lang_next) { 517 + for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { 535 518 snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, 536 519 lang_dirent.d_name); 537 520 lang_dir = opendir(lang_path); 538 521 if (!lang_dir) 539 522 continue; 540 523 541 - for_each_script(lang_dir, script_dirent, script_next) { 524 + for_each_script(lang_path, lang_dir, script_dirent, script_next) { 542 525 __script_root = strdup(script_dirent.d_name); 543 526 str = ends_with(__script_root, suffix); 544 527 if (str) {