Complete olliesrv fid synchronization
This commit is contained in:
parent
cad1c6be9b
commit
a8a6bb5204
|
|
@ -562,7 +562,9 @@ func read(root *fs.Tree, cs *connState, fc *plan9.Fcall, ctx context.Context) *p
|
|||
f, fidOK := cs.fids[fc.Fid]
|
||||
var base string
|
||||
if fidOK {
|
||||
f.mu.Lock()
|
||||
base = f.waitBase
|
||||
f.mu.Unlock()
|
||||
}
|
||||
cs.mu.RUnlock()
|
||||
waitCtx, waitCancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
|
|
@ -595,7 +597,9 @@ func read(root *fs.Tree, cs *connState, fc *plan9.Fcall, ctx context.Context) *p
|
|||
f, fidOK := cs.fids[fc.Fid]
|
||||
var base string
|
||||
if fidOK {
|
||||
f.mu.Lock()
|
||||
base = f.waitBase
|
||||
f.mu.Unlock()
|
||||
}
|
||||
cs.mu.RUnlock()
|
||||
waitCtx, waitCancel := context.WithCancel(ctx)
|
||||
|
|
@ -683,24 +687,28 @@ func write(cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
|||
cs.mu.Unlock()
|
||||
return errFcall(fc, "bad fid")
|
||||
}
|
||||
|
||||
if f.entry != nil && f.entry.RdwrMode() {
|
||||
f.readCache = nil // clear cached response for next read
|
||||
cs.mu.Unlock()
|
||||
if err := f.entry.Write(fc.Data); err != nil {
|
||||
return errFcall(fc, err.Error())
|
||||
f.mu.Lock()
|
||||
entry := f.entry
|
||||
if entry != nil && entry.RdwrMode() {
|
||||
f.readCache = nil
|
||||
}
|
||||
if entry == nil || !entry.RdwrMode() {
|
||||
end := int(fc.Offset) + len(fc.Data)
|
||||
if end > len(f.writeBuf) {
|
||||
grown := make([]byte, end)
|
||||
copy(grown, f.writeBuf)
|
||||
f.writeBuf = grown
|
||||
}
|
||||
copy(f.writeBuf[fc.Offset:], fc.Data)
|
||||
f.mu.Unlock()
|
||||
cs.mu.Unlock()
|
||||
return &plan9.Fcall{Type: plan9.Rwrite, Tag: fc.Tag, Count: uint32(len(fc.Data))}
|
||||
}
|
||||
|
||||
end := int(fc.Offset) + len(fc.Data)
|
||||
if end > len(f.writeBuf) {
|
||||
grown := make([]byte, end)
|
||||
copy(grown, f.writeBuf)
|
||||
f.writeBuf = grown
|
||||
}
|
||||
copy(f.writeBuf[fc.Offset:], fc.Data)
|
||||
f.mu.Unlock()
|
||||
cs.mu.Unlock()
|
||||
if err := entry.Write(fc.Data); err != nil {
|
||||
return errFcall(fc, err.Error())
|
||||
}
|
||||
return &plan9.Fcall{Type: plan9.Rwrite, Tag: fc.Tag, Count: uint32(len(fc.Data))}
|
||||
}
|
||||
|
||||
|
|
@ -711,13 +719,16 @@ func stat(root *fs.Tree, cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
|||
if !ok {
|
||||
return errFcall(fc, "bad fid")
|
||||
}
|
||||
if _, err := root.Stat(f.path[1:]); err != nil {
|
||||
f.mu.Lock()
|
||||
path := f.path
|
||||
f.mu.Unlock()
|
||||
if _, err := root.Stat(path[1:]); err != nil {
|
||||
cs.mu.Lock()
|
||||
delete(cs.fids, fc.Fid)
|
||||
cs.mu.Unlock()
|
||||
return errFcall(fc, "file not found")
|
||||
}
|
||||
dir := makeStat(root, f.path)
|
||||
dir := makeStat(root, path)
|
||||
stat, err := dir.Bytes()
|
||||
if err != nil {
|
||||
return errFcall(fc, err.Error())
|
||||
|
|
@ -736,22 +747,29 @@ func wstat(root *fs.Tree, cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
|||
if err != nil {
|
||||
return &plan9.Fcall{Type: plan9.Rwstat, Tag: fc.Tag}
|
||||
}
|
||||
oldName := pathBase(f.path)
|
||||
f.mu.Lock()
|
||||
path := f.path
|
||||
f.mu.Unlock()
|
||||
oldName := pathBase(path)
|
||||
if newDir.Name == "" || newDir.Name == oldName {
|
||||
return &plan9.Fcall{Type: plan9.Rwstat, Tag: fc.Tag}
|
||||
}
|
||||
if err := root.Rename(f.path[1:], newDir.Name); err != nil {
|
||||
if err := root.Rename(path[1:], newDir.Name); err != nil {
|
||||
return errFcall(fc, err.Error())
|
||||
}
|
||||
// GC stale fids on this connection referencing the old path
|
||||
oldPrefix := f.path
|
||||
oldPrefix := path
|
||||
var stale []fs.File
|
||||
cs.mu.Lock()
|
||||
for id, fid := range cs.fids {
|
||||
if fid.path == oldPrefix || strings.HasPrefix(fid.path, oldPrefix+"/") {
|
||||
fid.mu.Lock()
|
||||
fidPath := fid.path
|
||||
entry := fid.entry
|
||||
fid.mu.Unlock()
|
||||
if fidPath == oldPrefix || strings.HasPrefix(fidPath, oldPrefix+"/") {
|
||||
delete(cs.fids, id)
|
||||
if fid.entry != nil {
|
||||
stale = append(stale, fid.entry)
|
||||
if entry != nil {
|
||||
stale = append(stale, entry)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -770,20 +788,28 @@ func clunk(root *fs.Tree, cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
|||
var writable bool
|
||||
var isRequest bool
|
||||
if ok {
|
||||
if m := f.mode & 3; m == plan9.OWRITE || m == plan9.ORDWR {
|
||||
path = f.path
|
||||
f.mu.Lock()
|
||||
mode := f.mode
|
||||
path = f.path
|
||||
data = append([]byte(nil), f.writeBuf...)
|
||||
entry := f.entry
|
||||
if mode&3 == plan9.OWRITE || mode&3 == plan9.ORDWR {
|
||||
writable = true
|
||||
data = make([]byte, len(f.writeBuf))
|
||||
copy(data, f.writeBuf)
|
||||
if f.entry != nil {
|
||||
isRequest = f.entry.RdwrMode()
|
||||
if entry != nil {
|
||||
isRequest = entry.RdwrMode()
|
||||
}
|
||||
}
|
||||
f.mu.Unlock()
|
||||
delete(cs.fids, fc.Fid)
|
||||
}
|
||||
cs.mu.Unlock()
|
||||
if f != nil && f.entry != nil {
|
||||
_ = f.entry.Close()
|
||||
if f != nil {
|
||||
f.mu.Lock()
|
||||
entry := f.entry
|
||||
f.mu.Unlock()
|
||||
if entry != nil {
|
||||
_ = entry.Close()
|
||||
}
|
||||
}
|
||||
if writable && !isRequest {
|
||||
input := strings.TrimSpace(string(data))
|
||||
|
|
@ -805,16 +831,21 @@ func remove(root *fs.Tree, cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
|||
delete(cs.fids, fc.Fid)
|
||||
}
|
||||
cs.mu.Unlock()
|
||||
if ok && f.entry != nil {
|
||||
_ = f.entry.Close()
|
||||
var entry fs.File
|
||||
if ok {
|
||||
f.mu.Lock()
|
||||
entry = f.entry
|
||||
path := f.path
|
||||
f.mu.Unlock()
|
||||
if entry != nil {
|
||||
_ = entry.Close()
|
||||
}
|
||||
if err := root.Delete(path[1:]); err != nil {
|
||||
return errFcall(fc, err.Error())
|
||||
}
|
||||
return &plan9.Fcall{Type: plan9.Rremove, Tag: fc.Tag}
|
||||
}
|
||||
if !ok {
|
||||
return errFcall(fc, "bad fid")
|
||||
}
|
||||
if err := root.Delete(f.path[1:]); err != nil {
|
||||
return errFcall(fc, err.Error())
|
||||
}
|
||||
return &plan9.Fcall{Type: plan9.Rremove, Tag: fc.Tag}
|
||||
return errFcall(fc, "bad fid")
|
||||
}
|
||||
|
||||
func (s *Server) Kill() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue