Skip to content

Commit

Permalink
Remove ref counting from layer store
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Crosby <[email protected]>
  • Loading branch information
crosbymichael committed May 23, 2016
1 parent 5b6b8df commit e194997
Show file tree
Hide file tree
Showing 4 changed files with 3 additions and 116 deletions.
8 changes: 1 addition & 7 deletions layer/layer_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,15 +502,9 @@ func (ls *layerStore) ReinitRWLayer(l RWLayer) error {
ls.mountL.Lock()
defer ls.mountL.Unlock()

m, ok := ls.mounts[l.Name()]
if !ok {
if _, ok := ls.mounts[l.Name()]; !ok {
return ErrMountDoesNotExist
}

if err := m.incActivityCount(l); err != nil {
return err
}

return nil
}

Expand Down
17 changes: 0 additions & 17 deletions layer/layer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,14 +400,11 @@ func TestStoreRestore(t *testing.T) {
if err := ioutil.WriteFile(filepath.Join(path, "testfile.txt"), []byte("nothing here"), 0644); err != nil {
t.Fatal(err)
}
assertActivityCount(t, m, 1)

if err := m.Unmount(); err != nil {
t.Fatal(err)
}

assertActivityCount(t, m, 0)

ls2, err := NewStoreFromGraphDriver(ls.(*layerStore).store, ls.(*layerStore).driver)
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -438,20 +435,15 @@ func TestStoreRestore(t *testing.T) {
t.Fatalf("Unexpected path %s, expected %s", mountPath, path)
}

assertActivityCount(t, m2, 1)

if mountPath, err := m2.Mount(""); err != nil {
t.Fatal(err)
} else if path != mountPath {
t.Fatalf("Unexpected path %s, expected %s", mountPath, path)
}
assertActivityCount(t, m2, 2)
if err := m2.Unmount(); err != nil {
t.Fatal(err)
}

assertActivityCount(t, m2, 1)

b, err := ioutil.ReadFile(filepath.Join(path, "testfile.txt"))
if err != nil {
t.Fatal(err)
Expand All @@ -464,8 +456,6 @@ func TestStoreRestore(t *testing.T) {
t.Fatal(err)
}

assertActivityCount(t, m2, 0)

if metadata, err := ls2.ReleaseRWLayer(m2); err != nil {
t.Fatal(err)
} else if len(metadata) != 0 {
Expand Down Expand Up @@ -674,13 +664,6 @@ func assertReferences(t *testing.T, references ...Layer) {
}
}

func assertActivityCount(t *testing.T, l RWLayer, expected int) {
rl := l.(*referencedRWLayer)
if rl.activityCount != expected {
t.Fatalf("Unexpected activity count %d, expected %d", rl.activityCount, expected)
}
}

func TestRegisterExistingLayer(t *testing.T) {
ls, _, cleanup := newTestStore(t)
defer cleanup()
Expand Down
13 changes: 0 additions & 13 deletions layer/migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,6 @@ func TestMountMigration(t *testing.T) {
Kind: archive.ChangeAdd,
})

assertActivityCount(t, rwLayer1, 1)

if _, err := ls.CreateRWLayer("migration-mount", layer1.ChainID(), "", nil, nil); err == nil {
t.Fatal("Expected error creating mount with same name")
} else if err != ErrMountNameConflict {
Expand All @@ -401,16 +399,10 @@ func TestMountMigration(t *testing.T) {
t.Fatal(err)
}

assertActivityCount(t, rwLayer2, 1)
assertActivityCount(t, rwLayer1, 1)

if _, err := rwLayer2.Mount(""); err != nil {
t.Fatal(err)
}

assertActivityCount(t, rwLayer2, 2)
assertActivityCount(t, rwLayer1, 1)

if metadata, err := ls.Release(layer1); err != nil {
t.Fatal(err)
} else if len(metadata) > 0 {
Expand All @@ -420,8 +412,6 @@ func TestMountMigration(t *testing.T) {
if err := rwLayer1.Unmount(); err != nil {
t.Fatal(err)
}
assertActivityCount(t, rwLayer2, 2)
assertActivityCount(t, rwLayer1, 0)

if _, err := ls.ReleaseRWLayer(rwLayer1); err != nil {
t.Fatal(err)
Expand All @@ -430,9 +420,6 @@ func TestMountMigration(t *testing.T) {
if err := rwLayer2.Unmount(); err != nil {
t.Fatal(err)
}
if _, err := ls.ReleaseRWLayer(rwLayer2); err == nil {
t.Fatal("Expected error deleting active mount")
}
if err := rwLayer2.Unmount(); err != nil {
t.Fatal(err)
}
Expand Down
81 changes: 2 additions & 79 deletions layer/mounted_layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package layer

import (
"io"
"sync"

"github.com/docker/docker/pkg/archive"
)
Expand Down Expand Up @@ -83,106 +82,30 @@ func (ml *mountedLayer) hasReferences() bool {
return len(ml.references) > 0
}

func (ml *mountedLayer) incActivityCount(ref RWLayer) error {
rl, ok := ml.references[ref]
if !ok {
return ErrLayerNotRetained
}

if err := rl.acquire(); err != nil {
return err
}
return nil
}

func (ml *mountedLayer) deleteReference(ref RWLayer) error {
rl, ok := ml.references[ref]
if !ok {
if _, ok := ml.references[ref]; !ok {
return ErrLayerNotRetained
}

if err := rl.release(); err != nil {
return err
}
delete(ml.references, ref)

return nil
}

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

type referencedRWLayer struct {
*mountedLayer

activityL sync.Mutex
activityCount int
}

func (rl *referencedRWLayer) acquire() error {
rl.activityL.Lock()
defer rl.activityL.Unlock()

rl.activityCount++

return nil
}

func (rl *referencedRWLayer) release() error {
rl.activityL.Lock()
defer rl.activityL.Unlock()

if rl.activityCount > 0 {
return ErrActiveMount
}

rl.activityCount = -1

return nil
}

func (rl *referencedRWLayer) Mount(mountLabel string) (string, error) {
rl.activityL.Lock()
defer rl.activityL.Unlock()

if rl.activityCount == -1 {
return "", ErrLayerNotRetained
}

if rl.activityCount > 0 {
rl.activityCount++
return rl.path, nil
}

m, err := rl.mountedLayer.Mount(mountLabel)
if err == nil {
rl.activityCount++
rl.path = m
}
return m, err
return rl.mountedLayer.Mount(mountLabel)
}

// Unmount decrements the activity count and unmounts the underlying layer
// Callers should only call `Unmount` once per call to `Mount`, even on error.
func (rl *referencedRWLayer) Unmount() error {
rl.activityL.Lock()
defer rl.activityL.Unlock()

if rl.activityCount == 0 {
return ErrNotMounted
}
if rl.activityCount == -1 {
return ErrLayerNotRetained
}

rl.activityCount--
if rl.activityCount > 0 {
return nil
}

return rl.mountedLayer.Unmount()
}

0 comments on commit e194997

Please sign in to comment.