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

This commit is contained in:
Simon Frei
2021-02-22 18:27:40 +01:00
committed by Jakob Borg
parent b0cce98648
commit 9be6f1a70e
4 changed files with 37 additions and 15 deletions
+22 -6
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 {