Remove ref counting from layer store

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2016-05-06 14:54:28 -07:00
parent 5b6b8df0c1
commit e19499710e
4 changed files with 3 additions and 116 deletions

View File

@ -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
}

View File

@ -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)
@ -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)
@ -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 {
@ -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()

View File

@ -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 {
@ -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 {
@ -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)
@ -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)
}

View File

@ -2,7 +2,6 @@ package layer
import (
"io"
"sync"
"github.com/docker/docker/pkg/archive"
)
@ -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()
}