Synchronize toolsrv fid state

This commit is contained in:
Ollie Agent 2026-08-18 07:41:59 +02:00
parent c111cbd0ca
commit 6c476f4fb8
1 changed files with 30 additions and 12 deletions

View File

@ -17,6 +17,7 @@ import (
// fid represents an open file handle.
type fid struct {
mu sync.Mutex
path string
qid plan9.Qid
mode uint8
@ -393,20 +394,28 @@ func handleRead(cs *connState, fc *plan9.Fcall, tree *virtfs.Tree) *plan9.Fcall
if !isFid {
return errFcall(fc, "unknown fid")
}
if !f.opened {
f.mu.Lock()
opened := f.opened
qid := f.qid
entry := f.entry
f.mu.Unlock()
if !opened {
return errFcall(fc, "not open")
}
if f.qid.Type&plan9.QTDIR != 0 {
if qid.Type&plan9.QTDIR != 0 {
return handleDirRead(cs, f, fc, tree)
}
if f.entry == nil {
if entry == nil {
return errFcall(fc, "no entry")
}
// For rdwr files, check if we've already read
if f.entry.RdwrMode() && f.readDone {
f.mu.Lock()
readDone := entry.RdwrMode() && f.readDone
f.mu.Unlock()
if readDone {
return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Data: nil}
}
@ -494,8 +503,12 @@ func readSlice(fc *plan9.Fcall, content []byte) *plan9.Fcall {
}
func handleDirRead(cs *connState, f *fid, fc *plan9.Fcall, tree *virtfs.Tree) *plan9.Fcall {
if fc.Offset == 0 || f.dirCache == nil {
path := f.path
f.mu.Lock()
path := f.path
qidPath := f.path
cached := f.dirCache
f.mu.Unlock()
if fc.Offset == 0 || cached == nil {
if path == "/" {
path = ""
} else {
@ -517,7 +530,7 @@ func handleDirRead(cs *connState, f *fid, fc *plan9.Fcall, tree *virtfs.Tree) *p
}
dir := plan9.Dir{
Name: e.Name(),
Qid: plan9.Qid{Type: qt, Path: pathHash(f.path + "/" + e.Name())},
Qid: plan9.Qid{Type: qt, Path: pathHash(qidPath + "/" + e.Name())},
Mode: mode,
Uid: "toolsrv",
Gid: "toolsrv",
@ -525,20 +538,25 @@ func handleDirRead(cs *connState, f *fid, fc *plan9.Fcall, tree *virtfs.Tree) *p
data, _ := dir.Bytes()
buf = append(buf, data...)
}
f.dirCache = buf
f.mu.Lock()
if fc.Offset == 0 || f.dirCache == nil {
f.dirCache = buf
}
cached = f.dirCache
f.mu.Unlock()
}
offset := int(fc.Offset)
if offset >= len(f.dirCache) {
if offset >= len(cached) {
return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Data: nil}
}
end := offset + int(fc.Count)
if end > len(f.dirCache) {
end = len(f.dirCache)
if end > len(cached) {
end = len(cached)
}
return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Data: f.dirCache[offset:end]}
return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Data: cached[offset:end]}
}
func handleWrite(cs *connState, fc *plan9.Fcall, tree *virtfs.Tree) *plan9.Fcall {