mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-22 19:08:58 +00:00
This commit is contained in:
parent
f6fac3e949
commit
8f199e12b3
@ -48,25 +48,35 @@ type fskey struct {
|
||||
// their cache every now and then.
|
||||
type caseFilesystemRegistry struct {
|
||||
fss map[fskey]*caseFilesystem
|
||||
mut sync.Mutex
|
||||
mut sync.RWMutex
|
||||
startCleaner sync.Once
|
||||
}
|
||||
|
||||
func (r *caseFilesystemRegistry) get(fs Filesystem) Filesystem {
|
||||
r.mut.Lock()
|
||||
defer r.mut.Unlock()
|
||||
|
||||
k := fskey{fs.Type(), fs.URI()}
|
||||
|
||||
// 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
|
||||
// take a write lock and try again.
|
||||
|
||||
r.mut.RLock()
|
||||
caseFs, ok := r.fss[k]
|
||||
r.mut.RUnlock()
|
||||
|
||||
if !ok {
|
||||
caseFs = &caseFilesystem{
|
||||
Filesystem: fs,
|
||||
realCaser: newDefaultRealCaser(fs),
|
||||
r.mut.Lock()
|
||||
caseFs, ok = r.fss[k]
|
||||
if !ok {
|
||||
caseFs = &caseFilesystem{
|
||||
Filesystem: fs,
|
||||
realCaser: newDefaultRealCaser(fs),
|
||||
}
|
||||
r.fss[k] = caseFs
|
||||
r.startCleaner.Do(func() {
|
||||
go r.cleaner()
|
||||
})
|
||||
}
|
||||
r.fss[k] = caseFs
|
||||
r.startCleaner.Do(func() {
|
||||
go r.cleaner()
|
||||
})
|
||||
r.mut.Unlock()
|
||||
}
|
||||
|
||||
return caseFs
|
||||
@ -74,11 +84,11 @@ func (r *caseFilesystemRegistry) get(fs Filesystem) Filesystem {
|
||||
|
||||
func (r *caseFilesystemRegistry) cleaner() {
|
||||
for range time.NewTicker(time.Minute).C {
|
||||
r.mut.Lock()
|
||||
r.mut.RLock()
|
||||
for _, caseFs := range r.fss {
|
||||
caseFs.dropCache()
|
||||
}
|
||||
r.mut.Unlock()
|
||||
r.mut.RUnlock()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1790,13 +1790,6 @@ func (m *model) Request(deviceID protocol.DeviceID, folder, name string, blockNo
|
||||
return nil, protocol.ErrInvalid
|
||||
}
|
||||
|
||||
folderFs := folderCfg.Filesystem()
|
||||
|
||||
if err := osutil.TraversesSymlink(folderFs, filepath.Dir(name)); err != nil {
|
||||
l.Debugf("%v REQ(in) traversal check: %s - %s: %q / %q o=%d s=%d", m, err, deviceID, folder, name, offset, size)
|
||||
return nil, protocol.ErrNoSuchFile
|
||||
}
|
||||
|
||||
// Restrict parallel requests by connection/device
|
||||
|
||||
m.pmut.RLock()
|
||||
@ -1814,6 +1807,16 @@ func (m *model) Request(deviceID protocol.DeviceID, folder, name string, blockNo
|
||||
}
|
||||
}()
|
||||
|
||||
// Grab the FS after limiting, as it causes I/O and we want to minimize
|
||||
// the race time between the symlink check and the read.
|
||||
|
||||
folderFs := folderCfg.Filesystem()
|
||||
|
||||
if err := osutil.TraversesSymlink(folderFs, filepath.Dir(name)); err != nil {
|
||||
l.Debugf("%v REQ(in) traversal check: %s - %s: %q / %q o=%d s=%d", m, err, deviceID, folder, name, offset, size)
|
||||
return nil, protocol.ErrNoSuchFile
|
||||
}
|
||||
|
||||
// Only check temp files if the flag is set, and if we are set to advertise
|
||||
// the temp indexes.
|
||||
if fromTemporary && !folderCfg.DisableTempIndexes {
|
||||
|
Loading…
Reference in New Issue
Block a user