Skip to content

Commit

Permalink
chunked: fix reuse of the layers cache
Browse files Browse the repository at this point in the history
the global singleton was never updated, causing the cache to be always
recreated for each layer.

It is not possible to keep the layersCache mutex for the entire load()
since it calls into some store APIs causing a deadlock since
findDigestInternal() is already called while some store locks are
held.

Another benefit is that now only one goroutine can run load()
preventing multiple calls to load() to happen in parallel doing the
same work.

Closes: #2023

Signed-off-by: Giuseppe Scrivano <[email protected]>
  • Loading branch information
giuseppe committed Sep 13, 2024
1 parent ba6296e commit 918081c
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions pkg/chunked/cache_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func (c *layer) release() {
if err := unix.Munmap(c.mmapBuffer); err != nil {
logrus.Warnf("Error Munmap: layer %q: %v", c.id, err)
}
c.mmapBuffer = nil
}
}

Expand Down Expand Up @@ -110,7 +111,7 @@ func getLayersCacheRef(store storage.Store) *layersCache {
cache.refs++
return cache
}
cache := &layersCache{
cache = &layersCache{
store: store,
refs: 1,
}
Expand Down Expand Up @@ -779,14 +780,14 @@ func (c *layersCache) findDigestInternal(digest string) (string, string, int64,
return "", "", -1, nil
}

c.mutex.RLock()
defer c.mutex.RUnlock()

binaryDigest, err := makeBinaryDigest(digest)
if err != nil {
return "", "", 0, err
}

c.mutex.RLock()
defer c.mutex.RUnlock()

for _, layer := range c.layers {
if !layer.cacheFile.bloomFilter.maybeContains(binaryDigest) {
continue
Expand Down

0 comments on commit 918081c

Please sign in to comment.