Synchronize toolsrv fid state
This commit is contained in:
parent
c111cbd0ca
commit
6c476f4fb8
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in New Issue