lib/db: Copy returned, old FileVersion (#6952)

This commit is contained in:
Simon Frei 2020-09-04 14:13:38 +02:00 committed by GitHub
parent 7b821d2550
commit 52d1681fe6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 8 deletions

View File

@ -262,9 +262,10 @@ func (vl *VersionList) update(folder, device []byte, file protocol.FileIntf, t r
// Get the current global (before updating) // Get the current global (before updating)
oldFV, haveOldGlobal := vl.GetGlobal() oldFV, haveOldGlobal := vl.GetGlobal()
oldFV = oldFV.copy()
// Remove ourselves first // Remove ourselves first
removedFV, haveRemoved, _, err := vl.pop(folder, device, []byte(file.FileName()), t) removedFV, haveRemoved, _, err := vl.pop(device, []byte(file.FileName()))
if err == nil { if err == nil {
// Find position and insert the file // Find position and insert the file
err = vl.insert(folder, device, file, t) err = vl.insert(folder, device, file, t)
@ -314,10 +315,10 @@ func (vl *VersionList) insertAt(i int, v FileVersion) {
vl.RawVersions[i] = v vl.RawVersions[i] = v
} }
// pop returns the VersionList without the entry for the given device, as well // pop removes the given device from the VersionList and returns the FileVersion
// as the removed FileVersion, whether it was found/removed at all and whether // before removing the device, whether it was found/removed at all and whether
// the global changed in the process. // the global changed in the process.
func (vl *VersionList) pop(folder, device, name []byte, t readOnlyTransaction) (FileVersion, bool, bool, error) { func (vl *VersionList) pop(device, name []byte) (FileVersion, bool, bool, error) {
invDevice, i, j, ok := vl.findDevice(device) invDevice, i, j, ok := vl.findDevice(device)
if !ok { if !ok {
return FileVersion{}, false, false, nil return FileVersion{}, false, false, nil
@ -330,6 +331,7 @@ func (vl *VersionList) pop(folder, device, name []byte, t readOnlyTransaction) (
return fv, true, globalPos == i, nil return fv, true, globalPos == i, nil
} }
oldFV := vl.RawVersions[i].copy()
if invDevice { if invDevice {
vl.RawVersions[i].InvalidDevices = popDeviceAt(vl.RawVersions[i].InvalidDevices, j) vl.RawVersions[i].InvalidDevices = popDeviceAt(vl.RawVersions[i].InvalidDevices, j)
} else { } else {
@ -338,9 +340,9 @@ func (vl *VersionList) pop(folder, device, name []byte, t readOnlyTransaction) (
// If the last valid device of the previous global was removed above, // If the last valid device of the previous global was removed above,
// the next entry is now the global entry (unless all entries are invalid). // the next entry is now the global entry (unless all entries are invalid).
if len(vl.RawVersions[i].Devices) == 0 && globalPos == i { if len(vl.RawVersions[i].Devices) == 0 && globalPos == i {
return vl.RawVersions[i], true, globalPos == vl.findGlobal(), nil return oldFV, true, globalPos == vl.findGlobal(), nil
} }
return vl.RawVersions[i], true, false, nil return oldFV, true, false, nil
} }
// Get returns a FileVersion that contains the given device and whether it has // Get returns a FileVersion that contains the given device and whether it has
@ -536,6 +538,14 @@ func (fv FileVersion) deviceCount() int {
return len(fv.Devices) + len(fv.InvalidDevices) return len(fv.Devices) + len(fv.InvalidDevices)
} }
func (fv FileVersion) copy() FileVersion {
n := fv
n.Version = fv.Version.Copy()
n.Devices = append([][]byte{}, fv.Devices...)
n.InvalidDevices = append([][]byte{}, fv.InvalidDevices...)
return n
}
type fileList []protocol.FileInfo type fileList []protocol.FileInfo
func (fl fileList) Len() int { func (fl fileList) Len() int {

View File

@ -707,7 +707,7 @@ func (t readWriteTransaction) updateGlobal(gk, keyBuf, folder, device []byte, fi
} }
} }
} }
if Need(globalFV, haveLocal, localFV.Version) { if needNow {
meta.addNeeded(protocol.LocalDeviceID, global) meta.addNeeded(protocol.LocalDeviceID, global)
if !needBefore { if !needBefore {
if keyBuf, err = t.updateLocalNeed(keyBuf, folder, name, true); err != nil { if keyBuf, err = t.updateLocalNeed(keyBuf, folder, name, true); err != nil {
@ -801,7 +801,7 @@ func (t readWriteTransaction) removeFromGlobal(gk, keyBuf, folder, device, file
return keyBuf, t.Delete(gk) return keyBuf, t.Delete(gk)
} }
removedFV, haveRemoved, globalChanged, err := fl.pop(folder, device, file, t.readOnlyTransaction) removedFV, haveRemoved, globalChanged, err := fl.pop(device, file)
if err != nil { if err != nil {
return nil, err return nil, err
} }