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
+1 -1
View File
@@ -50,7 +50,7 @@ func (f FolderConfiguration) Filesystem() fs.Filesystem {
} }
filesystem := fs.NewFilesystem(f.FilesystemType, f.Path, opts...) filesystem := fs.NewFilesystem(f.FilesystemType, f.Path, opts...)
if !f.CaseSensitiveFS { if !f.CaseSensitiveFS {
filesystem = fs.NewCaseFilesystem(filesystem) filesystem = fs.NewCaseFilesystem(filesystem, opts...)
} }
return filesystem return filesystem
} }
+10 -7
View File
@@ -27,12 +27,15 @@ var (
) )
func WithJunctionsAsDirs() Option { func WithJunctionsAsDirs() Option {
return func(fs Filesystem) { return Option{
if basic, ok := fs.(*BasicFilesystem); !ok { apply: func(fs Filesystem) {
l.Warnln("WithJunctionsAsDirs must only be used with FilesystemTypeBasic") if basic, ok := fs.(*BasicFilesystem); !ok {
} else { l.Warnln("WithJunctionsAsDirs must only be used with FilesystemTypeBasic")
basic.junctionsAsDirs = true } else {
} basic.junctionsAsDirs = true
}
},
id: "junctionsAsDirs",
} }
} }
@@ -82,7 +85,7 @@ func newBasicFilesystem(root string, opts ...Option) *BasicFilesystem {
root: root, root: root,
} }
for _, opt := range opts { for _, opt := range opts {
opt(fs) opt.apply(fs)
} }
return fs return fs
} }
+22 -6
View File
@@ -43,8 +43,8 @@ type realCaser interface {
} }
type fskey struct { type fskey struct {
fstype FilesystemType fstype FilesystemType
uri string uri, opts string
} }
// caseFilesystemRegistry caches caseFilesystems and runs a routine to drop // caseFilesystemRegistry caches caseFilesystems and runs a routine to drop
@@ -55,8 +55,22 @@ type caseFilesystemRegistry struct {
startCleaner sync.Once startCleaner sync.Once
} }
func (r *caseFilesystemRegistry) get(fs Filesystem) Filesystem { func newFSKey(fs Filesystem, opts ...Option) fskey {
k := fskey{fs.Type(), fs.URI()} 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 // 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 // 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 // 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 // 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. // used if the filesystem is known to already behave case-sensitively.
func NewCaseFilesystem(fs Filesystem) Filesystem { func NewCaseFilesystem(fs Filesystem, opts ...Option) Filesystem {
return wrapFilesystem(fs, globalCaseFilesystemRegistry.get) return wrapFilesystem(fs, func(fs Filesystem) Filesystem {
return globalCaseFilesystemRegistry.get(fs, opts...)
})
} }
func (f *caseFilesystem) Chmod(name string, mode FileMode) error { func (f *caseFilesystem) Chmod(name string, mode FileMode) error {
+4 -1
View File
@@ -178,7 +178,10 @@ var IsPermission = os.IsPermission
// IsPathSeparator is the equivalent of os.IsPathSeparator // IsPathSeparator is the equivalent of os.IsPathSeparator
var IsPathSeparator = 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 { func NewFilesystem(fsType FilesystemType, uri string, opts ...Option) Filesystem {
var fs Filesystem var fs Filesystem