cache: fix releasing parent on error
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>docker-19.03
parent
32918bedc9
commit
6defbb2356
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue