vfs: Add exponential backoff during ENOSPC retries

Add an exponentially increasing delay during retries up ENOSPC error
to avoid exhausting the 10 retries too soon when the cache space
recovery from item resets is not available from the file system yet
or consumed by other large cache writes.
This commit is contained in:
Leo Luan 2020-10-05 01:47:54 -07:00 committed by Nick Craig-Wood
parent ff0280c0cb
commit 2295123cad
2 changed files with 7 additions and 1 deletions

View file

@ -610,7 +610,6 @@ func (c *Cache) clean(removeCleanFiles bool) {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return return
} }
c.mu.Lock() c.mu.Lock()
oldItems, oldUsed := len(c.item), fs.SizeSuffix(c.used) oldItems, oldUsed := len(c.item), fs.SizeSuffix(c.used)
c.mu.Unlock() c.mu.Unlock()

View file

@ -1182,6 +1182,7 @@ func (item *Item) setModTime(modTime time.Time) {
// ReadAt bytes from the file at off // ReadAt bytes from the file at off
func (item *Item) ReadAt(b []byte, off int64) (n int, err error) { func (item *Item) ReadAt(b []byte, off int64) (n int, err error) {
n = 0 n = 0
var expBackOff int
for retries := 0; retries < fs.Config.LowLevelRetries; retries++ { for retries := 0; retries < fs.Config.LowLevelRetries; retries++ {
item.preAccess() item.preAccess()
n, err = item.readAt(b, off) n, err = item.readAt(b, off)
@ -1195,6 +1196,12 @@ func (item *Item) ReadAt(b []byte, off int64) (n int, err error) {
break break
} }
item.c.KickCleaner() item.c.KickCleaner()
expBackOff = 2 << uint(retries)
time.Sleep(time.Duration(expBackOff) * time.Millisecond) // Exponential back-off the retries
}
if fserrors.IsErrNoSpace(err) {
fs.Errorf(item.name, "vfs cache: failed to _ensure cache after retries %v", err)
} }
return n, err return n, err