1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Revert "Add finer-grained locking for aufs"

This reverts commit f31014197c.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
This commit is contained in:
Brian Goff 2016-02-27 07:54:17 -05:00
parent df2b74188e
commit c2f7777603
2 changed files with 29 additions and 67 deletions

View file

@ -66,7 +66,6 @@ func init() {
type data struct { type data struct {
referenceCount int referenceCount int
path string path string
sync.Mutex
} }
// Driver contains information about the filesystem mounted. // Driver contains information about the filesystem mounted.
@ -77,7 +76,7 @@ type Driver struct {
root string root string
uidMaps []idtools.IDMap uidMaps []idtools.IDMap
gidMaps []idtools.IDMap gidMaps []idtools.IDMap
globalLock sync.Mutex // Protects concurrent modification to active sync.Mutex // Protects concurrent modification to active
active map[string]*data active map[string]*data
} }
@ -203,20 +202,7 @@ func (a *Driver) Exists(id string) bool {
// Create three folders for each id // Create three folders for each id
// mnt, layers, and diff // mnt, layers, and diff
func (a *Driver) Create(id, parent, mountLabel string) error { func (a *Driver) Create(id, parent, mountLabel string) error {
m := a.getActive(id) if err := a.createDirsFor(id); err != nil {
m.Lock()
var err error
defer func() {
a.globalLock.Lock()
if err != nil {
delete(a.active, id)
}
a.globalLock.Unlock()
m.Unlock()
}()
if err = a.createDirsFor(id); err != nil {
return err return err
} }
// Write the layers metadata // Write the layers metadata
@ -227,22 +213,23 @@ func (a *Driver) Create(id, parent, mountLabel string) error {
defer f.Close() defer f.Close()
if parent != "" { if parent != "" {
var ids []string ids, err := getParentIds(a.rootPath(), parent)
ids, err = getParentIds(a.rootPath(), parent)
if err != nil { if err != nil {
return err return err
} }
if _, err = fmt.Fprintln(f, parent); err != nil { if _, err := fmt.Fprintln(f, parent); err != nil {
return err return err
} }
for _, i := range ids { for _, i := range ids {
if _, err = fmt.Fprintln(f, i); err != nil { if _, err := fmt.Fprintln(f, i); err != nil {
return err return err
} }
} }
} }
a.Lock()
a.active[id] = &data{}
a.Unlock()
return nil return nil
} }
@ -266,10 +253,11 @@ func (a *Driver) createDirsFor(id string) error {
// Remove will unmount and remove the given id. // Remove will unmount and remove the given id.
func (a *Driver) Remove(id string) error { func (a *Driver) Remove(id string) error {
m := a.getActive(id) // Protect the a.active from concurrent access
m.Lock() a.Lock()
defer m.Unlock() defer a.Unlock()
m := a.active[id]
if m != nil { if m != nil {
if m.referenceCount > 0 { if m.referenceCount > 0 {
return nil return nil
@ -300,9 +288,9 @@ func (a *Driver) Remove(id string) error {
return err return err
} }
if m != nil { if m != nil {
a.globalLock.Lock() a.Lock()
delete(a.active, id) delete(a.active, id)
a.globalLock.Unlock() a.Unlock()
} }
return nil return nil
} }
@ -310,36 +298,21 @@ func (a *Driver) Remove(id string) error {
// Get returns the rootfs path for the id. // Get returns the rootfs path for the id.
// This will mount the dir at it's given path // This will mount the dir at it's given path
func (a *Driver) Get(id, mountLabel string) (string, error) { func (a *Driver) Get(id, mountLabel string) (string, error) {
m := a.getActive(id) // Protect the a.active from concurrent access
m.Lock() a.Lock()
defer m.Unlock() defer a.Unlock()
m := a.active[id]
if m == nil {
m = &data{}
a.active[id] = m
}
parents, err := a.getParentLayerPaths(id) parents, err := a.getParentLayerPaths(id)
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
return "", err return "", err
} }
var parentLocks []*data
a.globalLock.Lock()
for _, p := range parents {
parentM, exists := a.active[p]
if !exists {
parentM = &data{}
a.active[p] = parentM
}
parentLocks = append(parentLocks, parentM)
}
a.globalLock.Unlock()
for _, l := range parentLocks {
l.Lock()
}
defer func() {
for _, l := range parentLocks {
l.Unlock()
}
}()
// If a dir does not have a parent ( no layers )do not try to mount // If a dir does not have a parent ( no layers )do not try to mount
// just return the diff path to the data // just return the diff path to the data
m.path = path.Join(a.rootPath(), "diff", id) m.path = path.Join(a.rootPath(), "diff", id)
@ -355,24 +328,13 @@ func (a *Driver) Get(id, mountLabel string) (string, error) {
return m.path, nil return m.path, nil
} }
func (a *Driver) getActive(id string) *data {
// Protect the a.active from concurrent access
a.globalLock.Lock()
m, exists := a.active[id]
if !exists {
m = &data{}
a.active[id] = m
}
a.globalLock.Unlock()
return m
}
// Put unmounts and updates list of active mounts. // Put unmounts and updates list of active mounts.
func (a *Driver) Put(id string) error { func (a *Driver) Put(id string) error {
m := a.getActive(id) // Protect the a.active from concurrent access
m.Lock() a.Lock()
defer m.Unlock() defer a.Unlock()
m := a.active[id]
if m == nil { if m == nil {
// but it might be still here // but it might be still here
if a.Exists(id) { if a.Exists(id) {
@ -384,7 +346,6 @@ func (a *Driver) Put(id string) error {
} }
return nil return nil
} }
if count := m.referenceCount; count > 1 { if count := m.referenceCount; count > 1 {
m.referenceCount = count - 1 m.referenceCount = count - 1
} else { } else {
@ -393,6 +354,7 @@ func (a *Driver) Put(id string) error {
if ids != nil && len(ids) > 0 { if ids != nil && len(ids) > 0 {
a.unmount(m) a.unmount(m)
} }
delete(a.active, id)
} }
return nil return nil
} }

View file

@ -12,7 +12,7 @@ import (
// Unmount the target specified. // Unmount the target specified.
func Unmount(target string) error { func Unmount(target string) error {
if err := exec.Command("auplink", target, "flush").Run(); err != nil { if err := exec.Command("auplink", target, "flush").Run(); err != nil {
logrus.Errorf("Couldn't run auplink before unmount %s: %s", target, err) logrus.Errorf("Couldn't run auplink before unmount: %s", err)
} }
if err := syscall.Unmount(target, 0); err != nil { if err := syscall.Unmount(target, 0); err != nil {
return err return err