With this change we emulate a case sensitive filesystem on top of insensitive filesystems. This means we correctly pick up case-only renames and throw a case conflict error when there would be multiple files differing only in case. This safety check has a small performance hit (about 20% more filesystem operations when scanning for changes). The new advanced folder option `caseSensitiveFS` can be used to disable the safety checks, retaining the previous behavior on systems known to be fully case sensitive. Co-authored-by: Jakob Borg <jakob@kastelo.net>
This commit is contained in:
committed by
Jakob Borg
co-authored by
Jakob Borg
parent
21dd9d6b43
commit
932d8c69de
@@ -61,8 +61,8 @@ type FolderConfiguration struct {
|
||||
DisableFsync bool `xml:"disableFsync" json:"disableFsync"`
|
||||
BlockPullOrder BlockPullOrder `xml:"blockPullOrder" json:"blockPullOrder"`
|
||||
CopyRangeMethod fs.CopyRangeMethod `xml:"copyRangeMethod" json:"copyRangeMethod" default:"standard"`
|
||||
CaseSensitiveFS bool `xml:"caseSensitiveFS" json:"caseSensitiveFS"`
|
||||
|
||||
cachedFilesystem fs.Filesystem
|
||||
cachedModTimeWindow time.Duration
|
||||
|
||||
DeprecatedReadOnly bool `xml:"ro,attr,omitempty" json:"-"`
|
||||
@@ -101,11 +101,11 @@ func (f FolderConfiguration) Copy() FolderConfiguration {
|
||||
func (f FolderConfiguration) Filesystem() fs.Filesystem {
|
||||
// This is intentionally not a pointer method, because things like
|
||||
// cfg.Folders["default"].Filesystem() should be valid.
|
||||
if f.cachedFilesystem == nil {
|
||||
l.Infoln("bug: uncached filesystem call (should only happen in tests)")
|
||||
return fs.NewFilesystem(f.FilesystemType, f.Path)
|
||||
filesystem := fs.NewFilesystem(f.FilesystemType, f.Path)
|
||||
if !f.CaseSensitiveFS {
|
||||
filesystem = fs.NewCaseFilesystem(filesystem)
|
||||
}
|
||||
return f.cachedFilesystem
|
||||
return filesystem
|
||||
}
|
||||
|
||||
func (f FolderConfiguration) ModTimeWindow() time.Duration {
|
||||
@@ -210,8 +210,6 @@ func (f *FolderConfiguration) DeviceIDs() []protocol.DeviceID {
|
||||
}
|
||||
|
||||
func (f *FolderConfiguration) prepare() {
|
||||
f.cachedFilesystem = fs.NewFilesystem(f.FilesystemType, f.Path)
|
||||
|
||||
if f.RescanIntervalS > MaxRescanIntervalS {
|
||||
f.RescanIntervalS = MaxRescanIntervalS
|
||||
} else if f.RescanIntervalS < 0 {
|
||||
@@ -263,7 +261,6 @@ func (f FolderConfiguration) RequiresRestartOnly() FolderConfiguration {
|
||||
|
||||
// Manual handling for things that are not taken care of by the tag
|
||||
// copier, yet should not cause a restart.
|
||||
copy.cachedFilesystem = nil
|
||||
|
||||
blank := FolderConfiguration{}
|
||||
util.CopyMatchingTag(&blank, ©, "restart", func(v string) bool {
|
||||
|
||||
Reference in New Issue
Block a user