Synchronize olliesrv fid read state
This commit is contained in:
parent
6c476f4fb8
commit
cad1c6be9b
|
|
@ -55,6 +55,7 @@ func (g *GroupTable) IsMember(group, user string) bool {
|
|||
}
|
||||
|
||||
type fid struct {
|
||||
mu sync.Mutex
|
||||
path string
|
||||
qid plan9.Qid
|
||||
mode uint8
|
||||
|
|
@ -517,16 +518,27 @@ func read(root *fs.Tree, cs *connState, fc *plan9.Fcall, ctx context.Context) *p
|
|||
cs.mu.RUnlock()
|
||||
return errFcall(fc, "bad fid")
|
||||
}
|
||||
f.mu.Lock()
|
||||
path := f.path
|
||||
isDir := f.qid.Type&QTDir != 0
|
||||
entry := f.entry
|
||||
f.mu.Unlock()
|
||||
cs.mu.RUnlock()
|
||||
|
||||
if isDir {
|
||||
f.mu.Lock()
|
||||
cached := f.dirCache
|
||||
f.mu.Unlock()
|
||||
if fc.Offset == 0 || cached == nil {
|
||||
cached = buildDirData(root, path)
|
||||
f.mu.Lock()
|
||||
if fc.Offset == 0 || f.dirCache == nil {
|
||||
f.dirCache = buildDirData(root, path)
|
||||
f.dirCache = cached
|
||||
}
|
||||
data := sliceDirData(f.dirCache, fc.Offset, fc.Count)
|
||||
cached = f.dirCache
|
||||
f.mu.Unlock()
|
||||
}
|
||||
data := sliceDirData(cached, fc.Offset, fc.Count)
|
||||
return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Count: uint32(len(data)), Data: data}
|
||||
}
|
||||
|
||||
|
|
@ -536,11 +548,14 @@ func read(root *fs.Tree, cs *connState, fc *plan9.Fcall, ctx context.Context) *p
|
|||
|
||||
if entry.BlockingReadMode() {
|
||||
// Serve from cache if we already have content (multi-Tread paging).
|
||||
if f.readCache != nil {
|
||||
if int(fc.Offset) >= len(f.readCache) {
|
||||
f.mu.Lock()
|
||||
cached := f.readCache
|
||||
f.mu.Unlock()
|
||||
if cached != nil {
|
||||
if int(fc.Offset) >= len(cached) {
|
||||
return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Count: 0}
|
||||
}
|
||||
return readSlice(fc, f.readCache)
|
||||
return readSlice(fc, cached)
|
||||
}
|
||||
// First Tread: block for content.
|
||||
cs.mu.RLock()
|
||||
|
|
@ -563,11 +578,15 @@ func read(root *fs.Tree, cs *connState, fc *plan9.Fcall, ctx context.Context) *p
|
|||
if nextBase != "" {
|
||||
cs.mu.Lock()
|
||||
if f, ok := cs.fids[fc.Fid]; ok {
|
||||
f.mu.Lock()
|
||||
f.waitBase = nextBase
|
||||
f.mu.Unlock()
|
||||
}
|
||||
cs.mu.Unlock()
|
||||
}
|
||||
f.mu.Lock()
|
||||
f.readCache = content
|
||||
f.mu.Unlock()
|
||||
return readSlice(fc, content)
|
||||
}
|
||||
|
||||
|
|
@ -588,7 +607,9 @@ func read(root *fs.Tree, cs *connState, fc *plan9.Fcall, ctx context.Context) *p
|
|||
if nextBase != "" {
|
||||
cs.mu.Lock()
|
||||
if f, ok := cs.fids[fc.Fid]; ok {
|
||||
f.mu.Lock()
|
||||
f.waitBase = nextBase
|
||||
f.mu.Unlock()
|
||||
}
|
||||
cs.mu.Unlock()
|
||||
}
|
||||
|
|
@ -599,11 +620,17 @@ func read(root *fs.Tree, cs *connState, fc *plan9.Fcall, ctx context.Context) *p
|
|||
return &plan9.Fcall{Type: plan9.Rread, Tag: fc.Tag, Count: uint32(count), Data: content[:count]}
|
||||
}
|
||||
|
||||
// Normal file read: cache content on first Tread, serve via readSlice.
|
||||
// This handles the case where io.ReadAll issues multiple Treads at
|
||||
// increasing offsets (buffer starts at 512 bytes and grows).
|
||||
if f.readCache != nil {
|
||||
return readSlice(fc, f.readCache)
|
||||
cs.mu.RLock()
|
||||
f, ok = cs.fids[fc.Fid]
|
||||
cs.mu.RUnlock()
|
||||
if !ok {
|
||||
return errFcall(fc, "bad fid")
|
||||
}
|
||||
f.mu.Lock()
|
||||
cached := f.readCache
|
||||
f.mu.Unlock()
|
||||
if cached != nil {
|
||||
return readSlice(fc, cached)
|
||||
}
|
||||
|
||||
type result struct {
|
||||
|
|
@ -622,8 +649,11 @@ func read(root *fs.Tree, cs *connState, fc *plan9.Fcall, ctx context.Context) *p
|
|||
if r.err != nil {
|
||||
return errFcall(fc, r.err.Error())
|
||||
}
|
||||
f.mu.Lock()
|
||||
f.readCache = r.data
|
||||
return readSlice(fc, r.data)
|
||||
cached := f.readCache
|
||||
f.mu.Unlock()
|
||||
return readSlice(fc, cached)
|
||||
case <-ctx.Done():
|
||||
entry.Close()
|
||||
return errFcall(fc, ctx.Err().Error())
|
||||
|
|
|
|||
Loading…
Reference in New Issue