storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/xl-storage-format-v1.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2020 MinIO, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package cmd 18 19 import ( 20 "encoding/hex" 21 "encoding/json" 22 "fmt" 23 "time" 24 25 jsoniter "github.com/json-iterator/go" 26 27 "storj.io/minio/cmd/logger" 28 ) 29 30 // XL constants. 31 const ( 32 // XL metadata file carries per object metadata. 33 xlStorageFormatFileV1 = "xl.json" 34 ) 35 36 // Valid - tells us if the format is sane by validating 37 // format version and erasure coding information. 38 func (m *xlMetaV1Object) valid() bool { 39 return isXLMetaFormatValid(m.Version, m.Format) && 40 isXLMetaErasureInfoValid(m.Erasure.DataBlocks, m.Erasure.ParityBlocks) 41 } 42 43 // Verifies if the backend format metadata is sane by validating 44 // the version string and format style. 45 func isXLMetaFormatValid(version, format string) bool { 46 return ((version == xlMetaVersion101 || 47 version == xlMetaVersion100) && 48 format == xlMetaFormat) 49 } 50 51 // Verifies if the backend format metadata is sane by validating 52 // the ErasureInfo, i.e. data and parity blocks. 53 func isXLMetaErasureInfoValid(data, parity int) bool { 54 return ((data >= parity) && (data != 0) && (parity != 0)) 55 } 56 57 //go:generate msgp -file=$GOFILE -unexported 58 59 // A xlMetaV1Object represents `xl.meta` metadata header. 60 type xlMetaV1Object struct { 61 Version string `json:"version"` // Version of the current `xl.meta`. 62 Format string `json:"format"` // Format of the current `xl.meta`. 63 Stat StatInfo `json:"stat"` // Stat of the current object `xl.meta`. 64 // Erasure coded info for the current object `xl.meta`. 65 Erasure ErasureInfo `json:"erasure"` 66 // MinIO release tag for current object `xl.meta`. 67 Minio struct { 68 Release string `json:"release"` 69 } `json:"minio"` 70 // Metadata map for current object `xl.meta`. 71 Meta map[string]string `json:"meta,omitempty"` 72 // Captures all the individual object `xl.meta`. 73 Parts []ObjectPartInfo `json:"parts,omitempty"` 74 75 // Dummy values used for legacy use cases. 76 VersionID string `json:"versionId,omitempty"` 77 DataDir string `json:"dataDir,omitempty"` // always points to "legacy" 78 } 79 80 // StatInfo - carries stat information of the object. 81 type StatInfo struct { 82 Size int64 `json:"size"` // Size of the object `xl.meta`. 83 ModTime time.Time `json:"modTime"` // ModTime of the object `xl.meta`. 84 } 85 86 // ErasureInfo holds erasure coding and bitrot related information. 87 type ErasureInfo struct { 88 // Algorithm is the string representation of erasure-coding-algorithm 89 Algorithm string `json:"algorithm"` 90 // DataBlocks is the number of data blocks for erasure-coding 91 DataBlocks int `json:"data"` 92 // ParityBlocks is the number of parity blocks for erasure-coding 93 ParityBlocks int `json:"parity"` 94 // BlockSize is the size of one erasure-coded block 95 BlockSize int64 `json:"blockSize"` 96 // Index is the index of the current disk 97 Index int `json:"index"` 98 // Distribution is the distribution of the data and parity blocks 99 Distribution []int `json:"distribution"` 100 // Checksums holds all bitrot checksums of all erasure encoded blocks 101 Checksums []ChecksumInfo `json:"checksum,omitempty"` 102 } 103 104 // BitrotAlgorithm specifies a algorithm used for bitrot protection. 105 type BitrotAlgorithm uint 106 107 const ( 108 // SHA256 represents the SHA-256 hash function 109 SHA256 BitrotAlgorithm = 1 + iota 110 // HighwayHash256 represents the HighwayHash-256 hash function 111 HighwayHash256 112 // HighwayHash256S represents the Streaming HighwayHash-256 hash function 113 HighwayHash256S 114 // BLAKE2b512 represents the BLAKE2b-512 hash function 115 BLAKE2b512 116 ) 117 118 // DefaultBitrotAlgorithm is the default algorithm used for bitrot protection. 119 const ( 120 DefaultBitrotAlgorithm = HighwayHash256S 121 ) 122 123 // ObjectPartInfo Info of each part kept in the multipart metadata 124 // file after CompleteMultipartUpload() is called. 125 type ObjectPartInfo struct { 126 ETag string `json:"etag,omitempty"` 127 Number int `json:"number"` 128 Size int64 `json:"size"` 129 ActualSize int64 `json:"actualSize"` 130 } 131 132 // ChecksumInfo - carries checksums of individual scattered parts per disk. 133 type ChecksumInfo struct { 134 PartNumber int 135 Algorithm BitrotAlgorithm 136 Hash []byte 137 } 138 139 type checksumInfoJSON struct { 140 Name string `json:"name"` 141 Algorithm string `json:"algorithm"` 142 Hash string `json:"hash,omitempty"` 143 } 144 145 // MarshalJSON marshals the ChecksumInfo struct 146 func (c ChecksumInfo) MarshalJSON() ([]byte, error) { 147 info := checksumInfoJSON{ 148 Name: fmt.Sprintf("part.%d", c.PartNumber), 149 Algorithm: c.Algorithm.String(), 150 Hash: hex.EncodeToString(c.Hash), 151 } 152 return json.Marshal(info) 153 } 154 155 // UnmarshalJSON - custom checksum info unmarshaller 156 func (c *ChecksumInfo) UnmarshalJSON(data []byte) error { 157 var info checksumInfoJSON 158 var json = jsoniter.ConfigCompatibleWithStandardLibrary 159 if err := json.Unmarshal(data, &info); err != nil { 160 return err 161 } 162 sum, err := hex.DecodeString(info.Hash) 163 if err != nil { 164 return err 165 } 166 c.Algorithm = BitrotAlgorithmFromString(info.Algorithm) 167 c.Hash = sum 168 if _, err = fmt.Sscanf(info.Name, "part.%d", &c.PartNumber); err != nil { 169 return err 170 } 171 172 if !c.Algorithm.Available() { 173 logger.LogIf(GlobalContext, errBitrotHashAlgoInvalid) 174 return errBitrotHashAlgoInvalid 175 } 176 return nil 177 } 178 179 // constant and shouldn't be changed. 180 const legacyDataDir = "legacy" 181 182 func (m *xlMetaV1Object) ToFileInfo(volume, path string) (FileInfo, error) { 183 if !m.valid() { 184 return FileInfo{}, errFileCorrupt 185 } 186 fi := FileInfo{ 187 Volume: volume, 188 Name: path, 189 ModTime: m.Stat.ModTime, 190 Size: m.Stat.Size, 191 Metadata: m.Meta, 192 Parts: m.Parts, 193 Erasure: m.Erasure, 194 VersionID: m.VersionID, 195 DataDir: m.DataDir, 196 } 197 if st, ok := m.Meta[ReservedMetadataPrefixLower+"transition-status"]; ok { 198 fi.TransitionStatus = st 199 } 200 return fi, nil 201 } 202 203 // XL metadata constants. 204 const ( 205 // XL meta version. 206 xlMetaVersion101 = "1.0.1" 207 208 // XL meta version. 209 xlMetaVersion100 = "1.0.0" 210 211 // XL meta format string. 212 xlMetaFormat = "xl" 213 )