lib9p

Go 9P library.
Log | Files | Refs | LICENSE

commit 66deafdfb4f8b18f23c7296c3203440ba6ecca20
parent a4393eee59500105689e3e355db32e6a46951d07
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue,  9 Jan 2024 15:40:03 +0900

delete fs.Glob

Diffstat:
Mfid.go | 2++
Mserver.go | 40++++++++++++++++++++++++----------------
2 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/fid.go b/fid.go @@ -2,6 +2,7 @@ package lib9p import ( "fmt" + "io/fs" "sync" ) @@ -36,6 +37,7 @@ type fid struct { uid string // The user id derived from the attach message. dirOffset uint64 // Used when reading directory. dirIndex int // Used when reading directory. + dirEnts []fs.DirEntry // DirEntry cache. } // NOFID is used in afid field of Tattach message when no authentication diff --git a/server.go b/server.go @@ -715,7 +715,7 @@ func sRead(ctx context.Context, c *conn, rc <-chan *request) { fi fs.FileInfo err error data []byte - errc chan error + done chan struct{} n int ) if !ok { @@ -741,28 +741,37 @@ func sRead(ctx context.Context, c *conn, rc <-chan *request) { goto resp } data = make([]byte, ifcall.Count) - errc = make(chan error) + done = make(chan struct{}) go func() { - defer close(errc) + defer close(done) if fi.IsDir() { if ifcall.Offset != 0 && ifcall.Offset != r.fid.dirOffset { - errc <- fmt.Errorf("invalid dir offset") - return - } - children, err := fs.Glob(ExportFS{r.fid.fs}, path.Join(r.fid.path, "*")) - if err != nil { - errc <- fmt.Errorf("glob children: %v", err) + err = fmt.Errorf("invalid dir offset") return } - if ifcall.Offset == 0 { + if ifcall.Offset == 0 && r.fid.dirIndex != 0 { r.fid.dirIndex = 0 r.fid.dirOffset = 0 + r.fid.dirEnts = nil + if err = r.fid.file.Close(); err != nil { + return + } + r.fid.file, err = r.fid.fs.OpenFile(r.fid.path, r.fid.omode) + if err != nil { + return + } + } + if r.fid.dirIndex == 0 { + r.fid.dirEnts, err = r.fid.file.(ReadDirFile).ReadDir(-1) + if err != nil { + return + } } k := r.fid.dirIndex - for ; k < len(children); k++ { - fi, err := fs.Stat(ExportFS{r.fid.fs}, children[k]) + for ; k < len(r.fid.dirEnts); k++ { + fi, err := r.fid.dirEnts[k].Info() if err != nil { - log.Printf("stat: %v", err) + log.Println(err) continue } st := fi.Sys().(*Stat) @@ -776,7 +785,7 @@ func sRead(ctx context.Context, c *conn, rc <-chan *request) { n += len(buf) } r.fid.dirOffset += uint64(n) - r.fid.dirIndex = k + r.fid.dirIndex += k } else { var err error if reader, ok := r.fid.file.(io.ReaderAt); ok { @@ -785,13 +794,12 @@ func sRead(ctx context.Context, c *conn, rc <-chan *request) { n, err = r.fid.file.Read(data) } if err != io.EOF && err != nil { - errc <- err return } } }() select { - case err := <-errc: + case <-done: if err != nil { r.err = err goto resp