From 3df3c9f9aea7ef1b70b896e5fbcfe419837b1a6c Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Thu, 13 Sep 2018 15:38:16 -0400 Subject: [PATCH] Hold the layer store lock while diffing While generating a Diff, hold the lock on the layer store until after we've completely finished building the diff. There's an internal Mount/Unmount being done so that we can read the layer's contents, and we don't update the mount counts properly if we're not still holding the lock when the layer store's Unmount() method is called, which doesn't happen until the ReadCloser that Diff() returns gets closed. Signed-off-by: Nalin Dahyabhai --- store.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/store.go b/store.go index e0deb2c30c..94cf1f0a74 100644 --- a/store.go +++ b/store.go @@ -2369,13 +2369,23 @@ func (s *store) Diff(from, to string, options *DiffOptions) (io.ReadCloser, erro } for _, store := range append([]ROLayerStore{lstore}, lstores...) { store.Lock() - defer store.Unlock() if modified, err := store.Modified(); modified || err != nil { store.Load() } if store.Exists(to) { - return store.Diff(from, to, options) + rc, err := store.Diff(from, to, options) + if rc != nil && err == nil { + wrapped := ioutils.NewReadCloserWrapper(rc, func() error { + err := rc.Close() + store.Unlock() + return err + }) + return wrapped, nil + } + store.Unlock() + return rc, err } + store.Unlock() } return nil, ErrLayerUnknown }