diff --git a/daemon/commit.go b/daemon/commit.go
index 3e5744c0c2..ba083598b0 100644
--- a/daemon/commit.go
+++ b/daemon/commit.go
@@ -145,7 +145,7 @@ func (daemon *Daemon) exportContainerRw(container *container.Container) (archive
 	}
 	return ioutils.NewReadCloserWrapper(archive, func() error {
 			archive.Close()
-			return daemon.layerStore.Unmount(container.ID)
+			return container.RWLayer.Unmount()
 		}),
 		nil
 }
diff --git a/daemon/container_operations_windows.go b/daemon/container_operations_windows.go
index ebbefa3eb4..2c4a24c463 100644
--- a/daemon/container_operations_windows.go
+++ b/daemon/container_operations_windows.go
@@ -98,7 +98,7 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
 		}
 	}
 
-	m, err := daemon.layerStore.Metadata(c.ID)
+	m, err := c.RWLayer.Metadata()
 	if err != nil {
 		return derr.ErrorCodeGetLayerMetadata.WithArgs(err)
 	}
diff --git a/daemon/create.go b/daemon/create.go
index aa3d97896e..26b7c1c26c 100644
--- a/daemon/create.go
+++ b/daemon/create.go
@@ -7,6 +7,7 @@ import (
 	"github.com/docker/docker/container"
 	derr "github.com/docker/docker/errors"
 	"github.com/docker/docker/image"
+	"github.com/docker/docker/layer"
 	"github.com/docker/docker/pkg/idtools"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/volume"
@@ -95,6 +96,11 @@ func (daemon *Daemon) create(params types.ContainerCreateConfig) (*container.Con
 		}
 	}()
 
+	// Set RWLayer for container after mount labels have been set
+	if err := daemon.setRWLayer(container); err != nil {
+		return nil, err
+	}
+
 	if err := daemon.createContainerPlatformSpecificSettings(container, params.Config, params.HostConfig, img); err != nil {
 		return nil, err
 	}
@@ -126,6 +132,24 @@ func (daemon *Daemon) generateSecurityOpt(ipcMode containertypes.IpcMode, pidMod
 	return nil, nil
 }
 
