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 12, 2024
1 parent e31e896 commit ee8e7f4
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 @@ -83,6 +83,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 @@ -111,7 +112,7 @@ func getLayersCacheRef(store storage.Store) *layersCache {
cache.refs++
return cache
}
cache := &layersCache{
cache = &layersCache{
store: store,
refs: 1,
created: time.Now(),
Expand Down Expand Up @@ -781,14 +782,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 ee8e7f4

Please sign in to comment.