policy: close memoized policy filesystems

Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax
2026-07-11 16:59:58 +02:00
parent 041dcec566
commit d5c8b8894c
2 changed files with 134 additions and 14 deletions
+73 -14
View File
@@ -152,11 +152,21 @@ func newPolicyPathFS(ctx context.Context, resolver *sourcemeta.Resolver, popt po
}
return func() (fs.StatFS, func() error, error) {
return p, p.Close, nil
ref := &policyPathFSRef{policyPathFS: p}
return ref, ref.Close, nil
}
}
func (p *policyPathFS) Open(name string) (fs.File, error) {
type policyPathFSRef struct {
*policyPathFS
mu sync.Mutex
cwdRoot fs.StatFS
cwdClose func() error
contextRoot fs.StatFS
contextClose func() error
}
func (p *policyPathFSRef) Open(name string) (fs.File, error) {
backend, target, err := p.resolve(name)
if err != nil {
return nil, err
@@ -167,7 +177,7 @@ func (p *policyPathFS) Open(name string) (fs.File, error) {
return backend.Open(target)
}
func (p *policyPathFS) Stat(name string) (fs.FileInfo, error) {
func (p *policyPathFSRef) Stat(name string) (fs.FileInfo, error) {
backend, target, err := p.resolve(name)
if err != nil {
return nil, err
@@ -178,14 +188,7 @@ func (p *policyPathFS) Stat(name string) (fs.FileInfo, error) {
return backend.Stat(target)
}
func (p *policyPathFS) Close() error {
if err := p.cwdFS.close(); err != nil {
return err
}
return p.contextFS.close()
}
func (p *policyPathFS) resolve(name string) (fs.StatFS, string, error) {
func (p *policyPathFSRef) resolve(name string) (fs.StatFS, string, error) {
if name == "" {
return nil, "", errors.New("policy filename is empty")
}
@@ -193,14 +196,14 @@ func (p *policyPathFS) resolve(name string) (fs.StatFS, string, error) {
if v == "" {
return nil, "", errors.Errorf("invalid policy filename %q", name)
}
cwd, err := p.cwdFS.get()
cwd, err := p.getCwdFS()
if err != nil {
return nil, "", err
}
return cwd, filepath.Clean(v), nil
}
contextFS, err := p.contextFS.get()
contextFS, err := p.getContextFS()
if err != nil {
return nil, "", err
}
@@ -214,6 +217,62 @@ func (p *policyPathFS) resolve(name string) (fs.StatFS, string, error) {
return contextFS, normalizeLocalPolicyPath(name, p.contextDir), nil
}
func (p *policyPathFSRef) getCwdFS() (fs.StatFS, error) {
p.mu.Lock()
defer p.mu.Unlock()
if p.cwdClose != nil {
return p.cwdRoot, nil
}
cwd, err := p.cwdFS.get()
if err != nil {
return nil, err
}
p.cwdRoot = cwd
p.cwdClose = p.cwdFS.close
return cwd, nil
}
func (p *policyPathFSRef) getContextFS() (fs.StatFS, error) {
p.mu.Lock()
defer p.mu.Unlock()
if p.contextClose != nil {
return p.contextRoot, nil
}
contextFS, err := p.contextFS.get()
if err != nil {
return nil, err
}
p.contextRoot = contextFS
p.contextClose = p.contextFS.close
return contextFS, nil
}
func (p *policyPathFSRef) Close() error {
p.mu.Lock()
cwdClose := p.cwdClose
contextClose := p.contextClose
p.cwdRoot = nil
p.contextRoot = nil
p.cwdClose = nil
p.contextClose = nil
p.mu.Unlock()
var firstErr error
if cwdClose != nil {
if err := cwdClose(); err != nil {
firstErr = err
}
}
if contextClose != nil {
if err := contextClose(); err != nil {
if firstErr == nil {
firstErr = err
}
}
}
return firstErr
}
func normalizeLocalPolicyPath(name, contextDir string) string {
if filepath.IsAbs(name) && contextDir != "" {
if rel, err := filepath.Rel(contextDir, name); err == nil {
@@ -405,7 +464,7 @@ func (i policyFileInfo) Sys() any {
return &types.Stat{Mode: uint32(i.mode), Size: i.size, ModTime: i.tm.UnixNano()}
}
var _ fs.StatFS = (*policyPathFS)(nil)
var _ fs.StatFS = (*policyPathFSRef)(nil)
var _ fs.StatFS = (*remotePolicyFS)(nil)
var _ fs.File = (*policyReadFile)(nil)
var _ io.ReaderAt = (*bytes.Reader)(nil)