lib9p

Go 9P library.
Log | Files | Refs

commit 167da5aa0f2333ae79765c024d7415d689045408
parent 69f6bebf17cd459725cccc22942cb9427001825a
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sun, 24 Sep 2023 07:57:13 +0900

update iofs

Diffstat:
Miofs/file.go | 93+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Miofs/fs.go | 20++++++++++++--------
Miofs/qid.go | 21+++++++++++++--------
Mserver.go | 1+
4 files changed, 82 insertions(+), 53 deletions(-)

diff --git a/iofs/file.go b/iofs/file.go @@ -13,10 +13,8 @@ type File struct { fs *FS // file system to which this file belongs file fs.File // underlying file path string // absolute path from the root of the fs. - diroff int // directory offset to be read from. - childEntry []*lib9p.DirEntry } - +/* func openFile(fsys *FS, fpath string) (*File, error) { file, err := fsys.fs.Open(fpath) if err != nil { @@ -29,55 +27,45 @@ func openFile(fsys *FS, fpath string) (*File, error) { } return f, nil } +*/ func (f *File) Fsys() lib9p.FS { return f.fs } func (f *File) Parent() (lib9p.File, error) { parentPath := path.Dir(f.path) - parent, err := f.fs.Open(parentPath) - if err != nil { - return nil, fmt.Errorf("open: %v", err) + match, err := fs.Glob(f.fs.fs, parentPath) + if err != nil || len(match) != 1 { + return nil, fmt.Errorf("parent not found. err: %v", err) } - return parent, nil + return &File{ + fs: f.fs, + path: match[0], + }, nil } func (f *File) Child() ([]lib9p.File, error) { - if f.childEntry == nil { - dir, ok := f.file.(fs.ReadDirFile) - if !ok { - return nil, fmt.Errorf("not a directory") - } - fsde, err := dir.ReadDir(-1) - if err != nil { - return nil, err - } - de := make([]*lib9p.DirEntry, len(fsde)) - for i := 0; i < len(de); i++ { - info, err := fsde[i].Info() - if err != nil { - return nil, fmt.Errorf("stat: %v", err) - } - - fpath := path.Join(f.path, info.Name()) - - de[i] = &lib9p.FileInfo{*fiStat(f.fs.qidPool, fileID(fpath), info)} - } - f.childEntry = de + childnames, err := fs.Glob(f.fs.fs, f.path + "/*") + if err != nil { + return nil, err } - children := make([]lib9p.File, len(f.childEntry)) - for i, ent := range f.childEntry { - cpath := path.Join(f.path, ent.Name()) - c, err := f.fs.Open(cpath) - if err != nil { - return children, fmt.Errorf("open: %v", err) + children := make([]lib9p.File, len(childnames)) + for i, name := range childnames { + children[i] = &File{ + fs: f.fs, + path: name, } - children[i] = c } return children, nil } func (f *File) Stat() (*lib9p.FileInfo, error) { - fsfi, err := f.file.Stat() + fsfile, err := f.fs.fs.Open(f.path) + if err != nil { + return nil, fmt.Errorf("open: %v", err) + } + defer fsfile.Close() + + fsfi, err := fsfile.Stat() if err != nil { return nil, fmt.Errorf("stat: %v") } @@ -104,11 +92,42 @@ func (f *File) Stat() (*lib9p.FileInfo, error) { return &lib9p.FileInfo{stat}, nil } +func (f *File) Qid() lib9p.Qid { + qid, ok := f.fs.qidPool.lookup(f) + if !ok { + var err error + qid, err = f.fs.qidPool.alloc(f) + if err != nil { + panic(fmt.Errorf("alloc qid: %v", err)) + } + } + return qid +} + +func (f *File) Open(mode lib9p.OpenMode) error { + fsfile, err := f.fs.fs.Open(f.path) + if err != nil { + return err + } + f.file = fsfile + return nil +} + func (f *File) Close() error { - return f.file.Close() + if f.file == nil { + return fmt.Errorf("not open") + } + if err := f.file.Close(); err != nil { + return err + } + f.file = nil + return nil } func (f *File) Read(b []byte) (int, error) { + if f.file == nil { + return 0, fmt.Errorf("not open") + } return f.file.Read(b) } diff --git a/iofs/fs.go b/iofs/fs.go @@ -11,20 +11,23 @@ DiskFS is a file system opened by OpenDiskFS */ type FS struct { fs fs.FS + root *File qidPool *QidPool } func NewFS(fsys fs.FS) *FS { - return &FS{ + root := &File{ + path: ".", + } + fs := &FS{ fs: fsys, + root: root, qidPool: allocQidPool(), } + root.fs = fs + return fs } -func (fsys *FS) Open(name string) (lib9p.File, error) { - file, err := openFile(fsys, name) - if err != nil { - return nil, err - } - return file, nil -} +func (fs *FS) Root() lib9p.File { + return fs.root +} +\ No newline at end of file diff --git a/iofs/qid.go b/iofs/qid.go @@ -20,12 +20,7 @@ type QidPool struct { } func (f *File) id() (fileID, error) { - fi, err := f.file.Stat() - if err != nil { - return fileID(""), err - } - id := fileID(fi.Name()) - return id, nil + return fileID(f.path), nil } func allocQidPool() *QidPool { @@ -44,7 +39,12 @@ func (pool *QidPool) lookup(f *File) (lib9p.Qid, bool) { return lib9p.Qid{}, false } - stat, err := f.file.Stat() + fsfile, err := f.fs.fs.Open(f.path) + if err != nil { + return lib9p.Qid{}, false + } + defer fsfile.Close() + stat, err := fsfile.Stat() if err != nil { return lib9p.Qid{}, false } @@ -61,7 +61,12 @@ func (pool *QidPool) alloc(f *File) (lib9p.Qid, error) { if err != nil { return lib9p.Qid{}, fmt.Errorf("get id: %v", err) } - fi, err := f.file.Stat() + fsfile, err := f.fs.fs.Open(f.path) + if err != nil { + return lib9p.Qid{}, err + } + defer fsfile.Close() + fi, err := fsfile.Stat() if err != nil { return lib9p.Qid{}, fmt.Errorf("stat %v: %v", f, err) } diff --git a/server.go b/server.go @@ -342,6 +342,7 @@ func sOpen(s *Server, r *Req) { } func rOpen(r *Req, err error) { if err != nil { + setError(r, err) return } r.fid.OMode = r.ifcall.(*TOpen).Mode()