chore(model): the easier linter complaints
This commit is contained in:
@@ -51,7 +51,7 @@ type standardBlockPullReorderer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newStandardBlockPullReorderer(id protocol.DeviceID, otherDevices []protocol.DeviceID) *standardBlockPullReorderer {
|
func newStandardBlockPullReorderer(id protocol.DeviceID, otherDevices []protocol.DeviceID) *standardBlockPullReorderer {
|
||||||
allDevices := append(otherDevices, id)
|
allDevices := append(otherDevices, id) //nolint:gocritic
|
||||||
slices.SortFunc(allDevices, func(a, b protocol.DeviceID) int {
|
slices.SortFunc(allDevices, func(a, b protocol.DeviceID) int {
|
||||||
return a.Compare(b)
|
return a.Compare(b)
|
||||||
})
|
})
|
||||||
@@ -92,7 +92,7 @@ func (p *standardBlockPullReorderer) Reorder(blocks []protocol.BlockInfo) []prot
|
|||||||
// The rest of the chunks we fetch in a random order in whole chunks.
|
// The rest of the chunks we fetch in a random order in whole chunks.
|
||||||
// Generate chunk index slice and shuffle it
|
// Generate chunk index slice and shuffle it
|
||||||
indexes := make([]int, 0, len(chunks)-1)
|
indexes := make([]int, 0, len(chunks)-1)
|
||||||
for i := range len(chunks) {
|
for i := range chunks {
|
||||||
if i != p.myIndex {
|
if i != p.myIndex {
|
||||||
indexes = append(indexes, i)
|
indexes = append(indexes, i)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,17 +56,18 @@ func (p *deviceFolderDownloadState) Update(updates []protocol.FileDownloadProgre
|
|||||||
if update.UpdateType == protocol.FileDownloadProgressUpdateTypeForget && ok && local.version.Equal(update.Version) {
|
if update.UpdateType == protocol.FileDownloadProgressUpdateTypeForget && ok && local.version.Equal(update.Version) {
|
||||||
delete(p.files, update.Name)
|
delete(p.files, update.Name)
|
||||||
} else if update.UpdateType == protocol.FileDownloadProgressUpdateTypeAppend {
|
} else if update.UpdateType == protocol.FileDownloadProgressUpdateTypeAppend {
|
||||||
if !ok {
|
switch {
|
||||||
|
case !ok:
|
||||||
local = deviceFolderFileDownloadState{
|
local = deviceFolderFileDownloadState{
|
||||||
blockIndexes: update.BlockIndexes,
|
blockIndexes: update.BlockIndexes,
|
||||||
version: update.Version,
|
version: update.Version,
|
||||||
blockSize: update.BlockSize,
|
blockSize: update.BlockSize,
|
||||||
}
|
}
|
||||||
} else if !local.version.Equal(update.Version) {
|
case !local.version.Equal(update.Version):
|
||||||
local.blockIndexes = append(local.blockIndexes[:0], update.BlockIndexes...)
|
local.blockIndexes = append(local.blockIndexes[:0], update.BlockIndexes...)
|
||||||
local.version = update.Version
|
local.version = update.Version
|
||||||
local.blockSize = update.BlockSize
|
local.blockSize = update.BlockSize
|
||||||
} else {
|
default:
|
||||||
local.blockIndexes = append(local.blockIndexes, update.BlockIndexes...)
|
local.blockIndexes = append(local.blockIndexes, update.BlockIndexes...)
|
||||||
}
|
}
|
||||||
p.files[update.Name] = local
|
p.files[update.Name] = local
|
||||||
|
|||||||
+4
-4
@@ -52,7 +52,7 @@ type folder struct {
|
|||||||
ignores *ignore.Matcher
|
ignores *ignore.Matcher
|
||||||
mtimefs fs.Filesystem
|
mtimefs fs.Filesystem
|
||||||
modTimeWindow time.Duration
|
modTimeWindow time.Duration
|
||||||
ctx context.Context // used internally, only accessible on serve lifetime
|
ctx context.Context //nolint:containedctx // used internally, only accessible on serve lifetime
|
||||||
done chan struct{} // used externally, accessible regardless of serve
|
done chan struct{} // used externally, accessible regardless of serve
|
||||||
|
|
||||||
scanInterval time.Duration
|
scanInterval time.Duration
|
||||||
@@ -322,7 +322,7 @@ func (f *folder) Reschedule() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Sleep a random time between 3/4 and 5/4 of the configured interval.
|
// Sleep a random time between 3/4 and 5/4 of the configured interval.
|
||||||
sleepNanos := (f.scanInterval.Nanoseconds()*3 + rand.Int63n(2*f.scanInterval.Nanoseconds())) / 4
|
sleepNanos := (f.scanInterval.Nanoseconds()*3 + rand.Int63n(2*f.scanInterval.Nanoseconds())) / 4 //nolint:gosec
|
||||||
interval := time.Duration(sleepNanos) * time.Nanosecond
|
interval := time.Duration(sleepNanos) * time.Nanosecond
|
||||||
l.Debugln(f, "next rescan in", interval)
|
l.Debugln(f, "next rescan in", interval)
|
||||||
f.scanTimer.Reset(interval)
|
f.scanTimer.Reset(interval)
|
||||||
@@ -1111,7 +1111,7 @@ func (f *folder) setWatchError(err error, nextTryIn time.Duration) {
|
|||||||
prevErr := f.watchErr
|
prevErr := f.watchErr
|
||||||
f.watchErr = err
|
f.watchErr = err
|
||||||
f.watchMut.Unlock()
|
f.watchMut.Unlock()
|
||||||
if err != prevErr {
|
if err != prevErr { //nolint:errorlint
|
||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
"folder": f.ID,
|
"folder": f.ID,
|
||||||
}
|
}
|
||||||
@@ -1127,7 +1127,7 @@ func (f *folder) setWatchError(err error, nextTryIn time.Duration) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
msg := fmt.Sprintf("Error while trying to start filesystem watcher for folder %s, trying again in %v: %v", f.Description(), nextTryIn, err)
|
msg := fmt.Sprintf("Error while trying to start filesystem watcher for folder %s, trying again in %v: %v", f.Description(), nextTryIn, err)
|
||||||
if prevErr != err {
|
if prevErr != err { //nolint:errorlint
|
||||||
l.Infof(msg)
|
l.Infof(msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ func newSendOnlyFolder(model *model, ignores *ignore.Matcher, cfg config.FolderC
|
|||||||
f := &sendOnlyFolder{
|
f := &sendOnlyFolder{
|
||||||
folder: newFolder(model, ignores, cfg, evLogger, ioLimiter, nil),
|
folder: newFolder(model, ignores, cfg, evLogger, ioLimiter, nil),
|
||||||
}
|
}
|
||||||
f.folder.puller = f
|
f.puller = f
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ func newSendReceiveFolder(model *model, ignores *ignore.Matcher, cfg config.Fold
|
|||||||
blockPullReorderer: newBlockPullReorderer(cfg.BlockPullOrder, model.id, cfg.DeviceIDs()),
|
blockPullReorderer: newBlockPullReorderer(cfg.BlockPullOrder, model.id, cfg.DeviceIDs()),
|
||||||
writeLimiter: semaphore.New(cfg.MaxConcurrentWrites),
|
writeLimiter: semaphore.New(cfg.MaxConcurrentWrites),
|
||||||
}
|
}
|
||||||
f.folder.puller = f
|
f.puller = f
|
||||||
|
|
||||||
if f.Copiers == 0 {
|
if f.Copiers == 0 {
|
||||||
f.Copiers = defaultCopiers
|
f.Copiers = defaultCopiers
|
||||||
@@ -359,13 +359,14 @@ loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
case file.IsDeleted():
|
case file.IsDeleted():
|
||||||
if file.IsDirectory() {
|
switch {
|
||||||
|
case file.IsDirectory():
|
||||||
// Perform directory deletions at the end, as we may have
|
// Perform directory deletions at the end, as we may have
|
||||||
// files to delete inside them before we get to that point.
|
// files to delete inside them before we get to that point.
|
||||||
dirDeletions = append(dirDeletions, file)
|
dirDeletions = append(dirDeletions, file)
|
||||||
} else if file.IsSymlink() {
|
case file.IsSymlink():
|
||||||
f.deleteFile(file, dbUpdateChan, scanChan)
|
f.deleteFile(file, dbUpdateChan, scanChan)
|
||||||
} else {
|
default:
|
||||||
df, ok, err := f.model.sdb.GetDeviceFile(f.folderID, protocol.LocalDeviceID, file.Name)
|
df, ok, err := f.model.sdb.GetDeviceFile(f.folderID, protocol.LocalDeviceID, file.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return changed, nil, nil, err
|
return changed, nil, nil, err
|
||||||
@@ -1023,7 +1024,7 @@ func (f *sendReceiveFolder) renameFile(cur, source, target protocol.FileInfo, db
|
|||||||
tempName := fs.TempName(target.Name)
|
tempName := fs.TempName(target.Name)
|
||||||
|
|
||||||
if f.versioner != nil {
|
if f.versioner != nil {
|
||||||
err = f.CheckAvailableSpace(uint64(source.Size))
|
err = f.CheckAvailableSpace(uint64(source.Size)) //nolint:gosec
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = osutil.Copy(f.CopyRangeMethod.ToFS(), f.mtimefs, f.mtimefs, source.Name, tempName)
|
err = osutil.Copy(f.CopyRangeMethod.ToFS(), f.mtimefs, f.mtimefs, source.Name, tempName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -1295,7 +1296,7 @@ func (f *sendReceiveFolder) copierRoutine(in <-chan copyBlocksState, pullChan ch
|
|||||||
}
|
}
|
||||||
|
|
||||||
for state := range in {
|
for state := range in {
|
||||||
if err := f.CheckAvailableSpace(uint64(state.file.Size)); err != nil {
|
if err := f.CheckAvailableSpace(uint64(state.file.Size)); err != nil { //nolint:gosec
|
||||||
state.fail(err)
|
state.fail(err)
|
||||||
// Nothing more to do for this failed file, since it would use to much disk space
|
// Nothing more to do for this failed file, since it would use to much disk space
|
||||||
out <- state.sharedPullerState
|
out <- state.sharedPullerState
|
||||||
@@ -1461,7 +1462,7 @@ func (f *sendReceiveFolder) copyBlockFromFile(srcName string, srcOffset int64, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (*sendReceiveFolder) verifyBuffer(buf []byte, block protocol.BlockInfo) error {
|
func (*sendReceiveFolder) verifyBuffer(buf []byte, block protocol.BlockInfo) error {
|
||||||
if len(buf) != int(block.Size) {
|
if len(buf) != block.Size {
|
||||||
return fmt.Errorf("length mismatch %d != %d", len(buf), block.Size)
|
return fmt.Errorf("length mismatch %d != %d", len(buf), block.Size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1489,8 +1490,7 @@ func (f *sendReceiveFolder) pullerRoutine(in <-chan pullBlockState, out chan<- *
|
|||||||
// ongoing at any given time, based on the size of the blocks
|
// ongoing at any given time, based on the size of the blocks
|
||||||
// themselves.
|
// themselves.
|
||||||
|
|
||||||
state := state
|
bytes := state.block.Size
|
||||||
bytes := int(state.block.Size)
|
|
||||||
|
|
||||||
if err := requestLimiter.TakeWithContext(f.ctx, bytes); err != nil {
|
if err := requestLimiter.TakeWithContext(f.ctx, bytes); err != nil {
|
||||||
state.fail(err)
|
state.fail(err)
|
||||||
@@ -1713,7 +1713,7 @@ func (f *sendReceiveFolder) dbUpdaterRoutine(dbUpdateChan <-chan dbUpdateJob) {
|
|||||||
// sync directories
|
// sync directories
|
||||||
for dir := range changedDirs {
|
for dir := range changedDirs {
|
||||||
delete(changedDirs, dir)
|
delete(changedDirs, dir)
|
||||||
if !f.FolderConfiguration.DisableFsync {
|
if !f.DisableFsync {
|
||||||
fd, err := f.mtimefs.Open(dir)
|
fd, err := f.mtimefs.Open(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Debugf("fsync %q failed: %v", dir, err)
|
l.Debugf("fsync %q failed: %v", dir, err)
|
||||||
@@ -1996,7 +1996,7 @@ func (f *sendReceiveFolder) deleteDirOnDiskHandleChildren(dir string, scanChan c
|
|||||||
// Lets just assume the file has changed.
|
// Lets just assume the file has changed.
|
||||||
scanChan <- path
|
scanChan <- path
|
||||||
hasToBeScanned = true
|
hasToBeScanned = true
|
||||||
return nil
|
return nil //nolint:nilerr
|
||||||
}
|
}
|
||||||
if !cf.IsEquivalentOptional(diskFile, protocol.FileInfoComparison{
|
if !cf.IsEquivalentOptional(diskFile, protocol.FileInfoComparison{
|
||||||
ModTimeWindow: f.modTimeWindow,
|
ModTimeWindow: f.modTimeWindow,
|
||||||
@@ -2055,7 +2055,7 @@ func (f *sendReceiveFolder) deleteDirOnDiskHandleChildren(dir string, scanChan c
|
|||||||
// not changed.
|
// not changed.
|
||||||
func (f *sendReceiveFolder) scanIfItemChanged(name string, stat fs.FileInfo, item protocol.FileInfo, hasItem bool, fromDelete bool, scanChan chan<- string) (err error) {
|
func (f *sendReceiveFolder) scanIfItemChanged(name string, stat fs.FileInfo, item protocol.FileInfo, hasItem bool, fromDelete bool, scanChan chan<- string) (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err == errModified {
|
if errors.Is(err, errModified) {
|
||||||
scanChan <- name
|
scanChan <- name
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -125,7 +126,7 @@ func (c *folderSummaryService) Summary(folder string) (*FolderSummary, error) {
|
|||||||
var local, global, need, ro db.Counts
|
var local, global, need, ro db.Counts
|
||||||
var ourSeq int64
|
var ourSeq int64
|
||||||
var remoteSeq map[protocol.DeviceID]int64
|
var remoteSeq map[protocol.DeviceID]int64
|
||||||
errors, err := c.model.FolderErrors(folder)
|
errs, err := c.model.FolderErrors(folder)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
global, _ = c.model.GlobalSize(folder)
|
global, _ = c.model.GlobalSize(folder)
|
||||||
local, _ = c.model.LocalSize(folder, protocol.LocalDeviceID)
|
local, _ = c.model.LocalSize(folder, protocol.LocalDeviceID)
|
||||||
@@ -137,12 +138,12 @@ func (c *folderSummaryService) Summary(folder string) (*FolderSummary, error) {
|
|||||||
// For API backwards compatibility (SyncTrayzor needs it) an empty folder
|
// For API backwards compatibility (SyncTrayzor needs it) an empty folder
|
||||||
// summary is returned for not running folders, an error might actually be
|
// summary is returned for not running folders, an error might actually be
|
||||||
// more appropriate
|
// more appropriate
|
||||||
if err != nil && err != ErrFolderPaused && err != ErrFolderNotRunning {
|
if err != nil && !errors.Is(err, ErrFolderPaused) && !errors.Is(err, ErrFolderNotRunning) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res.Errors = len(errors)
|
res.Errors = len(errs)
|
||||||
res.PullErrors = len(errors) // deprecated
|
res.PullErrors = len(errs) // deprecated
|
||||||
|
|
||||||
res.Invalid = "" // Deprecated, retains external API for now
|
res.Invalid = "" // Deprecated, retains external API for now
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ func newIndexHandler(conn protocol.Connection, downloads *deviceDownloadState, f
|
|||||||
// about us. Lets check to see if we can start sending index
|
// about us. Lets check to see if we can start sending index
|
||||||
// updates directly or need to send the index from start...
|
// updates directly or need to send the index from start...
|
||||||
|
|
||||||
if startInfo.local.IndexID == myIndexID {
|
switch startInfo.local.IndexID {
|
||||||
|
case myIndexID:
|
||||||
// They say they've seen our index ID before, so we can
|
// They say they've seen our index ID before, so we can
|
||||||
// send a delta update only.
|
// send a delta update only.
|
||||||
|
|
||||||
@@ -83,15 +84,17 @@ func newIndexHandler(conn protocol.Connection, downloads *deviceDownloadState, f
|
|||||||
l.Debugf("Device %v folder %s is delta index compatible (mlv=%d)", conn.DeviceID().Short(), folder.Description(), startInfo.local.MaxSequence)
|
l.Debugf("Device %v folder %s is delta index compatible (mlv=%d)", conn.DeviceID().Short(), folder.Description(), startInfo.local.MaxSequence)
|
||||||
startSequence = startInfo.local.MaxSequence
|
startSequence = startInfo.local.MaxSequence
|
||||||
}
|
}
|
||||||
} else if startInfo.local.IndexID != 0 {
|
|
||||||
|
case 0:
|
||||||
|
l.Debugf("Device %v folder %s has no index ID for us", conn.DeviceID().Short(), folder.Description())
|
||||||
|
|
||||||
|
default:
|
||||||
// They say they've seen an index ID from us, but it's
|
// They say they've seen an index ID from us, but it's
|
||||||
// not the right one. Either they are confused or we
|
// not the right one. Either they are confused or we
|
||||||
// must have reset our database since last talking to
|
// must have reset our database since last talking to
|
||||||
// them. We'll start with a full index transfer.
|
// them. We'll start with a full index transfer.
|
||||||
l.Infof("Device %v folder %s has mismatching index ID for us (%v != %v)", conn.DeviceID().Short(), folder.Description(), startInfo.local.IndexID, myIndexID)
|
l.Infof("Device %v folder %s has mismatching index ID for us (%v != %v)", conn.DeviceID().Short(), folder.Description(), startInfo.local.IndexID, myIndexID)
|
||||||
startSequence = 0
|
startSequence = 0
|
||||||
} else {
|
|
||||||
l.Debugf("Device %v folder %s has no index ID for us", conn.DeviceID().Short(), folder.Description())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the other side's description of themselves. We
|
// This is the other side's description of themselves. We
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ var (
|
|||||||
Name: "folder_state",
|
Name: "folder_state",
|
||||||
Help: "Current folder state",
|
Help: "Current folder state",
|
||||||
}, []string{"folder"})
|
}, []string{"folder"})
|
||||||
metricFolderSummary = promauto.NewGaugeVec(prometheus.GaugeOpts{
|
metricFolderSummary = promauto.NewGaugeVec(prometheus.GaugeOpts{ //nolint:promlinter
|
||||||
Namespace: "syncthing",
|
Namespace: "syncthing",
|
||||||
Subsystem: "model",
|
Subsystem: "model",
|
||||||
Name: "folder_summary",
|
Name: "folder_summary",
|
||||||
|
|||||||
+25
-21
@@ -195,7 +195,7 @@ var (
|
|||||||
ErrFolderMissing = errors.New("no such folder")
|
ErrFolderMissing = errors.New("no such folder")
|
||||||
errNoVersioner = errors.New("folder has no versioner")
|
errNoVersioner = errors.New("folder has no versioner")
|
||||||
// errors about why a connection is closed
|
// errors about why a connection is closed
|
||||||
errStopped = errors.New("Syncthing is being stopped")
|
errStopped = errors.New("Syncthing is being stopped") //nolint:staticcheck
|
||||||
errEncryptionInvConfigLocal = errors.New("can't encrypt outgoing data because local data is encrypted (folder-type receive-encrypted)")
|
errEncryptionInvConfigLocal = errors.New("can't encrypt outgoing data because local data is encrypted (folder-type receive-encrypted)")
|
||||||
errEncryptionInvConfigRemote = errors.New("remote has encrypted data and encrypts that data for us - this is impossible")
|
errEncryptionInvConfigRemote = errors.New("remote has encrypted data and encrypts that data for us - this is impossible")
|
||||||
errEncryptionNotEncryptedLocal = errors.New("remote expects to exchange encrypted data, but is configured for plain data")
|
errEncryptionNotEncryptedLocal = errors.New("remote expects to exchange encrypted data, but is configured for plain data")
|
||||||
@@ -622,24 +622,26 @@ func (m *model) UsageReportingStats(report *contract.Report, version int, previe
|
|||||||
|
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
// Allow prefixes to be specified in any order, but only once.
|
// Allow prefixes to be specified in any order, but only once.
|
||||||
|
loop:
|
||||||
for {
|
for {
|
||||||
if strings.HasPrefix(line, "!") && !seenPrefix[0] {
|
switch {
|
||||||
|
case strings.HasPrefix(line, "!") && !seenPrefix[0]:
|
||||||
seenPrefix[0] = true
|
seenPrefix[0] = true
|
||||||
line = line[1:]
|
line = line[1:]
|
||||||
report.IgnoreStats.Inverts++
|
report.IgnoreStats.Inverts++
|
||||||
} else if strings.HasPrefix(line, "(?i)") && !seenPrefix[1] {
|
case strings.HasPrefix(line, "(?i)") && !seenPrefix[1]:
|
||||||
seenPrefix[1] = true
|
seenPrefix[1] = true
|
||||||
line = line[4:]
|
line = line[4:]
|
||||||
report.IgnoreStats.Folded++
|
report.IgnoreStats.Folded++
|
||||||
} else if strings.HasPrefix(line, "(?d)") && !seenPrefix[2] {
|
case strings.HasPrefix(line, "(?d)") && !seenPrefix[2]:
|
||||||
seenPrefix[2] = true
|
seenPrefix[2] = true
|
||||||
line = line[4:]
|
line = line[4:]
|
||||||
report.IgnoreStats.Deletable++
|
report.IgnoreStats.Deletable++
|
||||||
} else {
|
default:
|
||||||
seenPrefix[0] = false
|
seenPrefix[0] = false
|
||||||
seenPrefix[1] = false
|
seenPrefix[1] = false
|
||||||
seenPrefix[2] = false
|
seenPrefix[2] = false
|
||||||
break
|
break loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1227,9 +1229,10 @@ func (m *model) ClusterConfig(conn protocol.Connection, cm *protocol.ClusterConf
|
|||||||
for _, folder := range cm.Folders {
|
for _, folder := range cm.Folders {
|
||||||
info := &clusterConfigDeviceInfo{}
|
info := &clusterConfigDeviceInfo{}
|
||||||
for _, dev := range folder.Devices {
|
for _, dev := range folder.Devices {
|
||||||
if dev.ID == m.id {
|
switch dev.ID {
|
||||||
|
case m.id:
|
||||||
info.local = dev
|
info.local = dev
|
||||||
} else if dev.ID == deviceID {
|
case deviceID:
|
||||||
info.remote = dev
|
info.remote = dev
|
||||||
}
|
}
|
||||||
if info.local.ID != protocol.EmptyDeviceID && info.remote.ID != protocol.EmptyDeviceID {
|
if info.local.ID != protocol.EmptyDeviceID && info.remote.ID != protocol.EmptyDeviceID {
|
||||||
@@ -1451,7 +1454,7 @@ func (m *model) ccHandleFolders(folders []protocol.Folder, deviceCfg config.Devi
|
|||||||
sameError := false
|
sameError := false
|
||||||
m.mut.Lock()
|
m.mut.Lock()
|
||||||
if devs, ok := m.folderEncryptionFailures[folder.ID]; ok {
|
if devs, ok := m.folderEncryptionFailures[folder.ID]; ok {
|
||||||
sameError = devs[deviceID] == err
|
sameError = devs[deviceID] == err //nolint:errorlint
|
||||||
} else {
|
} else {
|
||||||
m.folderEncryptionFailures[folder.ID] = make(map[protocol.DeviceID]error)
|
m.folderEncryptionFailures[folder.ID] = make(map[protocol.DeviceID]error)
|
||||||
}
|
}
|
||||||
@@ -1461,7 +1464,8 @@ func (m *model) ccHandleFolders(folders []protocol.Folder, deviceCfg config.Devi
|
|||||||
if sameError {
|
if sameError {
|
||||||
l.Debugln(msg)
|
l.Debugln(msg)
|
||||||
} else {
|
} else {
|
||||||
if rerr, ok := err.(*redactedError); ok {
|
var rerr *redactedError
|
||||||
|
if errors.As(err, &rerr) {
|
||||||
err = rerr.redacted
|
err = rerr.redacted
|
||||||
}
|
}
|
||||||
m.evLogger.Log(events.Failure, err.Error())
|
m.evLogger.Log(events.Failure, err.Error())
|
||||||
@@ -2015,7 +2019,7 @@ func (m *model) Request(conn protocol.Connection, req *protocol.Request) (out pr
|
|||||||
|
|
||||||
// The requestResponse releases the bytes to the buffer pool and the
|
// The requestResponse releases the bytes to the buffer pool and the
|
||||||
// limiters when its Close method is called.
|
// limiters when its Close method is called.
|
||||||
res := newLimitedRequestResponse(int(req.Size), limiter, m.globalRequestLimiter)
|
res := newLimitedRequestResponse(req.Size, limiter, m.globalRequestLimiter)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
// Close it ourselves if it isn't returned due to an error
|
// Close it ourselves if it isn't returned due to an error
|
||||||
@@ -2061,16 +2065,17 @@ func (m *model) Request(conn protocol.Connection, req *protocol.Request) (out pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
n, err := readOffsetIntoBuf(folderFs, req.Name, req.Offset, res.data)
|
n, err := readOffsetIntoBuf(folderFs, req.Name, req.Offset, res.data)
|
||||||
if fs.IsNotExist(err) {
|
switch {
|
||||||
|
case fs.IsNotExist(err):
|
||||||
l.Debugf("%v REQ(in) file doesn't exist: %s: %q / %q o=%d s=%d", m, deviceID.Short(), req.Folder, req.Name, req.Offset, req.Size)
|
l.Debugf("%v REQ(in) file doesn't exist: %s: %q / %q o=%d s=%d", m, deviceID.Short(), req.Folder, req.Name, req.Offset, req.Size)
|
||||||
return nil, protocol.ErrNoSuchFile
|
return nil, protocol.ErrNoSuchFile
|
||||||
} else if err == io.EOF {
|
case errors.Is(err, io.EOF):
|
||||||
// Read beyond end of file. This might indicate a problem, or it
|
// Read beyond end of file. This might indicate a problem, or it
|
||||||
// might be a short block that gets padded when read for encrypted
|
// might be a short block that gets padded when read for encrypted
|
||||||
// folders. We ignore the error and let the hash validation in the
|
// folders. We ignore the error and let the hash validation in the
|
||||||
// next step take care of it, by only hashing the part we actually
|
// next step take care of it, by only hashing the part we actually
|
||||||
// managed to read.
|
// managed to read.
|
||||||
} else if err != nil {
|
case err != nil:
|
||||||
l.Debugf("%v REQ(in) failed reading file (%v): %s: %q / %q o=%d s=%d", m, err, deviceID.Short(), req.Folder, req.Name, req.Offset, req.Size)
|
l.Debugf("%v REQ(in) failed reading file (%v): %s: %q / %q o=%d s=%d", m, err, deviceID.Short(), req.Folder, req.Name, req.Offset, req.Size)
|
||||||
return nil, protocol.ErrGeneric
|
return nil, protocol.ErrGeneric
|
||||||
}
|
}
|
||||||
@@ -2230,13 +2235,13 @@ func (m *model) SetIgnores(folder string, content []string) error {
|
|||||||
|
|
||||||
func (m *model) setIgnores(cfg config.FolderConfiguration, content []string) error {
|
func (m *model) setIgnores(cfg config.FolderConfiguration, content []string) error {
|
||||||
err := cfg.CheckPath()
|
err := cfg.CheckPath()
|
||||||
if err == config.ErrPathMissing {
|
if errors.Is(err, config.ErrPathMissing) {
|
||||||
if err = cfg.CreateRoot(); err != nil {
|
if err = cfg.CreateRoot(); err != nil {
|
||||||
return fmt.Errorf("failed to create folder root: %w", err)
|
return fmt.Errorf("failed to create folder root: %w", err)
|
||||||
}
|
}
|
||||||
err = cfg.CheckPath()
|
err = cfg.CheckPath()
|
||||||
}
|
}
|
||||||
if err != nil && err != config.ErrMarkerMissing {
|
if err != nil && !errors.Is(err, config.ErrMarkerMissing) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2498,7 +2503,6 @@ func (m *model) ScanFolders() map[string]error {
|
|||||||
wg := sync.NewWaitGroup()
|
wg := sync.NewWaitGroup()
|
||||||
wg.Add(len(folders))
|
wg.Add(len(folders))
|
||||||
for _, folder := range folders {
|
for _, folder := range folders {
|
||||||
folder := folder
|
|
||||||
go func() {
|
go func() {
|
||||||
err := m.ScanFolder(folder)
|
err := m.ScanFolder(folder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -2677,7 +2681,7 @@ func (m *model) WatchError(folder string) error {
|
|||||||
runner, _ := m.folderRunners.Get(folder)
|
runner, _ := m.folderRunners.Get(folder)
|
||||||
m.mut.RUnlock()
|
m.mut.RUnlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil // If the folder isn't running, there's no error to report.
|
return nil //nolint:nilerr // If the folder isn't running, there's no error to report.
|
||||||
}
|
}
|
||||||
return runner.WatchError()
|
return runner.WatchError()
|
||||||
}
|
}
|
||||||
@@ -2744,7 +2748,7 @@ func (m *model) GlobalDirectoryTree(folder, prefix string, levels int, dirsOnly
|
|||||||
prefix = osutil.NativeFilename(prefix)
|
prefix = osutil.NativeFilename(prefix)
|
||||||
|
|
||||||
if prefix != "" && !strings.HasSuffix(prefix, sep) {
|
if prefix != "" && !strings.HasSuffix(prefix, sep) {
|
||||||
prefix = prefix + sep
|
prefix += sep
|
||||||
}
|
}
|
||||||
|
|
||||||
for f, err := range itererr.Zip(m.sdb.AllGlobalFilesPrefix(folder, prefix)) {
|
for f, err := range itererr.Zip(m.sdb.AllGlobalFilesPrefix(folder, prefix)) {
|
||||||
@@ -3456,8 +3460,8 @@ type updatedPendingFolder struct {
|
|||||||
// redactPathError checks if the error is actually a os.PathError, and if yes
|
// redactPathError checks if the error is actually a os.PathError, and if yes
|
||||||
// returns a redactedError with the path removed.
|
// returns a redactedError with the path removed.
|
||||||
func redactPathError(err error) (error, bool) {
|
func redactPathError(err error) (error, bool) {
|
||||||
perr, ok := err.(*os.PathError)
|
var perr *os.PathError
|
||||||
if !ok {
|
if !errors.As(err, &perr) {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
return &redactedError{
|
return &redactedError{
|
||||||
|
|||||||
@@ -384,7 +384,7 @@ func writeEncryptionTrailer(file protocol.FileInfo, writer io.WriterAt) (int64,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
binary.BigEndian.PutUint32(bs[n:], uint32(n))
|
binary.BigEndian.PutUint32(bs[n:], uint32(n)) //nolint:gosec
|
||||||
bs = bs[:n+4]
|
bs = bs[:n+4]
|
||||||
|
|
||||||
if _, err := writer.WriteAt(bs, wireFile.Size); err != nil {
|
if _, err := writer.WriteAt(bs, wireFile.Size); err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user