浏览代码

lib/db: Remove emptied global list in checkGlobals (fixes #6425) (#6426)

Simon Frei 5 年之前
父节点
当前提交
40580d8b9b
共有 4 个文件被更改,包括 43 次插入7 次删除
  1. 37 0
      lib/db/db_test.go
  2. 5 1
      lib/db/lowlevel.go
  3. 1 2
      lib/db/structs.go
  4. 0 4
      lib/db/transactions.go

+ 37 - 0
lib/db/db_test.go

@@ -440,3 +440,40 @@ func TestDowngrade(t *testing.T) {
 		t.Fatalf("Error has %v as min Syncthing version, expected %v", err.minSyncthingVersion, dbMinSyncthingVersion)
 	}
 }
+
+func TestCheckGlobals(t *testing.T) {
+	db := NewLowlevel(backend.OpenMemory())
+	defer db.Close()
+
+	fs := NewFileSet("test", fs.NewFilesystem(fs.FilesystemTypeFake, ""), db)
+
+	// Add any file
+	name := "foo"
+	fs.Update(protocol.LocalDeviceID, []protocol.FileInfo{
+		{
+			Name:    name,
+			Type:    protocol.FileInfoTypeFile,
+			Version: protocol.Vector{Counters: []protocol.Counter{{ID: 1, Value: 1001}}},
+		},
+	})
+
+	// Remove just the file entry
+	if err := db.dropPrefix([]byte{KeyTypeDevice}); err != nil {
+		t.Fatal(err)
+	}
+
+	// Clean up global entry of the now missing file
+	if err := db.checkGlobals([]byte(fs.folder), fs.meta); err != nil {
+		t.Fatal(err)
+	}
+
+	// Check that the global entry is gone
+	gk, err := db.keyer.GenerateGlobalVersionKey(nil, []byte(fs.folder), []byte(name))
+	if err != nil {
+		t.Fatal(err)
+	}
+	_, err = db.Get(gk)
+	if !backend.IsNotFound(err) {
+		t.Error("Expected key missing error, got", err)
+	}
+}

+ 5 - 1
lib/db/lowlevel.go

@@ -417,7 +417,11 @@ func (db *Lowlevel) checkGlobals(folder []byte, meta *metadataTracker) error {
 			}
 		}
 
-		if len(newVL.Versions) != len(vl.Versions) {
+		if newLen := len(newVL.Versions); newLen == 0 {
+			if err := t.Delete(dbi.Key()); err != nil {
+				return err
+			}
+		} else if newLen != len(vl.Versions) {
 			if err := t.Put(dbi.Key(), mustMarshal(&newVL)); err != nil {
 				return err
 			}

+ 1 - 2
lib/db/structs.go

@@ -257,14 +257,13 @@ func (vl VersionList) insertAt(i int, v FileVersion) VersionList {
 // as the removed FileVersion and the position, where that FileVersion was.
 // If there is no FileVersion for the given device, the position is -1.
 func (vl VersionList) pop(device []byte) (VersionList, FileVersion, int) {
-	removedAt := -1
 	for i, v := range vl.Versions {
 		if bytes.Equal(v.Device, device) {
 			vl.Versions = append(vl.Versions[:i], vl.Versions[i+1:]...)
 			return vl, v, i
 		}
 	}
-	return vl, FileVersion{}, removedAt
+	return vl, FileVersion{}, -1
 }
 
 func (vl VersionList) Get(device []byte) (FileVersion, bool) {

+ 0 - 4
lib/db/transactions.go

@@ -485,10 +485,6 @@ func (t readWriteTransaction) updateGlobal(gk, keyBuf, folder, device []byte, fi
 	if err != nil {
 		return nil, false, err
 	}
-	if insertedAt == -1 {
-		l.Debugln("update global; same version, global unchanged")
-		return keyBuf, false, nil
-	}
 
 	name := []byte(file.Name)