diff options
-rw-r--r-- | nlplug-findfs.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/nlplug-findfs.c b/nlplug-findfs.c index be112d9..6b2c356 100644 --- a/nlplug-findfs.c +++ b/nlplug-findfs.c @@ -265,6 +265,7 @@ struct recurse_opts { const char *searchname; void (*callback)(const char *, const void *); void *userdata; + int fastdir; /* avoid lstat on sysfs which we know support d_type */ }; /* pathbuf needs hold PATH_MAX chars */ @@ -280,6 +281,7 @@ void recurse_dir(char *pathbuf, struct recurse_opts *opts) struct stat st; size_t pathlen = strlen(pathbuf); size_t namelen = strlen(entry->d_name); + int is_dir; /* d_type is not supported by all filesystems so we need lstat */ @@ -291,12 +293,21 @@ void recurse_dir(char *pathbuf, struct recurse_opts *opts) pathbuf[pathlen] = '/'; strcpy(&pathbuf[pathlen+1], entry->d_name); - if (lstat(pathbuf, &st) < 0) { - dbg("%s: %s", pathbuf, strerror(errno)); - goto next; + if (opts->fastdir) { + /* avoid the lstat syscall for sysfs which we know + support the d_type field. */ + is_dir = entry->d_type & DT_DIR; + } else { + /* some filesystems like iso9660 does not support + the d_type so we use lstat */ + if (lstat(pathbuf, &st) < 0) { + dbg("%s: %s", pathbuf, strerror(errno)); + goto next; + } + is_dir = S_ISDIR(st.st_mode); } - if (S_ISDIR(st.st_mode)) { + if (is_dir) { if (entry->d_name[0] == '.') goto next; } else if (opts->searchname @@ -304,7 +315,7 @@ void recurse_dir(char *pathbuf, struct recurse_opts *opts) goto next; } - if (S_ISDIR(st.st_mode)) + if (is_dir) recurse_dir(pathbuf, opts); else opts->callback(pathbuf, opts->userdata); @@ -376,6 +387,7 @@ static int find_bootrepos(const char *devnode, const char *type, .searchname = ".boot_repository", .callback = bootrepo_cb, .userdata = &repos, + .fastdir = 0, }; @@ -591,6 +603,7 @@ void *trigger_thread(void *data) .searchname = "uevent", .callback = trigger_uevent_cb, .userdata = NULL, + .fastdir = 1, }; char path[PATH_MAX] = "/sys/bus"; |