lib/db: Report number of repaired items from checkGlobal (#7329)

This commit is contained in:
Simon Frei 2021-02-04 14:42:46 +01:00 committed by GitHub
parent ade8d79d42
commit 070bf3b776
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 14 deletions

View File

@ -513,8 +513,10 @@ func TestCheckGlobals(t *testing.T) {
}
// Clean up global entry of the now missing file
if err := db.checkGlobals([]byte(fs.folder)); err != nil {
if repaired, err := db.checkGlobals([]byte(fs.folder)); err != nil {
t.Fatal(err)
} else if repaired != 1 {
t.Error("Expected 1 repaired global item, got", repaired)
}
// Check that the global entry is gone

View File

@ -441,30 +441,31 @@ func (db *Lowlevel) dropDeviceFolder(device, folder []byte, meta *metadataTracke
return t.Commit()
}
func (db *Lowlevel) checkGlobals(folder []byte) error {
func (db *Lowlevel) checkGlobals(folder []byte) (int, error) {
t, err := db.newReadWriteTransaction()
if err != nil {
return err
return 0, err
}
defer t.close()
key, err := db.keyer.GenerateGlobalVersionKey(nil, folder, nil)
if err != nil {
return err
return 0, err
}
dbi, err := t.NewPrefixIterator(key.WithoutName())
if err != nil {
return err
return 0, err
}
defer dbi.Release()
fixed := 0
var dk []byte
ro := t.readOnlyTransaction
for dbi.Next() {
var vl VersionList
if err := vl.Unmarshal(dbi.Value()); err != nil || vl.Empty() {
if err := t.Delete(dbi.Key()); err != nil && !backend.IsNotFound(err) {
return err
return 0, err
}
continue
}
@ -480,34 +481,36 @@ func (db *Lowlevel) checkGlobals(folder []byte) error {
for _, fv := range vl.RawVersions {
changedHere, err = checkGlobalsFilterDevices(dk, folder, name, fv.Devices, newVL, ro)
if err != nil {
return err
return 0, err
}
changed = changed || changedHere
changedHere, err = checkGlobalsFilterDevices(dk, folder, name, fv.InvalidDevices, newVL, ro)
if err != nil {
return err
return 0, err
}
changed = changed || changedHere
}
if newVL.Empty() {
if err := t.Delete(dbi.Key()); err != nil && !backend.IsNotFound(err) {
return err
return 0, err
}
fixed++
} else if changed {
if err := t.Put(dbi.Key(), mustMarshal(newVL)); err != nil {
return err
return 0, err
}
fixed++
}
}
dbi.Release()
if err := dbi.Error(); err != nil {
return err
return 0, err
}
l.Debugf("db check completed for %q", folder)
return t.Commit()
l.Debugf("global db check completed for %q", folder)
return fixed, t.Commit()
}
func checkGlobalsFilterDevices(dk, folder, name []byte, devices [][]byte, vl *VersionList, t readOnlyTransaction) (bool, error) {
@ -899,8 +902,10 @@ func (db *Lowlevel) recalcMeta(folderStr string) (*metadataTracker, error) {
folder := []byte(folderStr)
meta := newMetadataTracker(db.keyer, db.evLogger)
if err := db.checkGlobals(folder); err != nil {
if fixed, err := db.checkGlobals(folder); err != nil {
return nil, fmt.Errorf("checking globals: %w", err)
} else if fixed > 0 {
l.Infof("Repaired %d global entries for folder %v in database", fixed, folderStr)
}
t, err := db.newReadWriteTransaction(meta.CommitHook(folder))