diff --git a/lib/db/set_test.go b/lib/db/set_test.go index ec0ef91cd..05fc4d1f9 100644 --- a/lib/db/set_test.go +++ b/lib/db/set_test.go @@ -1707,6 +1707,38 @@ func TestNeedRemoteAfterReset(t *testing.T) { } } +// https://github.com/syncthing/syncthing/issues/6850 +func TestIgnoreLocalChanged(t *testing.T) { + ldb := db.NewLowlevel(backend.OpenMemory()) + defer ldb.Close() + + s := db.NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeFake, ""), ldb) + + // Add locally changed file + files := fileList{ + protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1001}}}, Blocks: genBlocks(2), LocalFlags: protocol.FlagLocalReceiveOnly}, + } + s.Update(protocol.LocalDeviceID, files) + + if c := globalSize(s).Files; c != 1 { + t.Error("Expected one global file, got", c) + } + if c := localSize(s).Files; c != 1 { + t.Error("Expected one local file, got", c) + } + + // Change file to ignored + files[0].LocalFlags = protocol.FlagLocalIgnored + s.Update(protocol.LocalDeviceID, files) + + if c := globalSize(s).Files; c != 0 { + t.Error("Expected no global file, got", c) + } + if c := localSize(s).Files; c != 0 { + t.Error("Expected no local file, got", c) + } +} + func replace(fs *db.FileSet, device protocol.DeviceID, files []protocol.FileInfo) { fs.Drop(device) fs.Update(device, files) diff --git a/lib/db/transactions.go b/lib/db/transactions.go index 43f652875..05ce2fa34 100644 --- a/lib/db/transactions.go +++ b/lib/db/transactions.go @@ -662,13 +662,11 @@ func (t readWriteTransaction) updateGlobal(gk, keyBuf, folder, device []byte, fi } } - // Update global size counter if necessary - - if !globalChanged { - // Neither the global state nor the needs of any devices, except - // the one updated, changed. - return keyBuf, true, nil - } + // Update global size counter. + // It's done regardless of if the global changed, as two files might + // both be invalid, but for different reasons i.e. have different flags + // (e.g. ignored vs receive only). + // https://github.com/syncthing/syncthing/issues/6850 // Remove the old global from the global size counter if haveOldGlobal { @@ -691,6 +689,12 @@ func (t readWriteTransaction) updateGlobal(gk, keyBuf, folder, device []byte, fi } meta.addFile(protocol.GlobalDeviceID, global) + if !globalChanged { + // Neither the global state nor the needs of any devices, except + // the one updated, changed. + return keyBuf, true, nil + } + // check for local (if not already done before) if !bytes.Equal(device, protocol.LocalDeviceID[:]) { localFV, haveLocal := fl.Get(protocol.LocalDeviceID[:])