From 567de35df45b11785bf5fe6a171e9bb2679daaf5 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Fri, 20 Nov 2015 22:35:35 +0100 Subject: [PATCH] Save new packs in index atomically This commit fixes a situation reported by a user where two indexes contained information about the same pack without overlap, e.g.: Index 3e6a32 contained: { "id": "c02e3b", "blobs": [ { "id": "8114b1", "type": "data", "offset": 0, "length": 530107 } ] } And index 62da5f contained: { "id": "c02e3b", "blobs": [ { "id": "e344f8", "type": "data", "offset": 1975848, "length": 3426468 }, { "id": "939ed9", "type": "data", "offset": 530107, "length": 1445741 } ] } This commit adds all blobs in a pack in one atomic operation so that intermediate such as these do not happen. --- repository/index.go | 16 ++++++++++++++++ repository/repository.go | 5 +++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/repository/index.go b/repository/index.go index 4694c5d13..b75d69992 100644 --- a/repository/index.go +++ b/repository/index.go @@ -109,6 +109,22 @@ func (idx *Index) Store(blob PackedBlob) { idx.store(blob) } +// StoreBlobs saves information about the blobs to the index in one atomic transaction. +func (idx *Index) StoreBlobs(blobs []PackedBlob) { + idx.m.Lock() + defer idx.m.Unlock() + + if idx.final { + panic("store new item in finalized index") + } + + debug.Log("Index.StoreBlobs", "stored %d blobs", len(blobs)) + + for _, blob := range blobs { + idx.store(blob) + } +} + // Lookup queries the index for the blob ID and returns a PackedBlob. func (idx *Index) Lookup(id backend.ID) (pb PackedBlob, err error) { idx.m.Lock() diff --git a/repository/repository.go b/repository/repository.go index 752ad6b7a..2aeceae54 100644 --- a/repository/repository.go +++ b/repository/repository.go @@ -268,9 +268,9 @@ func (r *Repository) savePacker(p *pack.Packer) error { debug.Log("Repo.savePacker", "saved as %v", sid.Str()) // update blobs in the index + var packedBlobs []PackedBlob for _, b := range p.Blobs() { - debug.Log("Repo.savePacker", " updating blob %v to pack %v", b.ID.Str(), sid.Str()) - r.idx.Current().Store(PackedBlob{ + packedBlobs = append(packedBlobs, PackedBlob{ Type: b.Type, ID: b.ID, PackID: sid, @@ -279,6 +279,7 @@ func (r *Repository) savePacker(p *pack.Packer) error { }) r.idx.RemoveFromInFlight(b.ID) } + r.idx.Current().StoreBlobs(packedBlobs) return nil }