diff --git a/MTFS/OpenOS/usr/bin/importfs.lua b/MTFS/OpenOS/usr/bin/importfs.lua index 57d3987..972162c 100644 --- a/MTFS/OpenOS/usr/bin/importfs.lua +++ b/MTFS/OpenOS/usr/bin/importfs.lua @@ -1,3 +1,4 @@ +local computer = require "computer" local fs = require "filesystem" local rpc = require "rpc" local tA = {...} @@ -19,7 +20,52 @@ for k,v in pairs(px) do mc = mc + 1 end if mc < 1 then - error("no such remote filesystem: "..addr) + error("no such remote filesystem: "..rpath) end +local statcache = {} px.address = rpath +if px.dirstat then -- use single call for file info + function px.list(path) + local t,e = px.dirstat(path) + if not t then return nil,e end + local rt = {} + for k,v in pairs(t) do + rt[#rt+1] = k + statcache[fs.canonical("/"..path.."/"..k)] = {computer.uptime(),v[1],v[2],v[3]} + end + return rt + end + local oid, osize, olm = px.isDirectory, px.size, px.lastModified + local function cc() -- clean the cache of old entries + for k,v in pairs(statcache) do + if computer.uptime() > v[1] + 1 then + statcache[k] = nil + end + end + end + function px.isDirectory(path) + cc() + local ci = statcache["/"..fs.canonical(path)] + if ci then + return ci[3] + end + return oid(path) + end + function px.size(path) + cc() + local ci = statcache["/"..fs.canonical(path)] + if ci then + return ci[2] + end + return osize(path) + end + function px.lastModified(path) + cc() + local ci = statcache["/"..fs.canonical(path)] + if ci then + return ci[3] + end + return olm(path) + end +end fs.mount(px, lpath) diff --git a/MTFS/OpenOS/usr/lib/fsproxy.lua b/MTFS/OpenOS/usr/lib/fsproxy.lua index d343b0b..e3cc55d 100644 --- a/MTFS/OpenOS/usr/lib/fsproxy.lua +++ b/MTFS/OpenOS/usr/lib/fsproxy.lua @@ -74,6 +74,17 @@ function fsproxy.new(path,wp) -- string boolean -- table -- Returns a proxy obje function proxy.size(path) return fs.size(cpath..sanitisePath(path)) end + + function proxy.dirstat(path) -- bundle the metadata about files into the listing to reduce round trips + local rt = {} + local dp = cpath..sanitisePath(path).."/" + local iter, err = fs.list(dp) + if not iter then return nil, err end + for name in iter do + rt[name] = {fs.isDirectory(dp..name), fs.size(dp..name), fs.lastModified(dp..name)} + end + return rt + end function proxy.open(path,mode) if wp and mode:find("[wa]") then return false, "read-only filesystem" end