diskpacked: don't append duplicate blobs.

Change-Id: I3adce39641458a67a3cdee09bb66411dd1111acd
This commit is contained in:
Brad Fitzpatrick 2014-02-07 10:46:35 -08:00
parent 97cd3926a0
commit 4afc5d32f0
2 changed files with 59 additions and 0 deletions

View File

@ -417,7 +417,18 @@ func (s *storage) ReceiveBlob(br blob.Ref, source io.Reader) (sbr blob.SizedRef,
if err != nil {
return
}
sbr = blob.SizedRef{Ref: br, Size: n}
// Check if it's a dup. Still accept it if the pack file on disk seems to be corrupt
// or truncated.
if m, err := s.meta(br); err == nil {
fi, err := os.Stat(s.filename(m.file))
if err == nil && fi.Size() >= m.offset+m.size {
return sbr, nil
}
}
err = s.append(sbr, &b)
return
}

View File

@ -19,10 +19,12 @@ package diskpacked
import (
"io/ioutil"
"os"
"strings"
"testing"
"camlistore.org/pkg/blobserver"
"camlistore.org/pkg/blobserver/storagetest"
"camlistore.org/pkg/test"
)
func newTempDiskpacked(t *testing.T) (sto blobserver.Storage, cleanup func()) {
@ -44,3 +46,49 @@ func newTempDiskpacked(t *testing.T) (sto blobserver.Storage, cleanup func()) {
func TestDiskpacked(t *testing.T) {
storagetest.Test(t, newTempDiskpacked)
}
func TestDoubleReceive(t *testing.T) {
sto, cleanup := newTempDiskpacked(t)
defer cleanup()
size := func(n int) int64 {
path := sto.(*storage).filename(n)
fi, err := os.Stat(path)
if err != nil {
t.Fatal(err)
}
return fi.Size()
}
const blobSize = 5 << 10
b := &test.Blob{Contents: strings.Repeat("a", blobSize)}
br := b.BlobRef()
_, err := blobserver.Receive(sto, br, b.Reader())
if err != nil {
t.Fatal(err)
}
if size(0) < blobSize {
t.Fatalf("size = %d; want at least %d", size(0), blobSize)
}
sto.(*storage).nextPack()
_, err = blobserver.Receive(sto, br, b.Reader())
if err != nil {
t.Fatal(err)
}
sizePostDup := size(1)
if sizePostDup >= blobSize {
t.Fatalf("size(pack1) = %d; appeared to double-write.", sizePostDup)
}
os.Remove(sto.(*storage).filename(0))
_, err = blobserver.Receive(sto, br, b.Reader())
if err != nil {
t.Fatal(err)
}
sizePostDelete := size(1)
if sizePostDelete < blobSize {
t.Fatalf("after packfile delete + reupload, not big enough. want size of a blob")
}
}