10 // A Volume is an interface that represents a Keep back-end volume.
12 type Volume interface {
13 Read(locator string) ([]byte, error)
14 Write(locator string, block []byte) error
17 // A UnixVolume is a Volume that writes to a locally mounted disk.
18 type UnixVolume struct {
19 root string // path to this volume
22 func (v *UnixVolume) Read(locator string) ([]byte, error) {
27 blockFilename := fmt.Sprintf("%s/%s/%s", v.root, locator[0:3], locator)
29 f, err = os.Open(blockFilename)
34 var buf = make([]byte, BLOCKSIZE)
35 nread, err = f.Read(buf)
37 log.Printf("%s: reading %s: %s\n", v.root, blockFilename, err)
41 // Double check the file checksum.
43 filehash := fmt.Sprintf("%x", md5.Sum(buf[:nread]))
44 if filehash != locator {
45 // TODO(twp): this condition probably represents a bad disk and
46 // should raise major alarm bells for an administrator: e.g.
47 // they should be sent directly to an event manager at high
48 // priority or logged as urgent problems.
50 log.Printf("%s: checksum mismatch: %s (actual locator %s)\n",
51 v.root, blockFilename, filehash)
52 return buf, CorruptError
56 return buf[:nread], nil