Repository: syncthing/syncthing
File: lib/model/folder_sendrecv.go (Go)

Code before:
	}
	// All good, except maybe failing to remove a (?d) ignored item
	return delErr
}

// scanIfItemChanged schedules the given file for scanning and returns errModified
// if it differs from the information in the database. Returns nil if the file has
// not changed.
func (f *sendReceiveFolder) scanIfItemChanged(name string, stat fs.FileInfo, item protocol.FileInfo, hasItem bool, scanChan chan<- string) (err error) {
	defer func() {
		if err == errModified {
			scanChan <- name
		}
	}()

	if !hasItem || item.Deleted {
		// The item appeared from nowhere
		return errModified
	}

	// Check that the item on disk is what we expect it to be according
	// to the database. If there's a mismatch here, there might be local
	// changes that we don't know about yet and we should scan before
	// touching the item.
	statItem, err := scanner.CreateFileInfo(stat, item.Name, f.mtimefs)
	if err != nil {
		return fmt.Errorf("comparing item on disk to db: %w", err)
	}

	if !statItem.IsEquivalentOptional(item, protocol.FileInfoComparison{
		ModTimeWindow:   f.modTimeWindow,
		IgnorePerms:     f.IgnorePerms,
		IgnoreBlocks:    true,
		IgnoreFlags:     protocol.LocalAllFlags,
		IgnoreOwnership: !f.SyncOwnership,
	}) {
		return errModified
	}

	return nil
}

// checkToBeDeleted makes sure the file on disk is compatible with what there is
// in the DB before the caller proceeds with actually deleting it.
// I.e. non-nil error status means "Do not delete!" or "is already deleted".
func (f *sendReceiveFolder) checkToBeDeleted(file, cur protocol.FileInfo, hasCur bool, scanChan chan<- string) error {
	if err := osutil.TraversesSymlink(f.mtimefs, filepath.Dir(file.Name)); err != nil {
		l.Debugln(f, "not deleting item behind symlink on disk, but update db", file.Name)
		return fs.ErrNotExist
	}


Review comment (suggestion):
```suggestion
		return fmt.Errorf("compare item on disk to db: %w", err)
```

Code after:
	// All good, except maybe failing to remove a (?d) ignored item
	return delErr
}

// scanIfItemChanged schedules the given file for scanning and returns errModified
// if it differs from the information in the database. Returns nil if the file has
// not changed.
func (f *sendReceiveFolder) scanIfItemChanged(name string, stat fs.FileInfo, item protocol.FileInfo, hasItem bool, scanChan chan<- string) (err error) {
	defer func() {
		if err == errModified {
			scanChan <- name
		}
	}()

	if !hasItem || item.Deleted {
		// The item appeared from nowhere
		return errModified
	}

	// Check that the item on disk is what we expect it to be according
	// to the database. If there's a mismatch here, there might be local
	// changes that we don't know about yet and we should scan before
	// touching the item.
	statItem, err := scanner.CreateFileInfo(stat, item.Name, f.mtimefs)
	if err != nil {
		return fmt.Errorf("comparing item on disk to db: %w", err)
	}

	if !statItem.IsEquivalentOptional(item, protocol.FileInfoComparison{
		ModTimeWindow:   f.modTimeWindow,
		IgnorePerms:     f.IgnorePerms,
		IgnoreBlocks:    true,
		IgnoreFlags:     protocol.LocalAllFlags,
		IgnoreOwnership: !f.SyncOwnership,
	}) {
		return errModified
	}

	return nil
}

// checkToBeDeleted makes sure the file on disk is compatible with what there is
// in the DB before the caller proceeds with actually deleting it.
// I.e. non-nil error status means "Do not delete!" or "is already deleted".
func (f *sendReceiveFolder) checkToBeDeleted(file, cur protocol.FileInfo, hasCur bool, scanChan chan<- string) error {
	if err := osutil.TraversesSymlink(f.mtimefs, filepath.Dir(file.Name)); err != nil {
		l.Debugln(f, "not deleting item behind symlink on disk, but update db", file.Name)
		return fs.ErrNotExist
	}

	stat, err := f.mtimefs.Lstat(file.Name)