syncthing / syncthing

Open Source Continuous File Synchronization
https://forum.syncthing.net/
Mozilla Public License 2.0
61.91k stars 4.13k forks source link

Provide advanced parameter configuration: Disable copying blocks from other folders on the device #9571

Open wobure123 opened 2 weeks ago

wobure123 commented 2 weeks ago

Feature description

Hope to provide a configuration parameter that allows customization to cancel the search for and copying of required blocks from other directories on syncthing machine device

Problem or use case

I use Syncthing as the server in a WebDAV file system, and everything works fine. However, a bug occurs when syncing files with identical hash values. Syncthing prioritizes copying blocks from existing files in other folders, causing the original file to be cyclically downloaded via WebDAV: one download for each copied block. This essentially causes the synchronization process to hang. Currently, I've resolved the bug by commenting out the following code (lib/model/folder_sendrecv.go) and recompiling my own release. I hope a parameter can be provided for custom control , making it more elegant for adapting to WebDAV file systems.

// if !found { //   found = f.model.finder.Iterate(folders, block.Hash, func(folder, path string, index int32) bool {
            //      ffs := folderFilesystems[folder]
            //      fd, err := ffs.Open(path)
            //      if err != nil {
            //          return false
            //      }
            //      defer fd.Close()

            //      srcOffset := int64(state.file.BlockSize()) * int64(index)
            //      _, err = fd.ReadAt(buf, srcOffset)
            //      if err != nil {
            //          return false
            //      }

            //      // Hash is not SHA256 as it's an encrypted hash token. In that
            //      // case we can't verify the block integrity so we'll take it on
            //      // trust. (The other side can and will verify.)
            //      if f.Type != config.FolderTypeReceiveEncrypted {
            //          if err := f.verifyBuffer(buf, block); err != nil {
            //              l.Debugln("Finder failed to verify buffer", err)
            //              return false
            //          }
            //      }

            //      if f.CopyRangeMethod != fs.CopyRangeMethodStandard {
            //          err = f.withLimiter(func() error {
            //              dstFd.mut.Lock()
            //              defer dstFd.mut.Unlock()
            //              return fs.CopyRange(f.CopyRangeMethod, fd, dstFd.fd, srcOffset, block.Offset, int64(block.Size))
            //          })
            //      } else {
            //          err = f.limitedWriteAt(dstFd, buf, block.Offset)
            //      }
            //      if err != nil {
            //          state.fail(fmt.Errorf("dst write: %w", err))
            //      }
            //      if path == state.file.Name {
            //          state.copiedFromOrigin(block.Size)
            //      } else {
            //          state.copiedFromElsewhere(block.Size)
            //      }
            //      return true
            //  })
            // }

Alternatives or workarounds

none

calmh commented 2 weeks ago

Frankly, with a filesystem implementation that stupid, I think you'll run into lots of issues and assumptions where Syncthing won't work well. It seems to me like it might be an inappropriate setup, where the correct solution would be to run Syncthing wherever the webdav server lives.

wobure123 commented 2 weeks ago

Personal special implementation 😁, works fine for months,gonna see how far it will go after unconment those code ~