commit 66deafdfb4f8b18f23c7296c3203440ba6ecca20
parent a4393eee59500105689e3e355db32e6a46951d07
Author: Matsuda Kenji <info@mtkn.jp>
Date: Tue, 9 Jan 2024 15:40:03 +0900
delete fs.Glob
Diffstat:
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