context fs

This commit is contained in:
royalcat 2024-03-21 00:47:51 +03:00
parent fd3beea874
commit 7b1863109c
25 changed files with 593 additions and 349 deletions
src/host/vfs

View file

@ -1,6 +1,7 @@
package vfs
import (
"context"
"fmt"
"io/fs"
"path"
@ -22,41 +23,41 @@ func NewResolveFS(rootFs Filesystem, factories map[string]FsFactory) *ResolverFS
}
// Open implements Filesystem.
func (r *ResolverFS) Open(filename string) (File, error) {
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open)
func (r *ResolverFS) Open(ctx context.Context, filename string) (File, error) {
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(ctx, filename, r.rootFS.Open)
if err != nil {
return nil, err
}
if nestedFs != nil {
return nestedFs.Open(nestedFsPath)
return nestedFs.Open(ctx, nestedFsPath)
}
return r.rootFS.Open(fsPath)
return r.rootFS.Open(ctx, fsPath)
}
// ReadDir implements Filesystem.
func (r *ResolverFS) ReadDir(dir string) ([]fs.DirEntry, error) {
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(dir, r.rootFS.Open)
func (r *ResolverFS) ReadDir(ctx context.Context, dir string) ([]fs.DirEntry, error) {
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(ctx, dir, r.rootFS.Open)
if err != nil {
return nil, err
}
if nestedFs != nil {
return nestedFs.ReadDir(nestedFsPath)
return nestedFs.ReadDir(ctx, nestedFsPath)
}
entries, err := r.rootFS.ReadDir(fsPath)
entries, err := r.rootFS.ReadDir(ctx, fsPath)
if err != nil {
return nil, err
}
out := make([]fs.DirEntry, 0, len(entries))
for _, e := range entries {
if r.resolver.isNestedFs(e.Name()) {
filepath := path.Join(dir, e.Name())
file, err := r.Open(filepath)
filepath := path.Join("/", dir, e.Name())
file, err := r.Open(ctx, filepath)
if err != nil {
return nil, err
}
nestedfs, err := r.resolver.nestedFs(filepath, file)
nestedfs, err := r.resolver.nestedFs(ctx, filepath, file)
if err != nil {
return nil, err
}
@ -70,29 +71,29 @@ func (r *ResolverFS) ReadDir(dir string) ([]fs.DirEntry, error) {
}
// Stat implements Filesystem.
func (r *ResolverFS) Stat(filename string) (fs.FileInfo, error) {
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open)
func (r *ResolverFS) Stat(ctx context.Context, filename string) (fs.FileInfo, error) {
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(ctx, filename, r.rootFS.Open)
if err != nil {
return nil, err
}
if nestedFs != nil {
return nestedFs.Stat(nestedFsPath)
return nestedFs.Stat(ctx, nestedFsPath)
}
return r.rootFS.Stat(fsPath)
return r.rootFS.Stat(ctx, fsPath)
}
// Unlink implements Filesystem.
func (r *ResolverFS) Unlink(filename string) error {
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(filename, r.rootFS.Open)
func (r *ResolverFS) Unlink(ctx context.Context, filename string) error {
fsPath, nestedFs, nestedFsPath, err := r.resolver.resolvePath(ctx, filename, r.rootFS.Open)
if err != nil {
return err
}
if nestedFs != nil {
return nestedFs.Unlink(nestedFsPath)
return nestedFs.Unlink(ctx, nestedFsPath)
}
return r.rootFS.Unlink(fsPath)
return r.rootFS.Unlink(ctx, fsPath)
}
// Info implements Filesystem.
@ -117,7 +118,7 @@ func (r *ResolverFS) Type() fs.FileMode {
var _ Filesystem = &ResolverFS{}
type FsFactory func(f File) (Filesystem, error)
type FsFactory func(ctx context.Context, f File) (Filesystem, error)
const Separator = "/"
@ -135,7 +136,7 @@ type resolver struct {
// TODO: add fsmap clean
}
type openFile func(path string) (File, error)
type openFile func(ctx context.Context, path string) (File, error)
func (r *resolver) isNestedFs(f string) bool {
for ext := range r.factories {
@ -146,7 +147,7 @@ func (r *resolver) isNestedFs(f string) bool {
return false
}
func (r *resolver) nestedFs(fsPath string, file File) (Filesystem, error) {
func (r *resolver) nestedFs(ctx context.Context, fsPath string, file File) (Filesystem, error) {
for ext, nestFactory := range r.factories {
if !strings.HasSuffix(fsPath, ext) {
continue
@ -156,7 +157,7 @@ func (r *resolver) nestedFs(fsPath string, file File) (Filesystem, error) {
return nestedFs, nil
}
nestedFs, err := nestFactory(file)
nestedFs, err := nestFactory(ctx, file)
if err != nil {
return nil, fmt.Errorf("error creating filesystem from file: %s with error: %w", fsPath, err)
}
@ -169,7 +170,7 @@ func (r *resolver) nestedFs(fsPath string, file File) (Filesystem, error) {
}
// open requeue raw open, without resolver call
func (r *resolver) resolvePath(name string, rawOpen openFile) (fsPath string, nestedFs Filesystem, nestedFsPath string, err error) {
func (r *resolver) resolvePath(ctx context.Context, name string, rawOpen openFile) (fsPath string, nestedFs Filesystem, nestedFsPath string, err error) {
name = path.Clean(name)
name = strings.TrimPrefix(name, Separator)
parts := strings.Split(name, Separator)
@ -206,11 +207,11 @@ PARTS_LOOP:
if nestedFs, ok := r.fsmap[fsPath]; ok {
return fsPath, nestedFs, nestedFsPath, nil
} else {
fsFile, err := rawOpen(fsPath)
fsFile, err := rawOpen(ctx, fsPath)
if err != nil {
return "", nil, "", fmt.Errorf("error opening filesystem file: %s with error: %w", fsPath, err)
}
nestedFs, err := nestFactory(fsFile)
nestedFs, err := nestFactory(ctx, fsFile)
if err != nil {
return "", nil, "", fmt.Errorf("error creating filesystem from file: %s with error: %w", fsPath, err)
}