This commit is contained in:
+46
-8
@@ -441,13 +441,14 @@ func (db *Lowlevel) dropDeviceFolder(device, folder []byte, meta *metadataTracke
|
||||
return t.Commit()
|
||||
}
|
||||
|
||||
func (db *Lowlevel) checkGlobals(folder []byte) (int, error) {
|
||||
func (db *Lowlevel) checkGlobals(folderStr string) (int, error) {
|
||||
t, err := db.newReadWriteTransaction()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer t.close()
|
||||
|
||||
folder := []byte(folderStr)
|
||||
key, err := db.keyer.GenerateGlobalVersionKey(nil, folder, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -509,7 +510,7 @@ func (db *Lowlevel) checkGlobals(folder []byte) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
l.Debugf("global db check completed for %q", folder)
|
||||
l.Debugf("global db check completed for %v", folder)
|
||||
return fixed, t.Commit()
|
||||
}
|
||||
|
||||
@@ -834,8 +835,10 @@ func (b *bloomFilter) hash(id []byte) uint64 {
|
||||
|
||||
// checkRepair checks folder metadata and sequences for miscellaneous errors.
|
||||
func (db *Lowlevel) checkRepair() error {
|
||||
db.gcMut.RLock()
|
||||
defer db.gcMut.RUnlock()
|
||||
for _, folder := range db.ListFolders() {
|
||||
if _, err := db.getMetaAndCheck(folder); err != nil {
|
||||
if _, err := db.getMetaAndCheckGCLocked(folder); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -858,6 +861,14 @@ func (db *Lowlevel) getMetaAndCheckGCLocked(folder string) (*metadataTracker, er
|
||||
l.Infof("Repaired %d local need entries for folder %v in database", fixed, folder)
|
||||
}
|
||||
|
||||
fixed, err = db.checkGlobals(folder)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("checking globals: %w", err)
|
||||
}
|
||||
if fixed != 0 {
|
||||
l.Infof("Repaired %d global entries for folder %v in database", fixed, folder)
|
||||
}
|
||||
|
||||
meta, err := db.recalcMeta(folder)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("recalculating metadata: %w", err)
|
||||
@@ -869,6 +880,10 @@ func (db *Lowlevel) getMetaAndCheckGCLocked(folder string) (*metadataTracker, er
|
||||
}
|
||||
if fixed != 0 {
|
||||
l.Infof("Repaired %d sequence entries for folder %v in database", fixed, folder)
|
||||
meta, err = db.recalcMeta(folder)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("recalculating metadata: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return meta, nil
|
||||
@@ -906,11 +921,6 @@ func (db *Lowlevel) recalcMeta(folderStr string) (*metadataTracker, error) {
|
||||
folder := []byte(folderStr)
|
||||
|
||||
meta := newMetadataTracker(db.keyer, db.evLogger)
|
||||
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))
|
||||
if err != nil {
|
||||
@@ -1022,6 +1032,34 @@ func (db *Lowlevel) repairSequenceGCLocked(folderStr string, meta *metadataTrack
|
||||
for it.Next() {
|
||||
intf, err := t.unmarshalTrunc(it.Value(), false)
|
||||
if err != nil {
|
||||
// Delete local items with invalid indirected blocks/versions.
|
||||
// They will be rescanned.
|
||||
var ierr *blocksIndirectionError
|
||||
if ok := errors.As(err, &ierr); ok && backend.IsNotFound(err) {
|
||||
intf, err = t.unmarshalTrunc(it.Value(), true)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
name := []byte(intf.FileName())
|
||||
gk, err := t.keyer.GenerateGlobalVersionKey(nil, folder, name)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
_, err = t.removeFromGlobal(gk, nil, folder, protocol.LocalDeviceID[:], name, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
sk, err = db.keyer.GenerateSequenceKey(sk, folder, intf.SequenceNo())
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := t.Delete(sk); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := t.Delete(it.Key()); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
fi := intf.(protocol.FileInfo)
|
||||
|
||||
Reference in New Issue
Block a user