lib/model: Don't consider hashes pulling on recv-enc (#7869)
This commit is contained in:
parent
6d0816e85a
commit
e56e8b7aa1
|
@ -1081,51 +1081,20 @@ func (f *sendReceiveFolder) handleFile(file protocol.FileInfo, snap *db.Snapshot
|
||||||
|
|
||||||
populateOffsets(file.Blocks)
|
populateOffsets(file.Blocks)
|
||||||
|
|
||||||
blocks := make([]protocol.BlockInfo, 0, len(file.Blocks))
|
blocks := append([]protocol.BlockInfo{}, file.Blocks...)
|
||||||
reused := make([]int, 0, len(file.Blocks))
|
reused := make([]int, 0, len(file.Blocks))
|
||||||
|
|
||||||
// Check for an old temporary file which might have some blocks we could
|
if f.Type != config.FolderTypeReceiveEncrypted {
|
||||||
// reuse.
|
blocks, reused = f.reuseBlocks(blocks, reused, file, tempName)
|
||||||
tempBlocks, err := scanner.HashFile(f.ctx, f.mtimefs, tempName, file.BlockSize(), nil, false)
|
|
||||||
if err != nil {
|
|
||||||
var caseErr *fs.ErrCaseConflict
|
|
||||||
if errors.As(err, &caseErr) {
|
|
||||||
if rerr := f.mtimefs.Rename(caseErr.Real, tempName); rerr == nil {
|
|
||||||
tempBlocks, err = scanner.HashFile(f.ctx, f.mtimefs, tempName, file.BlockSize(), nil, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if err == nil {
|
|
||||||
// Check for any reusable blocks in the temp file
|
|
||||||
tempCopyBlocks, _ := blockDiff(tempBlocks, file.Blocks)
|
|
||||||
|
|
||||||
// block.String() returns a string unique to the block
|
// The sharedpullerstate will know which flags to use when opening the
|
||||||
existingBlocks := make(map[string]struct{}, len(tempCopyBlocks))
|
// temp file depending if we are reusing any blocks or not.
|
||||||
for _, block := range tempCopyBlocks {
|
if len(reused) == 0 {
|
||||||
existingBlocks[block.String()] = struct{}{}
|
// Otherwise, discard the file ourselves in order for the
|
||||||
}
|
// sharedpuller not to panic when it fails to exclusively create a
|
||||||
|
// file which already exists
|
||||||
// Since the blocks are already there, we don't need to get them.
|
f.inWritableDir(f.mtimefs.Remove, tempName)
|
||||||
for i, block := range file.Blocks {
|
|
||||||
_, ok := existingBlocks[block.String()]
|
|
||||||
if !ok {
|
|
||||||
blocks = append(blocks, block)
|
|
||||||
} else {
|
|
||||||
reused = append(reused, i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The sharedpullerstate will know which flags to use when opening the
|
|
||||||
// temp file depending if we are reusing any blocks or not.
|
|
||||||
if len(reused) == 0 {
|
|
||||||
// Otherwise, discard the file ourselves in order for the
|
|
||||||
// sharedpuller not to panic when it fails to exclusively create a
|
|
||||||
// file which already exists
|
|
||||||
f.inWritableDir(f.mtimefs.Remove, tempName)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Copy the blocks, as we don't want to shuffle them on the FileInfo
|
|
||||||
blocks = append(blocks, file.Blocks...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reorder blocks
|
// Reorder blocks
|
||||||
|
@ -1150,6 +1119,45 @@ func (f *sendReceiveFolder) handleFile(file protocol.FileInfo, snap *db.Snapshot
|
||||||
copyChan <- cs
|
copyChan <- cs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *sendReceiveFolder) reuseBlocks(blocks []protocol.BlockInfo, reused []int, file protocol.FileInfo, tempName string) ([]protocol.BlockInfo, []int) {
|
||||||
|
// Check for an old temporary file which might have some blocks we could
|
||||||
|
// reuse.
|
||||||
|
tempBlocks, err := scanner.HashFile(f.ctx, f.mtimefs, tempName, file.BlockSize(), nil, false)
|
||||||
|
if err != nil {
|
||||||
|
var caseErr *fs.ErrCaseConflict
|
||||||
|
if errors.As(err, &caseErr) {
|
||||||
|
if rerr := f.mtimefs.Rename(caseErr.Real, tempName); rerr == nil {
|
||||||
|
tempBlocks, err = scanner.HashFile(f.ctx, f.mtimefs, tempName, file.BlockSize(), nil, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return blocks, reused
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for any reusable blocks in the temp file
|
||||||
|
tempCopyBlocks, _ := blockDiff(tempBlocks, file.Blocks)
|
||||||
|
|
||||||
|
// block.String() returns a string unique to the block
|
||||||
|
existingBlocks := make(map[string]struct{}, len(tempCopyBlocks))
|
||||||
|
for _, block := range tempCopyBlocks {
|
||||||
|
existingBlocks[block.String()] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since the blocks are already there, we don't need to get them.
|
||||||
|
blocks = blocks[:0]
|
||||||
|
for i, block := range file.Blocks {
|
||||||
|
_, ok := existingBlocks[block.String()]
|
||||||
|
if !ok {
|
||||||
|
blocks = append(blocks, block)
|
||||||
|
} else {
|
||||||
|
reused = append(reused, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return blocks, reused
|
||||||
|
}
|
||||||
|
|
||||||
// blockDiff returns lists of common and missing (to transform src into tgt)
|
// blockDiff returns lists of common and missing (to transform src into tgt)
|
||||||
// blocks. Both block lists must have been created with the same block size.
|
// blocks. Both block lists must have been created with the same block size.
|
||||||
func blockDiff(src, tgt []protocol.BlockInfo) ([]protocol.BlockInfo, []protocol.BlockInfo) {
|
func blockDiff(src, tgt []protocol.BlockInfo) ([]protocol.BlockInfo, []protocol.BlockInfo) {
|
||||||
|
|
Loading…
Reference in New Issue