Pārlūkot izejas kodu

lib/db: Initialize need meta on first dev occurrence (fixes #6668) (#6669)

Simon Frei 5 gadi atpakaļ
vecāks
revīzija
8f344d0915
2 mainītis faili ar 27 papildinājumiem un 2 dzēšanām
  1. 9 2
      lib/db/meta.go
  2. 18 0
      lib/db/set_test.go

+ 9 - 2
lib/db/meta.go

@@ -118,9 +118,16 @@ func (m *metadataTracker) countsPtr(dev protocol.DeviceID, flag uint32) *Counts
 		idx = len(m.counts.Counts)
 		idx = len(m.counts.Counts)
 		m.counts.Counts = append(m.counts.Counts, Counts{DeviceID: dev[:], LocalFlags: flag})
 		m.counts.Counts = append(m.counts.Counts, Counts{DeviceID: dev[:], LocalFlags: flag})
 		m.indexes[key] = idx
 		m.indexes[key] = idx
-		if flag == needFlag {
+		// Need bucket must be initialized when a device first occurs in
+		// the metadatatracker, even if there's no change to the need
+		// bucket itself.
+		nkey := metaKey{dev, needFlag}
+		nidx, ok := m.indexes[nkey]
+		if !ok {
 			// Initially a new device needs everything, except deletes
 			// Initially a new device needs everything, except deletes
-			m.counts.Counts[idx] = m.allNeededCounts(dev)
+			nidx = len(m.counts.Counts)
+			m.counts.Counts = append(m.counts.Counts, m.allNeededCounts(dev))
+			m.indexes[nkey] = nidx
 		}
 		}
 	}
 	}
 	return &m.counts.Counts[idx]
 	return &m.counts.Counts[idx]

+ 18 - 0
lib/db/set_test.go

@@ -1653,6 +1653,24 @@ func TestUpdateWithOneFileTwice(t *testing.T) {
 	}
 	}
 }
 }
 
 
+// https://github.com/syncthing/syncthing/issues/6668
+func TestNeedRemoteOnly(t *testing.T) {
+	ldb := db.NewLowlevel(backend.OpenMemory())
+	defer ldb.Close()
+
+	s := db.NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeFake, ""), ldb)
+
+	remote0Have := fileList{
+		protocol.FileInfo{Name: "b", Version: protocol.Vector{Counters: []protocol.Counter{{ID: myID, Value: 1001}}}, Blocks: genBlocks(2)},
+	}
+	s.Update(remoteDevice0, remote0Have)
+
+	need := needSize(s, remoteDevice0)
+	if !need.Equal(db.Counts{}) {
+		t.Error("Expected nothing needed, got", need)
+	}
+}
+
 func replace(fs *db.FileSet, device protocol.DeviceID, files []protocol.FileInfo) {
 func replace(fs *db.FileSet, device protocol.DeviceID, files []protocol.FileInfo) {
 	fs.Drop(device)
 	fs.Drop(device)
 	fs.Update(device, files)
 	fs.Update(device, files)