lib/fs: Consider options in case-fs caching (fixes #7371) (#7381)

This commit is contained in:
Simon Frei 2021-02-19 11:06:25 +01:00 committed by Jakob Borg
parent b0cce98648
commit 9be6f1a70e
4 changed files with 37 additions and 15 deletions

View File

@ -50,7 +50,7 @@ func (f FolderConfiguration) Filesystem() fs.Filesystem {
}
filesystem := fs.NewFilesystem(f.FilesystemType, f.Path, opts...)
if !f.CaseSensitiveFS {
filesystem = fs.NewCaseFilesystem(filesystem)
filesystem = fs.NewCaseFilesystem(filesystem, opts...)
}
return filesystem
}

View File

@ -27,12 +27,15 @@ var (
)
func WithJunctionsAsDirs() Option {
return func(fs Filesystem) {
if basic, ok := fs.(*BasicFilesystem); !ok {
l.Warnln("WithJunctionsAsDirs must only be used with FilesystemTypeBasic")
} else {
basic.junctionsAsDirs = true
}
return Option{
apply: func(fs Filesystem) {
if basic, ok := fs.(*BasicFilesystem); !ok {
l.Warnln("WithJunctionsAsDirs must only be used with FilesystemTypeBasic")
} else {
basic.junctionsAsDirs = true
}
},
id: "junctionsAsDirs",
}
}
@ -82,7 +85,7 @@ func newBasicFilesystem(root string, opts ...Option) *BasicFilesystem {
root: root,
}
for _, opt := range opts {
opt(fs)
opt.apply(fs)
}
return fs
}

View File

@ -43,8 +43,8 @@ type realCaser interface {
}
type fskey struct {
fstype FilesystemType
uri string
fstype FilesystemType
uri, opts string
}
// caseFilesystemRegistry caches caseFilesystems and runs a routine to drop
@ -55,8 +55,22 @@ type caseFilesystemRegistry struct {
startCleaner sync.Once
}
func (r *caseFilesystemRegistry) get(fs Filesystem) Filesystem {
k := fskey{fs.Type(), fs.URI()}
func newFSKey(fs Filesystem, opts ...Option) fskey {
k := fskey{
fstype: fs.Type(),
uri: fs.URI(),
}
if len(opts) > 0 {
k.opts = opts[0].id
for _, o := range opts[1:] {
k.opts += "&" + o.id
}
}
return k
}
func (r *caseFilesystemRegistry) get(fs Filesystem, opts ...Option) Filesystem {
k := newFSKey(fs, opts...)
// Use double locking when getting a caseFs. In the common case it will
// already exist and we take the read lock fast path. If it doesn't, we
@ -122,8 +136,10 @@ type caseFilesystem struct {
// from the real path. It is safe to use with any filesystem, i.e. also a
// case-sensitive one. However it will add some overhead and thus shouldn't be
// used if the filesystem is known to already behave case-sensitively.
func NewCaseFilesystem(fs Filesystem) Filesystem {
return wrapFilesystem(fs, globalCaseFilesystemRegistry.get)
func NewCaseFilesystem(fs Filesystem, opts ...Option) Filesystem {
return wrapFilesystem(fs, func(fs Filesystem) Filesystem {
return globalCaseFilesystemRegistry.get(fs, opts...)
})
}
func (f *caseFilesystem) Chmod(name string, mode FileMode) error {

View File

@ -178,7 +178,10 @@ var IsPermission = os.IsPermission
// IsPathSeparator is the equivalent of os.IsPathSeparator
var IsPathSeparator = os.IsPathSeparator
type Option func(Filesystem)
type Option struct {
apply func(Filesystem)
id string
}
func NewFilesystem(fsType FilesystemType, uri string, opts ...Option) Filesystem {
var fs Filesystem