aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nlplug-findfs.c23
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";