From 64d736a57bf429a9dd502222d1150e8d4ad721ff Mon Sep 17 00:00:00 2001 From: Leo Luan Date: Tue, 15 Sep 2020 01:36:17 -0700 Subject: [PATCH] vfs: Fix a race condition in retryFailedResets A failed item reset is saved in the errItems for retryFailedResets to process. If the item gets closed before the retry, the item may have been removed from the c.item array. Previous code did not account for this condition. This patch adds the check for the exitence of the retry items in retryFailedResets. --- vfs/vfscache/cache.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/vfs/vfscache/cache.go b/vfs/vfscache/cache.go index 3670e7058..9f6d5ca4e 100644 --- a/vfs/vfscache/cache.go +++ b/vfs/vfscache/cache.go @@ -467,9 +467,15 @@ func (c *Cache) retryFailedResets() { if len(c.errItems) != 0 { fs.Debugf(nil, "vfs cache reset: before redoing reset errItems = %v", c.errItems) for itemName := range c.errItems { - _, _, err := c.item[itemName].Reset() - if err == nil || !fserrors.IsErrNoSpace(err) { - // TODO: not trying to handle non-ENOSPC errors yet + if retryItem, ok := c.item[itemName]; ok { + _, _, err := retryItem.Reset() + if err == nil || !fserrors.IsErrNoSpace(err) { + // TODO: not trying to handle non-ENOSPC errors yet + delete(c.errItems, itemName) + } + } else { + // The retry item was deleted because it was closed. + // No need to redo the failed reset now. delete(c.errItems, itemName) } }