From 6012179c67276cb90ceb879d3138cafc09a2732c 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 11958138b..0ecb42a85 100644 --- a/vfs/vfscache/cache.go +++ b/vfs/vfscache/cache.go @@ -466,9 +466,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) } }