You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
2.9 KiB
125 lines
2.9 KiB
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"io"
|
|
"path"
|
|
"sort"
|
|
)
|
|
|
|
const (
|
|
fsMetaJSONFile = "fs.json"
|
|
)
|
|
|
|
// A fsMetaV1 represents a metadata header mapping keys to sets of values.
|
|
type fsMetaV1 struct {
|
|
Version string `json:"version"`
|
|
Format string `json:"format"`
|
|
Minio struct {
|
|
Release string `json:"release"`
|
|
} `json:"minio"`
|
|
Parts []objectPartInfo `json:"parts,omitempty"`
|
|
}
|
|
|
|
// ReadFrom - read from implements io.ReaderFrom interface for
|
|
// unmarshalling fsMetaV1.
|
|
func (m *fsMetaV1) ReadFrom(reader io.Reader) (n int64, err error) {
|
|
var buffer bytes.Buffer
|
|
n, err = buffer.ReadFrom(reader)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
err = json.Unmarshal(buffer.Bytes(), m)
|
|
return n, err
|
|
}
|
|
|
|
// WriteTo - write to implements io.WriterTo interface for marshalling fsMetaV1.
|
|
func (m fsMetaV1) WriteTo(writer io.Writer) (n int64, err error) {
|
|
metadataBytes, err := json.Marshal(m)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
p, err := writer.Write(metadataBytes)
|
|
return int64(p), err
|
|
}
|
|
|
|
// ObjectPartIndex - returns the index of matching object part number.
|
|
func (m fsMetaV1) ObjectPartIndex(partNumber int) (partIndex int) {
|
|
for i, part := range m.Parts {
|
|
if partNumber == part.Number {
|
|
partIndex = i
|
|
return partIndex
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// AddObjectPart - add a new object part in order.
|
|
func (m *fsMetaV1) AddObjectPart(partNumber int, partName string, partETag string, partSize int64) {
|
|
partInfo := objectPartInfo{
|
|
Number: partNumber,
|
|
Name: partName,
|
|
ETag: partETag,
|
|
Size: partSize,
|
|
}
|
|
|
|
// Update part info if it already exists.
|
|
for i, part := range m.Parts {
|
|
if partNumber == part.Number {
|
|
m.Parts[i] = partInfo
|
|
return
|
|
}
|
|
}
|
|
|
|
// Proceed to include new part info.
|
|
m.Parts = append(m.Parts, partInfo)
|
|
|
|
// Parts in fsMeta should be in sorted order by part number.
|
|
sort.Sort(byPartNumber(m.Parts))
|
|
}
|
|
|
|
// readFSMetadata - returns the object metadata `fs.json` content.
|
|
func (fs fsObjects) readFSMetadata(bucket, object string) (fsMeta fsMetaV1, err error) {
|
|
r, err := fs.storage.ReadFile(bucket, path.Join(object, fsMetaJSONFile), int64(0))
|
|
if err != nil {
|
|
return fsMetaV1{}, err
|
|
}
|
|
defer r.Close()
|
|
_, err = fsMeta.ReadFrom(r)
|
|
if err != nil {
|
|
return fsMetaV1{}, err
|
|
}
|
|
return fsMeta, nil
|
|
}
|
|
|
|
// newFSMetaV1 - initializes new fsMetaV1.
|
|
func newFSMetaV1() (fsMeta fsMetaV1) {
|
|
fsMeta = fsMetaV1{}
|
|
fsMeta.Version = "1"
|
|
fsMeta.Format = "fs"
|
|
fsMeta.Minio.Release = minioReleaseTag
|
|
return fsMeta
|
|
}
|
|
|
|
// writeFSMetadata - writes `fs.json` metadata.
|
|
func (fs fsObjects) writeFSMetadata(bucket, prefix string, fsMeta fsMetaV1) error {
|
|
w, err := fs.storage.CreateFile(bucket, path.Join(prefix, fsMetaJSONFile))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = fsMeta.WriteTo(w)
|
|
if err != nil {
|
|
if mErr := safeCloseAndRemove(w); mErr != nil {
|
|
return mErr
|
|
}
|
|
return err
|
|
}
|
|
if err = w.Close(); err != nil {
|
|
if mErr := safeCloseAndRemove(w); mErr != nil {
|
|
return mErr
|
|
}
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|