github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libfuse/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  //go:build !windows
     6  // +build !windows
     7  
     8  package libfuse
     9  
    10  import (
    11  	"errors"
    12  
    13  	"bazil.org/fuse"
    14  	"bazil.org/fuse/fs"
    15  	"github.com/keybase/client/go/kbfs/libcontext"
    16  	"github.com/keybase/client/go/kbfs/libkbfs"
    17  	"golang.org/x/net/context"
    18  )
    19  
    20  // UpdatesFile represents a write-only file where any write of at
    21  // least one byte triggers either disabling remote folder updates and
    22  // conflict resolution, or re-enabling both.  It is mainly useful for
    23  // testing.
    24  type UpdatesFile struct {
    25  	folder *Folder
    26  	enable bool
    27  }
    28  
    29  var _ fs.Node = (*UpdatesFile)(nil)
    30  
    31  // Attr implements the fs.Node interface for UpdatesFile.
    32  func (f *UpdatesFile) Attr(ctx context.Context, a *fuse.Attr) error {
    33  	a.Size = 0
    34  	a.Mode = 0222
    35  	return nil
    36  }
    37  
    38  var _ fs.Handle = (*UpdatesFile)(nil)
    39  
    40  var _ fs.HandleWriter = (*UpdatesFile)(nil)
    41  
    42  // Write implements the fs.HandleWriter interface for UpdatesFile.
    43  func (f *UpdatesFile) Write(ctx context.Context, req *fuse.WriteRequest,
    44  	resp *fuse.WriteResponse) (err error) {
    45  	f.folder.fs.log.CDebugf(ctx, "UpdatesFile (enable: %t) Write", f.enable)
    46  	defer func() { err = f.folder.processError(ctx, libkbfs.WriteMode, err) }()
    47  	if len(req.Data) == 0 {
    48  		return nil
    49  	}
    50  
    51  	f.folder.updateMu.Lock()
    52  	defer f.folder.updateMu.Unlock()
    53  	if f.enable {
    54  		if f.folder.updateChan == nil {
    55  			return errors.New("Updates are already enabled")
    56  		}
    57  		err = libkbfs.RestartCRForTesting(
    58  			libcontext.BackgroundContextWithCancellationDelayer(),
    59  			f.folder.fs.config, f.folder.getFolderBranch())
    60  		if err != nil {
    61  			return err
    62  		}
    63  		f.folder.updateChan <- struct{}{}
    64  		close(f.folder.updateChan)
    65  		f.folder.updateChan = nil
    66  	} else {
    67  		if f.folder.updateChan != nil {
    68  			return errors.New("Updates are already disabled")
    69  		}
    70  		f.folder.updateChan, err =
    71  			libkbfs.DisableUpdatesForTesting(f.folder.fs.config,
    72  				f.folder.getFolderBranch())
    73  		if err != nil {
    74  			return err
    75  		}
    76  		err = libkbfs.DisableCRForTesting(f.folder.fs.config,
    77  			f.folder.getFolderBranch())
    78  		if err != nil {
    79  			return err
    80  		}
    81  	}
    82  
    83  	resp.Size = len(req.Data)
    84  	return nil
    85  }