From 295cce278f827ddbfc91a97e21654663005ed98c Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Mon, 16 Oct 2017 11:57:50 -0700 Subject: [PATCH] Use single instance of snapshot and content stores Ensures that all callers and the garbage collector are using the same lock instances to prevent cleanup of objects during creation. Signed-off-by: Derek McGowan --- metadata/db.go | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/metadata/db.go b/metadata/db.go index 7ae293159..9629ccd30 100644 --- a/metadata/db.go +++ b/metadata/db.go @@ -37,8 +37,8 @@ const ( // datastores for content and snapshots. type DB struct { db *bolt.DB - ss map[string]snapshot.Snapshotter - cs content.Store + ss map[string]*snapshotter + cs *contentStore // wlock is used to protect access to the data structures during garbage // collection. While the wlock is held no writable transactions can be @@ -60,12 +60,19 @@ type DB struct { // NewDB creates a new metadata database using the provided // bolt database, content store, and snapshotters. func NewDB(db *bolt.DB, cs content.Store, ss map[string]snapshot.Snapshotter) *DB { - return &DB{ + m := &DB{ db: db, - ss: ss, - cs: cs, + ss: make(map[string]*snapshotter, len(ss)), dirtySS: map[string]struct{}{}, } + + // Initialize data stores + m.cs = newContentStore(m, cs) + for name, sn := range ss { + m.ss[name] = newSnapshotter(m, name, sn) + } + + return m } // Init ensures the database is at the correct version @@ -158,7 +165,7 @@ func (m *DB) ContentStore() content.Store { if m.cs == nil { return nil } - return newContentStore(m, m.cs) + return m.cs } // Snapshotter returns a namespaced content store for @@ -168,7 +175,7 @@ func (m *DB) Snapshotter(name string) snapshot.Snapshotter { if !ok { return nil } - return newSnapshotter(m, name, sn) + return sn } // View runs a readonly transaction on the metadata store. @@ -292,7 +299,7 @@ func (m *DB) cleanupSnapshotter(name string) { return } - err := newSnapshotter(m, name, sn).garbageCollect(ctx) + err := sn.garbageCollect(ctx) if err != nil { log.G(ctx).WithError(err).WithField("snapshotter", name).Warn("garbage collection failed") }