From 1e1af46a12afcd88d92fc22cffd62ca8b4e9396d Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Mon, 4 Apr 2022 09:32:50 +0100 Subject: [PATCH] union: fix get free space for remotes which don't support it #6071 Before this fix GetFreeSpace returned math.MaxInt64 for remotes which don't support reading free space, however this is used in various comparison routines as a too large value, meaning that remotes of size math.MaxInt64 were never being selected. This fixes GetFreeSpace to return math.MaxInt64 - 1 so then can be selected. It also fixes GetUsedSpace the same way however as the default for not supported was 0 this was very unlikely to have ever caused a problem. --- backend/union/upstream/upstream.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/backend/union/upstream/upstream.go b/backend/union/upstream/upstream.go index 41f30f400..1a85d783f 100644 --- a/backend/union/upstream/upstream.go +++ b/backend/union/upstream/upstream.go @@ -259,22 +259,30 @@ func (f *Fs) About(ctx context.Context) (*fs.Usage, error) { } // GetFreeSpace get the free space of the fs +// +// This is returned as 0..math.MaxInt64-1 leaving math.MaxInt64 as a sentinel func (f *Fs) GetFreeSpace() (int64, error) { if atomic.LoadInt64(&f.cacheExpiry) <= time.Now().Unix() { err := f.updateUsage() if err != nil { - return math.MaxInt64, ErrUsageFieldNotSupported + return math.MaxInt64 - 1, ErrUsageFieldNotSupported } } f.cacheMutex.RLock() defer f.cacheMutex.RUnlock() if f.usage.Free == nil { - return math.MaxInt64, ErrUsageFieldNotSupported + return math.MaxInt64 - 1, ErrUsageFieldNotSupported } - return *f.usage.Free, nil + free := *f.usage.Free + if free >= math.MaxInt64 { + free = math.MaxInt64 - 1 + } + return free, nil } // GetUsedSpace get the used space of the fs +// +// This is returned as 0..math.MaxInt64-1 leaving math.MaxInt64 as a sentinel func (f *Fs) GetUsedSpace() (int64, error) { if atomic.LoadInt64(&f.cacheExpiry) <= time.Now().Unix() { err := f.updateUsage() @@ -287,7 +295,11 @@ func (f *Fs) GetUsedSpace() (int64, error) { if f.usage.Used == nil { return 0, ErrUsageFieldNotSupported } - return *f.usage.Used, nil + used := *f.usage.Used + if used >= math.MaxInt64 { + used = math.MaxInt64 - 1 + } + return used, nil } // GetNumObjects get the number of objects of the fs