commit 167da5aa0f2333ae79765c024d7415d689045408
parent 69f6bebf17cd459725cccc22942cb9427001825a
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sun, 24 Sep 2023 07:57:13 +0900
update iofs
Diffstat:
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()