aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2021-01-24 01:32:38 +0000
committerKyle Evans <kevans@FreeBSD.org>2021-01-29 18:47:29 +0000
commite25ee296c919d6567aa76058a7049eac974797fb (patch)
treed4bdac024242eced85fb80d9932b5052d9aa796c
parent80a840b8ba03bafe299112e2364959d937a87fe1 (diff)
downloadsrc-e25ee296c919d6567aa76058a7049eac974797fb.tar.gz
src-e25ee296c919d6567aa76058a7049eac974797fb.zip
stand: lua: enhance lfs.dir() to speed up kernels_autodetect
This eliminates a lot of stat() calls that happen when lualoader renders the menu with the default settings, and greatly speeds up rendering on my laptop. ftype is nil if loader/loader.efi hasn't been updated yet, falling back to lfs.attributes() to test. This is technically incompatible with lfs, but not in a particularly terrible way. Reviewed-by: cem MFC-after: 4 days Differential Revision: https://reviews.freebsd.org/D27542
-rw-r--r--libexec/flua/modules/lfs.c28
-rw-r--r--stand/lua/core.lua8
2 files changed, 33 insertions, 3 deletions
diff --git a/libexec/flua/modules/lfs.c b/libexec/flua/modules/lfs.c
index 52a30c1515a9..e36c78d3b35b 100644
--- a/libexec/flua/modules/lfs.c
+++ b/libexec/flua/modules/lfs.c
@@ -123,6 +123,27 @@ __FBSDID("$FreeBSD$");
#define DIR_METATABLE "directory iterator metatable"
static int
+lua_dir_iter_pushtype(lua_State *L __unused, const struct dirent *ent __unused)
+{
+
+ /*
+ * This is a non-standard extension to luafilesystem for loader's
+ * benefit. The extra stat() calls to determine the entry type can
+ * be quite expensive on some systems, so this speeds up enumeration of
+ * /boot greatly by providing the type up front.
+ *
+ * This extension is compatible enough with luafilesystem, in that we're
+ * just using an extra return value for the iterator.
+ */
+#ifdef _STANDALONE
+ lua_pushinteger(L, ent->d_type);
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+static int
lua_dir_iter_next(lua_State *L)
{
struct dirent *entry;
@@ -144,7 +165,7 @@ lua_dir_iter_next(lua_State *L)
}
lua_pushstring(L, entry->d_name);
- return 1;
+ return 1 + lua_dir_iter_pushtype(L, entry);
}
static int
@@ -420,5 +441,10 @@ luaopen_lfs(lua_State *L)
{
register_metatable(L);
luaL_newlib(L, fslib);
+#ifdef _STANDALONE
+ /* Non-standard extension for loader, used with lfs.dir(). */
+ lua_pushinteger(L, DT_DIR);
+ lua_setfield(L, -2, "DT_DIR");
+#endif
return 1;
}
diff --git a/stand/lua/core.lua b/stand/lua/core.lua
index 9d331bc0ad3a..a119c3c258f8 100644
--- a/stand/lua/core.lua
+++ b/stand/lua/core.lua
@@ -240,14 +240,18 @@ function core.kernelList()
-- Automatically detect other bootable kernel directories using a
-- heuristic. Any directory in /boot that contains an ordinary file
-- named "kernel" is considered eligible.
- for file in lfs.dir("/boot") do
+ for file, ftype in lfs.dir("/boot") do
local fname = "/boot/" .. file
if file == "." or file == ".." then
goto continue
end
- if lfs.attributes(fname, "mode") ~= "directory" then
+ if ftype then
+ if ftype ~= lfs.DT_DIR then
+ goto continue
+ end
+ elseif lfs.attributes(fname, "mode") ~= "directory" then
goto continue
end