mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-09 14:50:56 +00:00
lib/db: Don't whack blocks when putting truncated file (#6434)
As of the latest database checker we are again putting files without blocks. I'm not 100% convinced that's a great idea, but we also do it for ignored files apparently so it looks like we probably should support it. This adds an escape hatch that must be manually enabled...
This commit is contained in:
parent
4c5e9cf921
commit
c4abe6f815
@ -261,11 +261,11 @@ func TestRepairSequence(t *testing.T) {
|
|||||||
short := protocol.LocalDeviceID.Short()
|
short := protocol.LocalDeviceID.Short()
|
||||||
|
|
||||||
files := []protocol.FileInfo{
|
files := []protocol.FileInfo{
|
||||||
{Name: "fine"},
|
{Name: "fine", Blocks: genBlocks(1)},
|
||||||
{Name: "duplicate"},
|
{Name: "duplicate", Blocks: genBlocks(2)},
|
||||||
{Name: "missing"},
|
{Name: "missing", Blocks: genBlocks(3)},
|
||||||
{Name: "overwriting"},
|
{Name: "overwriting", Blocks: genBlocks(4)},
|
||||||
{Name: "inconsistent"},
|
{Name: "inconsistent", Blocks: genBlocks(5)},
|
||||||
}
|
}
|
||||||
for i, f := range files {
|
for i, f := range files {
|
||||||
files[i].Version = f.Version.Update(short)
|
files[i].Version = f.Version.Update(short)
|
||||||
@ -282,7 +282,7 @@ func TestRepairSequence(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := trans.putFile(dk, f); err != nil {
|
if err := trans.putFile(dk, f, false); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
sk, err := trans.keyer.GenerateSequenceKey(nil, folder, seq)
|
sk, err := trans.keyer.GenerateSequenceKey(nil, folder, seq)
|
||||||
@ -399,16 +399,20 @@ func TestRepairSequence(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer it.Release()
|
defer it.Release()
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
fi, ok, err := ro.getFileTrunc(it.Value(), true)
|
intf, ok, err := ro.getFileTrunc(it.Value(), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
fi := intf.(protocol.FileInfo)
|
||||||
seq := ro.keyer.SequenceFromSequenceKey(it.Key())
|
seq := ro.keyer.SequenceFromSequenceKey(it.Key())
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Errorf("Sequence entry %v points at nothing", seq)
|
t.Errorf("Sequence entry %v points at nothing", seq)
|
||||||
} else if fi.SequenceNo() != seq {
|
} else if fi.SequenceNo() != seq {
|
||||||
t.Errorf("Inconsistent sequence entry for %v: %v != %v", fi.FileName(), fi.SequenceNo(), seq)
|
t.Errorf("Inconsistent sequence entry for %v: %v != %v", fi.FileName(), fi.SequenceNo(), seq)
|
||||||
}
|
}
|
||||||
|
if len(fi.Blocks) == 0 {
|
||||||
|
t.Error("Missing blocks in", fi.FileName())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := it.Error(); err != nil {
|
if err := it.Error(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -114,7 +114,7 @@ func (db *Lowlevel) updateRemoteFiles(folder, device []byte, fs []protocol.FileI
|
|||||||
meta.addFile(devID, f)
|
meta.addFile(devID, f)
|
||||||
|
|
||||||
l.Debugf("insert; folder=%q device=%v %v", folder, devID, f)
|
l.Debugf("insert; folder=%q device=%v %v", folder, devID, f)
|
||||||
if err := t.putFile(dk, f); err != nil {
|
if err := t.putFile(dk, f, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,7 +201,7 @@ func (db *Lowlevel) updateLocalFiles(folder []byte, fs []protocol.FileInfo, meta
|
|||||||
meta.addFile(protocol.LocalDeviceID, f)
|
meta.addFile(protocol.LocalDeviceID, f)
|
||||||
|
|
||||||
l.Debugf("insert (local); folder=%q %v", folder, f)
|
l.Debugf("insert (local); folder=%q %v", folder, f)
|
||||||
if err := t.putFile(dk, f); err != nil {
|
if err := t.putFile(dk, f, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -643,7 +643,7 @@ func (db *Lowlevel) getMetaAndCheck(folder string) *metadataTracker {
|
|||||||
var fixed int
|
var fixed int
|
||||||
fixed, err = db.repairSequenceGCLocked(folder, meta)
|
fixed, err = db.repairSequenceGCLocked(folder, meta)
|
||||||
if fixed != 0 {
|
if fixed != 0 {
|
||||||
l.Infoln("Repaired %v sequence entries in database", fixed)
|
l.Infof("Repaired %d sequence entries in database", fixed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,7 +790,7 @@ func (db *Lowlevel) repairSequenceGCLocked(folderStr string, meta *metadataTrack
|
|||||||
if err := t.Put(sk, it.Key()); err != nil {
|
if err := t.Put(sk, it.Key()); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if err := t.putFile(it.Key(), fi.copyToFileInfo()); err != nil {
|
if err := t.putFile(it.Key(), fi.copyToFileInfo(), true); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -465,7 +465,7 @@ func (db *schemaUpdater) updateSchemato9(prev int) error {
|
|||||||
if fi.Blocks == nil {
|
if fi.Blocks == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := t.putFile(it.Key(), fi); err != nil {
|
if err := t.putFile(it.Key(), fi, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := t.Checkpoint(); err != nil {
|
if err := t.Checkpoint(); err != nil {
|
||||||
|
@ -432,13 +432,19 @@ func (t readWriteTransaction) close() {
|
|||||||
t.WriteTransaction.Release()
|
t.WriteTransaction.Release()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t readWriteTransaction) putFile(fkey []byte, fi protocol.FileInfo) error {
|
// putFile stores a file in the database, taking care of indirected fields.
|
||||||
|
// Set the truncated flag when putting a file that deliberatly can have an
|
||||||
|
// empty block list but a non-empty block list hash. This should normally be
|
||||||
|
// false.
|
||||||
|
func (t readWriteTransaction) putFile(fkey []byte, fi protocol.FileInfo, truncated bool) error {
|
||||||
var bkey []byte
|
var bkey []byte
|
||||||
|
|
||||||
// Always set the blocks hash when there are blocks.
|
// Always set the blocks hash when there are blocks. Leave the blocks
|
||||||
|
// hash alone when there are no blocks and we might be putting a
|
||||||
|
// "truncated" FileInfo (no blocks, but the hash reference is live).
|
||||||
if len(fi.Blocks) > 0 {
|
if len(fi.Blocks) > 0 {
|
||||||
fi.BlocksHash = protocol.BlocksHash(fi.Blocks)
|
fi.BlocksHash = protocol.BlocksHash(fi.Blocks)
|
||||||
} else {
|
} else if !truncated {
|
||||||
fi.BlocksHash = nil
|
fi.BlocksHash = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user