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
This commit is contained in:
Kyle Evans 2021-01-23 19:32:38 -06:00
parent 80a840b8ba
commit e25ee296c9
2 changed files with 33 additions and 3 deletions

View File

@ -122,6 +122,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)
{
@ -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;
}

View File

@ -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