+func (daemon *Daemon) setRWLayer(container *container.Container) error {
+	var layerID layer.ChainID
+	if container.ImageID != "" {
+		img, err := daemon.imageStore.Get(container.ImageID)
+		if err != nil {
+			return err
+		}
+		layerID = img.RootFS.ChainID()
+	}
+	rwLayer, err := daemon.layerStore.CreateRWLayer(container.ID, layerID, container.MountLabel, daemon.setupInitLayer)
+	if err != nil {
+		return err
+	}
+	container.RWLayer = rwLayer
+
+	return nil
+}
+
 // VolumeCreate creates a volume with the specified name, driver, and opts
 // This is called directly from the remote API
 func (daemon *Daemon) VolumeCreate(name, driverName string, opts map[string]string) (*types.Volume, error) {
diff --git a/daemon/daemon.go b/daemon/daemon.go
index 7f84de7c4f..fb8ed4600f 100644
--- a/daemon/daemon.go
+++ b/daemon/daemon.go
@@ -323,6 +323,13 @@ func (daemon *Daemon) restore() error {
 			continue
 		}
 
+		rwlayer, err := daemon.layerStore.GetRWLayer(container.ID)
+		if err != nil {
+			logrus.Errorf("Failed to load container mount %v: %v", id, err)
+			continue
+		}
+		container.RWLayer = rwlayer
+
 		// Ignore the container if it does not support the current driver being used by the graph
 		if (container.Driver == "" && currentDriver == "aufs") || container.Driver == currentDriver {
 			logrus.Debugf("Loaded container %v", container.ID)
@@ -961,19 +968,7 @@ func (daemon *Daemon) Shutdown() error {
 // Mount sets container.BaseFS
 // (is it not set coming in? why is it unset?)
 func (daemon *Daemon) Mount(container *container.Container) error {
-	var layerID layer.ChainID
-	if container.ImageID != "" {
-		img, err := daemon.imageStore.Get(container.ImageID)
-		if err != nil {
-			return err
-		}
-		layerID = img.RootFS.ChainID()
-	}
-	rwlayer, err := daemon.layerStore.Mount(container.ID, layerID, container.GetMountLabel(), daemon.setupInitLayer)
-	if err != nil {
-		return err
-	}
-	dir, err := rwlayer.Path()
+	dir, err := container.RWLayer.Mount(container.GetMountLabel())
 	if err != nil {
 		return err
 	}
@@ -990,13 +985,12 @@ func (daemon *Daemon) Mount(container *container.Container) error {
 		}
 	}
 	container.BaseFS = dir // TODO: combine these fields
-	container.RWLayer = rwlayer
 	return nil
 }
 
 // Unmount unsets the container base filesystem
 func (daemon *Daemon) Unmount(container *container.Container) {
-	if err := daemon.layerStore.Unmount(container.ID); err != nil {
+	if err := container.RWLayer.Unmount(); err != nil {
 		logrus.Errorf("Error unmounting container %s: %s", container.ID, err)
 	}
 }
@@ -1029,7 +1023,7 @@ func (daemon *Daemon) unsubscribeToContainerStats(c *container.Container, ch cha
 }
 
 func (daemon *Daemon) changes(container *container.Container) ([]archive.Change, error) {
-	return daemon.layerStore.Changes(container.ID)
+	return container.RWLayer.Changes()
 }
 
 // TagImage creates a tag in the repository reponame, pointing to the image named
diff --git a/daemon/delete.go b/daemon/delete.go
index a282f3a9f9..e2ce1a8568 100644
--- a/daemon/delete.go
+++ b/daemon/delete.go
@@ -130,7 +130,7 @@ func (daemon *Daemon) cleanupContainer(container *container.Container, forceRemo
 		return derr.ErrorCodeRmFS.WithArgs(container.ID, err)
 	}
 
-	metadata, err := daemon.layerStore.DeleteMount(container.ID)
+	metadata, err := daemon.layerStore.ReleaseRWLayer(container.RWLayer)
 	layer.LogReleaseMetadata(metadata)
 	if err != nil && err != layer.ErrMountDoesNotExist {
 		return derr.ErrorCodeRmDriverFS.WithArgs(daemon.driver, container.ID, err)
diff --git a/daemon/inspect.go b/daemon/inspect.go
index 60bebcc598..b1e4eb43a7 100644
--- a/daemon/inspect.go
+++ b/daemon/inspect.go
@@ -163,7 +163,7 @@ func (daemon *Daemon) getInspectData(container *container.Container, size bool)
 
 	contJSONBase.GraphDriver.Name = container.Driver
 
-	graphDriverData, err := daemon.layerStore.Metadata(container.ID)
+	graphDriverData, err := container.RWLayer.Metadata()
 	if err != nil {
 		return nil, err
 	}
diff --git a/distribution/xfer/download_test.go b/distribution/xfer/download_test.go
index a09cd244e1..474e523694 100644
--- a/distribution/xfer/download_test.go
+++ b/distribution/xfer/download_test.go
@@ -12,7 +12,6 @@ import (
 	"github.com/docker/distribution/digest"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
-	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/progress"
 	"golang.org/x/net/context"
 )
@@ -115,25 +114,18 @@ func (ls *mockLayerStore) Get(chainID layer.ChainID) (layer.Layer, error) {
 func (ls *mockLayerStore) Release(l layer.Layer) ([]layer.Metadata, error) {
 	return []layer.Metadata{}, nil
 }
-
-func (ls *mockLayerStore) Mount(id string, parent layer.ChainID, label string, init layer.MountInit) (layer.RWLayer, error) {
+func (ls *mockLayerStore) CreateRWLayer(string, layer.ChainID, string, layer.MountInit) (layer.RWLayer, error) {
 	return nil, errors.New("not implemented")
 }
 
-func (ls *mockLayerStore) Unmount(id string) error {
-	return errors.New("not implemented")
+func (ls *mockLayerStore) GetRWLayer(string) (layer.RWLayer, error) {
+	return nil, errors.New("not implemented")
+
 }
 
-func (ls *mockLayerStore) DeleteMount(id string) ([]layer.Metadata, error) {
+func (ls *mockLayerStore) ReleaseRWLayer(layer.RWLayer) ([]layer.Metadata, error) {
 	return nil, errors.New("not implemented")
-}
 
-func (ls *mockLayerStore) Changes(id string) ([]archive.Change, error) {
-	return nil, errors.New("not implemented")
-}
-
-func (ls *mockLayerStore) Metadata(id string) (map[string]string, error) {
-	return nil, errors.New("not implemented")
 }
 
 type mockDownloadDescriptor struct {
diff --git a/layer/layer.go b/layer/layer.go
index eed5937e1e..f2fa5bc6c9 100644
--- a/layer/layer.go
+++ b/layer/layer.go
@@ -31,6 +31,11 @@ var (
 	// attempted on a mount layer which does not exist.
 	ErrMountDoesNotExist = errors.New("mount does not exist")
 
+	// ErrMountNameConflict is used when a mount is attempted
+	// to be created but there is already a mount with the name
+	// used for creation.
+	ErrMountNameConflict = errors.New("mount already exists with name")
+
 	// ErrActiveMount is used when an operation on a
 	// mount is attempted but the layer is still
 	// mounted and the operation cannot be performed.
@@ -103,18 +108,33 @@ type Layer interface {
 type RWLayer interface {
 	TarStreamer
 
-	// Path returns the filesystem path to the writable
-	// layer.
-	Path() (string, error)
+	// Name of mounted layer
+	Name() string
 
 	// Parent returns the layer which the writable
 	// layer was created from.
 	Parent() Layer
 
+	// Mount mounts the RWLayer and returns the filesystem path
+	// the to the writable layer.
+	Mount(mountLabel string) (string, error)
+
+	// Unmount unmounts the RWLayer. This should be called
+	// for every mount. If there are multiple mount calls
+	// this operation will only decrement the internal mount counter.
+	Unmount() error
+
 	// Size represents the size of the writable layer
 	// as calculated by the total size of the files
 	// changed in the mutable layer.
 	Size() (int64, error)
+
+	// Changes returns the set of changes for the mutable layer
+	// from the base layer.
+	Changes() ([]archive.Change, error)
+
+	// Metadata returns the low level metadata for the mutable layer
+	Metadata() (map[string]string, error)
 }
 
 // Metadata holds information about a
@@ -147,11 +167,9 @@ type Store interface {
 	Get(ChainID) (Layer, error)
 	Release(Layer) ([]Metadata, error)
 
-	Mount(id string, parent ChainID, label string, init MountInit) (RWLayer, error)
-	Unmount(id string) error
-	DeleteMount(id string) ([]Metadata, error)
-	Changes(id string) ([]archive.Change, error)
-	Metadata(id string) (map[string]string, error)
+	CreateRWLayer(id string, parent ChainID, mountLabel string, initFunc MountInit) (RWLayer, error)
+	GetRWLayer(id string) (RWLayer, error)
+	ReleaseRWLayer(RWLayer) ([]Metadata, error)
 }
 
 // MetadataTransaction represents functions for setting layer metadata
diff --git a/layer/layer_store.go b/layer/layer_store.go
index d67092f7d9..80dedfbfbc 100644
--- a/layer/layer_store.go
+++ b/layer/layer_store.go
@@ -5,7 +5,6 @@ import (
 	"fmt"
 	"io"
 	"io/ioutil"
-	"runtime"
 	"sync"
 
 	"github.com/Sirupsen/logrus"
@@ -144,6 +143,7 @@ func (ls *layerStore) loadMount(mount string) error {
 		mountID:    mountID,
 		initID:     initID,
 		layerStore: ls,
+		references: map[RWLayer]*referencedRWLayer{},
 	}
 
 	if parent != "" {
@@ -382,15 +382,114 @@ func (ls *layerStore) Release(l Layer) ([]Metadata, error) {
 	return ls.releaseLayer(layer)
 }
 
-func (ls *layerStore) mount(m *mountedLayer, mountLabel string) error {
-	dir, err := ls.driver.Get(m.mountID, mountLabel)
-	if err != nil {
-		return err
+func (ls *layerStore) CreateRWLayer(name string, parent ChainID, mountLabel string, initFunc MountInit) (RWLayer, error) {
+	ls.mountL.Lock()
+	defer ls.mountL.Unlock()
+	m, ok := ls.mounts[name]
+	if ok {
+		return nil, ErrMountNameConflict
 	}
-	m.path = dir
-	m.activityCount++
 
-	return nil
+	var err error
+	var pid string
+	var p *roLayer
+	if string(parent) != "" {
+		p = ls.get(parent)
+		if p == nil {
+			return nil, ErrLayerDoesNotExist
+		}
+		pid = p.cacheID
+
+		// Release parent chain if error
+		defer func() {
+			if err != nil {
+				ls.layerL.Lock()
+				ls.releaseLayer(p)
+				ls.layerL.Unlock()
+			}
+		}()
+	}
+
+	m = &mountedLayer{
+		name:       name,
+		parent:     p,
+		mountID:    ls.mountID(name),
+		layerStore: ls,
+		references: map[RWLayer]*referencedRWLayer{},
+	}
+
+	if initFunc != nil {
+		pid, err = ls.initMount(m.mountID, pid, mountLabel, initFunc)
+		if err != nil {
+			return nil, err
+		}
+		m.initID = pid
+	}
+
+	if err = ls.driver.Create(m.mountID, pid, ""); err != nil {
+		return nil, err
+	}
+
+	if err = ls.saveMount(m); err != nil {
+		return nil, err
+	}
+
+	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 {
+		return nil, ErrMountDoesNotExist
+	}
+
+	return mount.getReference(), nil
+}
+
+func (ls *layerStore) ReleaseRWLayer(l RWLayer) ([]Metadata, error) {
+	ls.mountL.Lock()
+	defer ls.mountL.Unlock()
+	m, ok := ls.mounts[l.Name()]
+	if !ok {
+		return []Metadata{}, nil
+	}
+
+	if err := m.deleteReference(l); err != nil {
+		return nil, err
+	}
+
+	if m.hasReferences() {
+		return []Metadata{}, nil
+	}
+
+	if err := ls.driver.Remove(m.mountID); err != nil {
+		logrus.Errorf("Error removing mounted layer %s: %s", m.name, err)
+		return nil, err
+	}
+
+	if m.initID != "" {
+		if err := ls.driver.Remove(m.initID); err != nil {
+			logrus.Errorf("Error removing init layer %s: %s", m.name, err)
+			return nil, err
+		}
+	}
+
+	if err := ls.store.RemoveMount(m.name); err != nil {
+		logrus.Errorf("Error removing mount metadata: %s: %s", m.name, err)
+		return nil, err
+	}
+
+	delete(ls.mounts, m.Name())
+
+	ls.layerL.Lock()
+	defer ls.layerL.Unlock()
+	if m.parent != nil {
+		return ls.releaseLayer(m.parent)
+	}
+
+	return []Metadata{}, nil
 }
 
 func (ls *layerStore) saveMount(mount *mountedLayer) error {
@@ -442,145 +541,6 @@ func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc Mou
 	return initID, nil
 }
 
-func (ls *layerStore) Mount(name string, parent ChainID, mountLabel string, initFunc MountInit) (l RWLayer, err error) {
-	ls.mountL.Lock()
-	defer ls.mountL.Unlock()
-	m, ok := ls.mounts[name]
-	if ok {
-		// Check if has path
-		if err := ls.mount(m, mountLabel); err != nil {
-			return nil, err
-		}
-		return m, nil
-	}
-
-	var pid string
-	var p *roLayer
-	if string(parent) != "" {
-		p = ls.get(parent)
-		if p == nil {
-			return nil, ErrLayerDoesNotExist
-		}
-		pid = p.cacheID
-
-		// Release parent chain if error
-		defer func() {
-			if err != nil {
-				ls.layerL.Lock()
-				ls.releaseLayer(p)
-				ls.layerL.Unlock()
-			}
-		}()
-	}
-
-	mountID := name
-	if runtime.GOOS != "windows" {
-		// windows has issues if container ID doesn't match mount ID
-		mountID = stringid.GenerateRandomID()
-	}
-
-	m = &mountedLayer{
-		name:       name,
-		parent:     p,
-		mountID:    mountID,
-		layerStore: ls,
-	}
-
-	if initFunc != nil {
-		pid, err = ls.initMount(m.mountID, pid, mountLabel, initFunc)
-		if err != nil {
-			return nil, err
-		}
-		m.initID = pid
-	}
-
-	if err = ls.driver.Create(m.mountID, pid, ""); err != nil {
-		return nil, err
-	}
-
-	if err = ls.saveMount(m); err != nil {
-		return nil, err
-	}
-
-	if err = ls.mount(m, mountLabel); err != nil {
-		return nil, err
-	}
-
-	return m, nil
-}
-
-func (ls *layerStore) Unmount(name string) error {
-	ls.mountL.Lock()
-	defer ls.mountL.Unlock()
-
-	m := ls.mounts[name]
-	if m == nil {
-		return ErrMountDoesNotExist
-	}
-
-	m.activityCount--
-
-	if err := ls.driver.Put(m.mountID); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func (ls *layerStore) DeleteMount(name string) ([]Metadata, error) {
-	ls.mountL.Lock()
-	defer ls.mountL.Unlock()
-
-	m := ls.mounts[name]
-	if m == nil {
-		return nil, ErrMountDoesNotExist
-	}
-	if m.activityCount > 0 {
-		return nil, ErrActiveMount
-	}
-
-	delete(ls.mounts, name)
-
-	if err := ls.driver.Remove(m.mountID); err != nil {
-		logrus.Errorf("Error removing mounted layer %s: %s", m.name, err)
-		return nil, err
-	}
-
-	if m.initID != "" {
-		if err := ls.driver.Remove(m.initID); err != nil {
-			logrus.Errorf("Error removing init layer %s: %s", m.name, err)
-			return nil, err
-		}
-	}
-
-	if err := ls.store.RemoveMount(m.name); err != nil {
-		logrus.Errorf("Error removing mount metadata: %s: %s", m.name, err)
-		return nil, err
-	}
-
-	ls.layerL.Lock()
-	defer ls.layerL.Unlock()
-	if m.parent != nil {
-		return ls.releaseLayer(m.parent)
-	}
-
-	return []Metadata{}, nil
-}
-
-func (ls *layerStore) Changes(name string) ([]archive.Change, error) {
-	ls.mountL.Lock()
-	m := ls.mounts[name]
-	ls.mountL.Unlock()
-	if m == nil {
-		return nil, ErrMountDoesNotExist
-	}
-	pid := m.initID
-	if pid == "" && m.parent != nil {
-		pid = m.parent.cacheID
-	}
-	return ls.driver.Changes(m.mountID, pid)
-}
-
 func (ls *layerStore) assembleTar(graphID string, metadata io.ReadCloser, size *int64) (io.ReadCloser, error) {
 	type diffPathDriver interface {
 		DiffPath(string) (string, func() error, error)
@@ -621,17 +581,6 @@ func (ls *layerStore) assembleTar(graphID string, metadata io.ReadCloser, size *
 	return pR, nil
 }
 
-// Metadata returns the low level metadata from the mount with the given name
-func (ls *layerStore) Metadata(name string) (map[string]string, error) {
-	ls.mountL.Lock()
-	m := ls.mounts[name]
-	ls.mountL.Unlock()
-	if m == nil {
-		return nil, ErrMountDoesNotExist
-	}
-	return ls.driver.GetMetadata(m.mountID)
-}
-
 type naiveDiffPathDriver struct {
 	graphdriver.Driver
 }
diff --git a/layer/layer_test.go b/layer/layer_test.go
index c3e4cf1d52..65cc15b2ae 100644
--- a/layer/layer_test.go
+++ b/layer/layer_test.go
@@ -82,12 +82,12 @@ type layerInit func(root string) error
 
 func createLayer(ls Store, parent ChainID, layerFunc layerInit) (Layer, error) {
 	containerID := stringid.GenerateRandomID()
-	mount, err := ls.Mount(containerID, parent, "", nil)
+	mount, err := ls.CreateRWLayer(containerID, parent, "", nil)
 	if err != nil {
 		return nil, err
 	}
 
-	path, err := mount.Path()
+	path, err := mount.Mount("")
 	if err != nil {
 		return nil, err
 	}
@@ -107,11 +107,11 @@ func createLayer(ls Store, parent ChainID, layerFunc layerInit) (Layer, error) {
 		return nil, err
 	}
 
-	if err := ls.Unmount(containerID); err != nil {
+	if err := mount.Unmount(); err != nil {
 		return nil, err
 	}
 
-	if _, err := ls.DeleteMount(containerID); err != nil {
+	if _, err := ls.ReleaseRWLayer(mount); err != nil {
 		return nil, err
 	}
 
@@ -171,6 +171,13 @@ func getCachedLayer(l Layer) *roLayer {
 	return l.(*roLayer)
 }
 
+func getMountLayer(l RWLayer) *mountedLayer {
+	if rl, ok := l.(*referencedRWLayer); ok {
+		return rl.mountedLayer
+	}
+	return l.(*mountedLayer)
+}
+
 func createMetadata(layers ...Layer) []Metadata {
 	metadata := make([]Metadata, len(layers))
 	for i := range layers {
@@ -270,12 +277,12 @@ func TestMountAndRegister(t *testing.T) {
 	size, _ := layer.Size()
 	t.Logf("Layer size: %d", size)
 
-	mount2, err := ls.Mount("new-test-mount", layer.ChainID(), "", nil)
+	mount2, err := ls.CreateRWLayer("new-test-mount", layer.ChainID(), "", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	path2, err := mount2.Path()
+	path2, err := mount2.Mount("")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -289,11 +296,11 @@ func TestMountAndRegister(t *testing.T) {
 		t.Fatalf("Wrong file data, expected %q, got %q", expected, string(b))
 	}
 
-	if err := ls.Unmount("new-test-mount"); err != nil {
+	if err := mount2.Unmount(); err != nil {
 		t.Fatal(err)
 	}
 
-	if _, err := ls.DeleteMount("new-test-mount"); err != nil {
+	if _, err := ls.ReleaseRWLayer(mount2); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -370,12 +377,12 @@ func TestStoreRestore(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	m, err := ls.Mount("some-mount_name", layer3.ChainID(), "", nil)
+	m, err := ls.CreateRWLayer("some-mount_name", layer3.ChainID(), "", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	path, err := m.Path()
+	path, err := m.Mount("")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -383,11 +390,14 @@ 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 := ls.Unmount("some-mount_name"); err != nil {
+	if err := m.Unmount(); err != nil {
 		t.Fatal(err)
 	}
 
+	assertActivityCount(t, m, 0)
+
 	ls2, err := NewStore(ls.(*layerStore).store, ls.(*layerStore).driver)
 	if err != nil {
 		t.Fatal(err)
@@ -400,18 +410,39 @@ func TestStoreRestore(t *testing.T) {
 
 	assertLayerEqual(t, layer3b, layer3)
 
-	// Mount again with same name, should already be loaded
-	m2, err := ls2.Mount("some-mount_name", layer3b.ChainID(), "", nil)
+	// Create again with same name, should return error
+	if _, err := ls2.CreateRWLayer("some-mount_name", layer3b.ChainID(), "", nil); err == nil {
+		t.Fatal("Expected error creating mount with same name")
+	} else if err != ErrMountNameConflict {
+		t.Fatal(err)
+	}
+
+	m2, err := ls2.GetRWLayer("some-mount_name")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	path2, err := m2.Path()
-	if err != nil {
+	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, 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)
 	}
 
-	b, err := ioutil.ReadFile(filepath.Join(path2, "testfile.txt"))
+	assertActivityCount(t, m2, 1)
+
+	b, err := ioutil.ReadFile(filepath.Join(path, "testfile.txt"))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -419,11 +450,19 @@ func TestStoreRestore(t *testing.T) {
 		t.Fatalf("Unexpected content %q, expected %q", string(b), expected)
 	}
 
-	if err := ls2.Unmount("some-mount_name"); err != nil {
+	if err := m2.Unmount(); err != nil {
 		t.Fatal(err)
 	}
 
-	if metadata, err := ls2.DeleteMount("some-mount_name"); err != nil {
+	assertActivityCount(t, m2, 0)
+
+	if metadata, err := ls2.ReleaseRWLayer(m2); err != nil {
+		t.Fatal(err)
+	} else if len(metadata) != 0 {
+		t.Fatalf("Unexpectedly deleted layers: %#v", metadata)
+	}
+
+	if metadata, err := ls2.ReleaseRWLayer(m2); err != nil {
 		t.Fatal(err)
 	} else if len(metadata) != 0 {
 		t.Fatalf("Unexpectedly deleted layers: %#v", metadata)
@@ -627,6 +666,13 @@ 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()
diff --git a/layer/layer_unix.go b/layer/layer_unix.go
new file mode 100644
index 0000000000..524b97e8d1
--- /dev/null
+++ b/layer/layer_unix.go
@@ -0,0 +1,9 @@
+// +build linux freebsd darwin
+
+package layer
+
+import "github.com/docker/docker/pkg/stringid"
+
+func (ls *layerStore) mountID(name string) string {
+	return stringid.GenerateRandomID()
+}
diff --git a/layer/layer_windows.go b/layer/layer_windows.go
index 369281448a..c40144d860 100644
--- a/layer/layer_windows.go
+++ b/layer/layer_windows.go
@@ -89,3 +89,8 @@ func (ls *layerStore) RegisterDiffID(graphID string, size int64) (Layer, error)
 
 	return layer.getReference(), nil
 }
+
+func (ls *layerStore) mountID(name string) string {
+	// windows has issues if container ID doesn't match mount ID
+	return name
+}
diff --git a/layer/migration.go b/layer/migration.go
index bc448a59a5..50dbcaec80 100644
--- a/layer/migration.go
+++ b/layer/migration.go
@@ -14,30 +14,33 @@ import (
 	"github.com/vbatts/tar-split/tar/storage"
 )
 
-func (ls *layerStore) MountByGraphID(name string, graphID string, parent ChainID) (l RWLayer, err error) {
+// CreateRWLayerByGraphID creates a RWLayer in the layer store using
+// the provided name with the given graphID. To get the RWLayer
+// after migration the layer may be retrieved by the given name.
+func (ls *layerStore) CreateRWLayerByGraphID(name string, graphID string, parent ChainID) (err error) {
 	ls.mountL.Lock()
 	defer ls.mountL.Unlock()
 	m, ok := ls.mounts[name]
 	if ok {
 		if m.parent.chainID != parent {
-			return nil, errors.New("name conflict, mismatched parent")
+			return errors.New("name conflict, mismatched parent")
 		}
 		if m.mountID != graphID {
-			return nil, errors.New("mount already exists")
+			return errors.New("mount already exists")
 		}
 
-		return m, nil
+		return nil
 	}
 
 	if !ls.driver.Exists(graphID) {
-		return nil, errors.New("graph ID does not exist")
+		return errors.New("graph ID does not exist")
 	}
 
 	var p *roLayer
 	if string(parent) != "" {
 		p = ls.get(parent)
 		if p == nil {
-			return nil, ErrLayerDoesNotExist
+			return ErrLayerDoesNotExist
 		}
 
 		// Release parent chain if error
@@ -57,6 +60,7 @@ func (ls *layerStore) MountByGraphID(name string, graphID string, parent ChainID
 		parent:     p,
 		mountID:    graphID,
 		layerStore: ls,
+		references: map[RWLayer]*referencedRWLayer{},
 	}
 
 	// Check for existing init layer
@@ -66,15 +70,10 @@ func (ls *layerStore) MountByGraphID(name string, graphID string, parent ChainID
 	}
 
 	if err = ls.saveMount(m); err != nil {
-		return nil, err
+		return err
 	}
 
-	// TODO: provide a mount label
-	if err = ls.mount(m, ""); err != nil {
-		return nil, err
-	}
-
-	return m, nil
+	return nil
 }
 
 func (ls *layerStore) migrateLayer(tx MetadataTransaction, tarDataFile string, layer *roLayer) error {
diff --git a/layer/migration_test.go b/layer/migration_test.go
index 11614ffde0..509e0c4eb5 100644
--- a/layer/migration_test.go
+++ b/layer/migration_test.go
@@ -303,12 +303,20 @@ func TestMountMigration(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	rwLayer1, err := ls.(*layerStore).MountByGraphID("migration-mount", containerID, layer1.ChainID())
+	if err := ls.(*layerStore).CreateRWLayerByGraphID("migration-mount", containerID, layer1.ChainID()); err != nil {
+		t.Fatal(err)
+	}
+
+	rwLayer1, err := ls.GetRWLayer("migration-mount")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	changes, err := ls.Changes("migration-mount")
+	if _, err := rwLayer1.Mount(""); err != nil {
+		t.Fatal(err)
+	}
+
+	changes, err := rwLayer1.Changes()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -341,39 +349,63 @@ func TestMountMigration(t *testing.T) {
 		Kind: archive.ChangeAdd,
 	})
 
-	if expectedCount := 1; rwLayer1.(*mountedLayer).activityCount != expectedCount {
-		t.Fatalf("Wrong activity count %d, expected %d", rwLayer1.(*mountedLayer).activityCount, expectedCount)
+	assertActivityCount(t, rwLayer1, 1)
+
+	if _, err := ls.CreateRWLayer("migration-mount", layer1.ChainID(), "", nil); err == nil {
+		t.Fatal("Expected error creating mount with same name")
+	} else if err != ErrMountNameConflict {
+		t.Fatal(err)
 	}
 
-	rwLayer2, err := ls.Mount("migration-mount", layer1.ChainID(), "", nil)
+	rwLayer2, err := ls.GetRWLayer("migration-mount")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if rwLayer1 != rwLayer2 {
-		t.Fatalf("Wrong rwlayer %v, expected %v", rwLayer2, rwLayer1)
+	if getMountLayer(rwLayer1) != getMountLayer(rwLayer2) {
+		t.Fatal("Expected same layer from get with same name as from migrate")
 	}
 
-	if expectedCount := 2; rwLayer2.(*mountedLayer).activityCount != expectedCount {
-		t.Fatalf("Wrong activity count %d, expected %d", rwLayer2.(*mountedLayer).activityCount, expectedCount)
+	if _, err := rwLayer2.Mount(""); err != nil {
+		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 {
 		t.Fatalf("Expected no layers to be deleted, deleted %#v", metadata)
 	}
 
-	if err := ls.Unmount("migration-mount"); err != nil {
+	if err := rwLayer1.Unmount(); err != nil {
 		t.Fatal(err)
 	}
-	if _, err := ls.DeleteMount("migration-mount"); err == nil {
+	assertActivityCount(t, rwLayer2, 2)
+	assertActivityCount(t, rwLayer1, 0)
+
+	if _, err := ls.ReleaseRWLayer(rwLayer1); err != nil {
+		t.Fatal(err)
+	}
+
+	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 := ls.Unmount("migration-mount"); err != nil {
+	if err := rwLayer2.Unmount(); err != nil {
 		t.Fatal(err)
 	}
-	metadata, err := ls.DeleteMount("migration-mount")
+	metadata, err := ls.ReleaseRWLayer(rwLayer2)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/layer/mount_test.go b/layer/mount_test.go
index 195f81193d..6889912e6d 100644
--- a/layer/mount_test.go
+++ b/layer/mount_test.go
@@ -27,12 +27,12 @@ func TestMountInit(t *testing.T) {
 		return initfile.ApplyFile(root)
 	}
 
-	m, err := ls.Mount("fun-mount", layer.ChainID(), "", mountInit)
+	m, err := ls.CreateRWLayer("fun-mount", layer.ChainID(), "", mountInit)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	path, err := m.Path()
+	path, err := m.Mount("")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -80,12 +80,12 @@ func TestMountSize(t *testing.T) {
 		return newTestFile("file-init", contentInit, 0777).ApplyFile(root)
 	}
 
-	m, err := ls.Mount("mount-size", layer.ChainID(), "", mountInit)
+	m, err := ls.CreateRWLayer("mount-size", layer.ChainID(), "", mountInit)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	path, err := m.Path()
+	path, err := m.Mount("")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -125,12 +125,12 @@ func TestMountChanges(t *testing.T) {
 		return initfile.ApplyFile(root)
 	}
 
-	m, err := ls.Mount("mount-changes", layer.ChainID(), "", mountInit)
+	m, err := ls.CreateRWLayer("mount-changes", layer.ChainID(), "", mountInit)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	path, err := m.Path()
+	path, err := m.Mount("")
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -155,7 +155,7 @@ func TestMountChanges(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	changes, err := ls.Changes("mount-changes")
+	changes, err := m.Changes()
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/layer/mounted_layer.go b/layer/mounted_layer.go
index 35f43609c6..b3d6568833 100644
--- a/layer/mounted_layer.go
+++ b/layer/mounted_layer.go
@@ -1,15 +1,20 @@
 package layer
 
-import "io"
+import (
+	"io"
+	"sync"
+
+	"github.com/docker/docker/pkg/archive"
+)
 
 type mountedLayer struct {
-	name          string
-	mountID       string
-	initID        string
-	parent        *roLayer
-	path          string
-	layerStore    *layerStore
-	activityCount int
+	name       string
+	mountID    string
+	initID     string
+	parent     *roLayer
+	layerStore *layerStore
+
+	references map[RWLayer]*referencedRWLayer
 }
 
 func (ml *mountedLayer) cacheParent() string {
@@ -30,11 +35,8 @@ func (ml *mountedLayer) TarStream() (io.ReadCloser, error) {
 	return archiver, nil
 }
 
-func (ml *mountedLayer) Path() (string, error) {
-	if ml.path == "" {
-		return "", ErrNotMounted
-	}
-	return ml.path, nil
+func (ml *mountedLayer) Name() string {
+	return ml.name
 }
 
 func (ml *mountedLayer) Parent() Layer {
@@ -47,6 +49,96 @@ func (ml *mountedLayer) Parent() Layer {
 	return nil
 }
 
+func (ml *mountedLayer) Mount(mountLabel string) (string, error) {
+	return ml.layerStore.driver.Get(ml.mountID, mountLabel)
+}
+
+func (ml *mountedLayer) Unmount() error {
+	return ml.layerStore.driver.Put(ml.mountID)
+}
+
 func (ml *mountedLayer) Size() (int64, error) {
 	return ml.layerStore.driver.DiffSize(ml.mountID, ml.cacheParent())
 }
+
+func (ml *mountedLayer) Changes() ([]archive.Change, error) {
+	return ml.layerStore.driver.Changes(ml.mountID, ml.cacheParent())
+}
+
+func (ml *mountedLayer) Metadata() (map[string]string, error) {
+	return ml.layerStore.driver.GetMetadata(ml.mountID)
+}
+
+func (ml *mountedLayer) getReference() RWLayer {
+	ref := &referencedRWLayer{
+		mountedLayer: ml,
+	}
+	ml.references[ref] = ref
+
+	return ref
+}
+
+func (ml *mountedLayer) hasReferences() bool {
+	return len(ml.references) > 0
+}
+
+func (ml *mountedLayer) deleteReference(ref RWLayer) error {
+	rl, ok := ml.references[ref]
+	if !ok {
+		return ErrLayerNotRetained
+	}
+
+	if err := rl.release(); err != nil {
+		return err
+	}
+	delete(ml.references, ref)
+
+	return nil
+}
+
+type referencedRWLayer struct {
+	*mountedLayer
+
+	activityL     sync.Mutex
+	activityCount int
+}
+
+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
+	}
+
+	rl.activityCount++
+	return rl.mountedLayer.Mount(mountLabel)
+}
+
+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--
+
+	return rl.mountedLayer.Unmount()
+}
diff --git a/migrate/v1/migratev1.go b/migrate/v1/migratev1.go
index a9110bca9c..c92c0f2107 100644
--- a/migrate/v1/migratev1.go
+++ b/migrate/v1/migratev1.go
@@ -24,8 +24,7 @@ type graphIDRegistrar interface {
 }
 
 type graphIDMounter interface {
-	MountByGraphID(string, string, layer.ChainID) (layer.RWLayer, error)
-	Unmount(string) error
+	CreateRWLayerByGraphID(string, string, layer.ChainID) error
 }
 
 const (
@@ -172,13 +171,7 @@ func migrateContainers(root string, ls graphIDMounter, is image.Store, imageMapp
 			return err
 		}
 
-		_, err = ls.MountByGraphID(id, id, img.RootFS.ChainID())
-		if err != nil {
-			return err
-		}
-
-		err = ls.Unmount(id)
-		if err != nil {
+		if err := ls.CreateRWLayerByGraphID(id, id, img.RootFS.ChainID()); err != nil {
 			return err
 		}
 
diff --git a/migrate/v1/migratev1_test.go b/migrate/v1/migratev1_test.go
index 067d04c382..5ee8206fdf 100644
--- a/migrate/v1/migratev1_test.go
+++ b/migrate/v1/migratev1_test.go
@@ -338,10 +338,9 @@ type mockMounter struct {
 	count  int
 }
 
-func (r *mockMounter) MountByGraphID(name string, graphID string, parent layer.ChainID) (layer.RWLayer, error) {
+func (r *mockMounter) CreateRWLayerByGraphID(name string, graphID string, parent layer.ChainID) error {
 	r.mounts = append(r.mounts, mountInfo{name, graphID, string(parent)})
-	r.count++
-	return nil, nil
+	return nil
 }
 func (r *mockMounter) Unmount(string) error {
 	r.count--