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  }