Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 32 additions & 18 deletions layer/layer_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,9 @@ func (ls *layerStore) loadLayer(layer ChainID) (*roLayer, error) {
}

func (ls *layerStore) loadMount(mount string) error {
if _, ok := ls.mounts[mount]; ok {
ls.mountL.Lock()
defer ls.mountL.Unlock()
if m := ls.mounts[mount]; m != nil {
return nil
}

Expand Down Expand Up @@ -477,7 +479,7 @@ func (ls *layerStore) Release(l Layer) ([]Metadata, error) {
return ls.releaseLayer(layer)
}

func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWLayerOpts) (RWLayer, error) {
func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWLayerOpts) (_ RWLayer, err error) {
var (
storageOpt map[string]string
initFunc MountInit
Expand All @@ -491,13 +493,21 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWL
}

ls.mountL.Lock()
defer ls.mountL.Unlock()
m, ok := ls.mounts[name]
if ok {
if _, ok := ls.mounts[name]; ok {
ls.mountL.Unlock()
return nil, ErrMountNameConflict
}
// Avoid name collision by temporary assigning nil
ls.mounts[name] = nil
ls.mountL.Unlock()
defer func() {
if err != nil {
ls.mountL.Lock()
delete(ls.mounts, name)
ls.mountL.Unlock()
}
}()

var err error
var pid string
var p *roLayer
if string(parent) != "" {
Expand All @@ -517,7 +527,7 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWL
}()
}

m = &mountedLayer{
m := &mountedLayer{
name: name,
parent: p,
mountID: ls.mountID(name),
Expand All @@ -528,7 +538,7 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWL
if initFunc != nil {
pid, err = ls.initMount(m.mountID, pid, mountLabel, initFunc, storageOpt)
if err != nil {
return nil, err
return
}
m.initID = pid
}
Expand All @@ -538,20 +548,20 @@ func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWL
}

if err = ls.driver.CreateReadWrite(m.mountID, pid, createOpts); err != nil {
return nil, err
return
}
if err = ls.saveMount(m); err != nil {
return nil, err
return
}

return m.getReference(), nil
}

func (ls *layerStore) GetRWLayer(id string) (RWLayer, error) {
ls.mountL.Lock()
defer ls.mountL.Unlock()
mount, ok := ls.mounts[id]
if !ok {
mount := ls.mounts[id]
ls.mountL.Unlock()
if mount == nil {
return nil, ErrMountDoesNotExist
}

Expand All @@ -561,8 +571,8 @@ func (ls *layerStore) GetRWLayer(id string) (RWLayer, error) {
func (ls *layerStore) GetMountID(id string) (string, error) {
ls.mountL.Lock()
defer ls.mountL.Unlock()
mount, ok := ls.mounts[id]
if !ok {
mount := ls.mounts[id]
if mount == nil {
return "", ErrMountDoesNotExist
}
logrus.Debugf("GetMountID id: %s -> mountID: %s", id, mount.mountID)
Expand All @@ -572,9 +582,9 @@ func (ls *layerStore) GetMountID(id string) (string, error) {

func (ls *layerStore) ReleaseRWLayer(l RWLayer) ([]Metadata, error) {
ls.mountL.Lock()
defer ls.mountL.Unlock()
m, ok := ls.mounts[l.Name()]
if !ok {
m := ls.mounts[l.Name()]
ls.mountL.Unlock()
if m == nil {
return []Metadata{}, nil
}

Expand Down Expand Up @@ -606,7 +616,9 @@ func (ls *layerStore) ReleaseRWLayer(l RWLayer) ([]Metadata, error) {
return nil, err
}

ls.mountL.Lock()
delete(ls.mounts, m.Name())
ls.mountL.Unlock()

ls.layerL.Lock()
defer ls.layerL.Unlock()
Expand Down Expand Up @@ -634,7 +646,9 @@ func (ls *layerStore) saveMount(mount *mountedLayer) error {
}
}

ls.mountL.Lock()
ls.mounts[mount.name] = mount
ls.mountL.Unlock()

return nil
}
Expand Down
6 changes: 3 additions & 3 deletions layer/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import (
// after migration the layer may be retrieved by the given name.
func (ls *layerStore) CreateRWLayerByGraphID(name, graphID string, parent ChainID) (err error) {
ls.mountL.Lock()
defer ls.mountL.Unlock()
m, ok := ls.mounts[name]
if ok {
m := ls.mounts[name]
ls.mountL.Unlock()
if m != nil {
if m.parent.chainID != parent {
return errors.New("name conflict, mismatched parent")
}
Expand Down
14 changes: 13 additions & 1 deletion layer/mounted_layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package layer // import "github.com/docker/docker/layer"

import (
"io"
"sync"

"github.com/docker/docker/pkg/archive"
"github.com/docker/docker/pkg/containerfs"
Expand All @@ -15,6 +16,7 @@ type mountedLayer struct {
path string
layerStore *layerStore

sync.Mutex
references map[RWLayer]*referencedRWLayer
}

Expand Down Expand Up @@ -62,16 +64,24 @@ func (ml *mountedLayer) getReference() RWLayer {
ref := &referencedRWLayer{
mountedLayer: ml,
}
ml.Lock()
ml.references[ref] = ref
ml.Unlock()

return ref
}

func (ml *mountedLayer) hasReferences() bool {
return len(ml.references) > 0
ml.Lock()
ret := len(ml.references) > 0
ml.Unlock()

return ret
}

func (ml *mountedLayer) deleteReference(ref RWLayer) error {
ml.Lock()
defer ml.Unlock()
if _, ok := ml.references[ref]; !ok {
return ErrLayerNotRetained
}
Expand All @@ -81,7 +91,9 @@ func (ml *mountedLayer) deleteReference(ref RWLayer) error {

func (ml *mountedLayer) retakeReference(r RWLayer) {
if ref, ok := r.(*referencedRWLayer); ok {
ml.Lock()
ml.references[ref] = ref
ml.Unlock()
}
}

Expand Down