home: hub: mkinitfs

Download patch

ref: 91a70d3906fd3614cbfd335f1cedcf2d94950c35
parent: c9891b80712725db0bd696dc0bdfcde31286d6ca
author: Natanael Copa <ncopa@alpinelinux.org>
date: Fri Oct 9 09:54:16 CDT 2015

nlplug-findfs: avoid lstat syscall wen scanning /sys if possible

There are ~10k entries in /sys so we want be fast. Not all filesystems
supports dirent filed d_type, (iso9660 for example) so we need use lstat
to find directories. However, we know that sysfs supports it, so we can
avoid 10k lstat syscalls. This might be noticiable difference on rpi.

--- a/nlplug-findfs.c
+++ b/nlplug-findfs.c
@@ -265,6 +265,7 @@
 	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 @@
 		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 @@
 		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 @@
 			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 @@
 		.searchname = ".boot_repository",
 		.callback = bootrepo_cb,
 		.userdata = &repos,
+		.fastdir = 0,
 	};
 
 
@@ -591,6 +603,7 @@
 		.searchname = "uevent",
 		.callback = trigger_uevent_cb,
 		.userdata = NULL,
+		.fastdir = 1,
 	};
 	char path[PATH_MAX] = "/sys/bus";