cache: fix releasing parent on error

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
docker-19.03
Tonis Tiigi 2019-05-24 18:37:24 -07:00
parent 32918bedc9
commit 6defbb2356
2 changed files with 21 additions and 19 deletions

21
cache/manager.go vendored
View File

@ -125,7 +125,7 @@ func (cm *cacheManager) GetFromSnapshotter(ctx context.Context, id string, opts
}
// get requires manager lock to be taken
func (cm *cacheManager) get(ctx context.Context, id string, fromSnapshotter bool, opts ...RefOption) (ImmutableRef, error) {
func (cm *cacheManager) get(ctx context.Context, id string, fromSnapshotter bool, opts ...RefOption) (*immutableRef, error) {
rec, err := cm.getRecord(ctx, id, fromSnapshotter, opts...)
if err != nil {
return nil, err
@ -193,7 +193,7 @@ func (cm *cacheManager) getRecord(ctx context.Context, id string, fromSnapshotte
return nil, errors.Wrap(errNotFound, err.Error())
}
var parent ImmutableRef
var parent *immutableRef
if info.Parent != "" {
parent, err = cm.get(ctx, info.Parent, fromSnapshotter, append(opts, NoUpdateLastUsed)...)
if err != nil {
@ -201,7 +201,9 @@ func (cm *cacheManager) getRecord(ctx context.Context, id string, fromSnapshotte
}
defer func() {
if retErr != nil {
parent.Release(context.TODO())
parent.mu.Lock()
parent.release(context.TODO())
parent.mu.Unlock()
}
}()
}
@ -224,9 +226,6 @@ func (cm *cacheManager) getRecord(ctx context.Context, id string, fromSnapshotte
}
if err := initializeMetadata(rec, opts...); err != nil {
if parent != nil {
parent.Release(context.TODO())
}
return nil, err
}
@ -237,18 +236,18 @@ func (cm *cacheManager) getRecord(ctx context.Context, id string, fromSnapshotte
func (cm *cacheManager) New(ctx context.Context, s ImmutableRef, opts ...RefOption) (MutableRef, error) {
id := identity.NewID()
var parent ImmutableRef
var parent *immutableRef
var parentID string
if s != nil {
var err error
parent, err = cm.Get(ctx, s.ID(), NoUpdateLastUsed)
p, err := cm.Get(ctx, s.ID(), NoUpdateLastUsed)
if err != nil {
return nil, err
}
if err := parent.Finalize(ctx, true); err != nil {
if err := p.Finalize(ctx, true); err != nil {
return nil, err
}
parentID = parent.ID()
parentID = p.ID()
parent = p.(*immutableRef)
}
if err := cm.Snapshotter.Prepare(ctx, id, parentID); err != nil {

19
cache/refs.go vendored
View File

@ -50,7 +50,7 @@ type cacheRecord struct {
mutable bool
refs map[ref]struct{}
parent ImmutableRef
parent *immutableRef
md *metadata.StorageItem
// dead means record is marked as deleted
@ -126,14 +126,17 @@ func (cr *cacheRecord) Size(ctx context.Context) (int64, error) {
}
func (cr *cacheRecord) Parent() ImmutableRef {
return cr.parentRef(true)
if p := cr.parentRef(true); p != nil { // avoid returning typed nil pointer
return p
}
return nil
}
func (cr *cacheRecord) parentRef(hidden bool) ImmutableRef {
if cr.parent == nil {
func (cr *cacheRecord) parentRef(hidden bool) *immutableRef {
p := cr.parent
if p == nil {
return nil
}
p := cr.parent.(*immutableRef)
p.mu.Lock()
defer p.mu.Unlock()
return p.ref(hidden)
@ -181,7 +184,7 @@ func (cr *cacheRecord) Mount(ctx context.Context, readonly bool) (snapshot.Mount
func (cr *cacheRecord) remove(ctx context.Context, removeSnapshot bool) error {
delete(cr.cm.records, cr.ID())
if cr.parent != nil {
if err := cr.parent.(*immutableRef).release(ctx); err != nil {
if err := cr.parent.release(ctx); err != nil {
return err
}
}
@ -315,7 +318,7 @@ func (sr *mutableRef) updateLastUsed() bool {
return sr.triggerLastUsed
}
func (sr *mutableRef) commit(ctx context.Context) (ImmutableRef, error) {
func (sr *mutableRef) commit(ctx context.Context) (*immutableRef, error) {
if !sr.mutable || len(sr.refs) == 0 {
return nil, errors.Wrapf(errInvalid, "invalid mutable ref %p", sr)
}
@ -398,7 +401,7 @@ func (sr *mutableRef) release(ctx context.Context) error {
}
}
if sr.parent != nil {
if err := sr.parent.(*immutableRef).release(ctx); err != nil {
if err := sr.parent.release(ctx); err != nil {
return err
}
}