github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libdokan/updates_file.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package libdokan 6 7 import ( 8 "errors" 9 10 "github.com/keybase/client/go/kbfs/dokan" 11 "github.com/keybase/client/go/kbfs/libcontext" 12 "github.com/keybase/client/go/kbfs/libkbfs" 13 "golang.org/x/net/context" 14 ) 15 16 // UpdatesFile represents a write-only file where any write of at 17 // least one byte triggers either disabling remote folder updates and 18 // conflict resolution, or re-enabling both. It is mainly useful for 19 // testing. 20 type UpdatesFile struct { 21 folder *Folder 22 enable bool 23 specialWriteFile 24 } 25 26 // WriteFile performs writes for dokan. 27 func (f *UpdatesFile) WriteFile(ctx context.Context, fi *dokan.FileInfo, bs []byte, offset int64) (n int, err error) { 28 f.folder.fs.logEnter(ctx, "UpdatesFile WriteFile") 29 defer func() { f.folder.fs.reportErr(ctx, libkbfs.WriteMode, err) }() 30 f.folder.fs.log.CDebugf(ctx, "UpdatesFile (enable: %t) Write", f.enable) 31 if len(bs) == 0 { 32 return 0, nil 33 } 34 35 f.folder.updateMu.Lock() 36 defer f.folder.updateMu.Unlock() 37 if f.enable { 38 if f.folder.updateChan == nil { 39 return 0, errors.New("Updates are already enabled") 40 } 41 err = libkbfs.RestartCRForTesting( 42 libcontext.BackgroundContextWithCancellationDelayer(), 43 f.folder.fs.config, f.folder.getFolderBranch()) 44 if err != nil { 45 return 0, err 46 } 47 f.folder.updateChan <- struct{}{} 48 close(f.folder.updateChan) 49 f.folder.updateChan = nil 50 } else { 51 if f.folder.updateChan != nil { 52 return 0, errors.New("Updates are already disabled") 53 } 54 f.folder.updateChan, err = 55 libkbfs.DisableUpdatesForTesting(f.folder.fs.config, 56 f.folder.getFolderBranch()) 57 if err != nil { 58 return 0, err 59 } 60 err = libkbfs.DisableCRForTesting(f.folder.fs.config, 61 f.folder.getFolderBranch()) 62 if err != nil { 63 return 0, err 64 } 65 } 66 // Because we store state in the folder it must not be forgotten 67 // even if it appears empty and unused. 68 f.folder.noForget = true 69 70 return len(bs), err 71 }