github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/xl-storage-free-version.go (about) 1 // Copyright (c) 2015-2021 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package cmd 19 20 import ( 21 "bytes" 22 "fmt" 23 24 "github.com/google/uuid" 25 "github.com/minio/minio/internal/bucket/lifecycle" 26 ) 27 28 const freeVersion = "free-version" 29 30 // InitFreeVersion creates a free-version to track the tiered-content of j. If j has 31 // no tiered content, it returns false. 32 func (j xlMetaV2Object) InitFreeVersion(fi FileInfo) (xlMetaV2Version, bool) { 33 if fi.SkipTierFreeVersion() { 34 return xlMetaV2Version{}, false 35 } 36 if status, ok := j.MetaSys[ReservedMetadataPrefixLower+TransitionStatus]; ok && bytes.Equal(status, []byte(lifecycle.TransitionComplete)) { 37 vID, err := uuid.Parse(fi.TierFreeVersionID()) 38 if err != nil { 39 panic(fmt.Errorf("Invalid Tier Object delete marker versionId %s %v", fi.TierFreeVersionID(), err)) 40 } 41 freeEntry := xlMetaV2Version{Type: DeleteType, WrittenByVersion: globalVersionUnix} 42 freeEntry.DeleteMarker = &xlMetaV2DeleteMarker{ 43 VersionID: vID, 44 ModTime: j.ModTime, // fi.ModTime may be empty 45 MetaSys: make(map[string][]byte), 46 } 47 48 freeEntry.DeleteMarker.MetaSys[ReservedMetadataPrefixLower+freeVersion] = []byte{} 49 tierKey := ReservedMetadataPrefixLower + TransitionTier 50 tierObjKey := ReservedMetadataPrefixLower + TransitionedObjectName 51 tierObjVIDKey := ReservedMetadataPrefixLower + TransitionedVersionID 52 53 for k, v := range j.MetaSys { 54 switch k { 55 case tierKey, tierObjKey, tierObjVIDKey: 56 freeEntry.DeleteMarker.MetaSys[k] = v 57 } 58 } 59 return freeEntry, true 60 } 61 return xlMetaV2Version{}, false 62 } 63 64 // FreeVersion returns true if j represents a free-version, false otherwise. 65 func (j xlMetaV2DeleteMarker) FreeVersion() bool { 66 _, ok := j.MetaSys[ReservedMetadataPrefixLower+freeVersion] 67 return ok 68 } 69 70 // FreeVersion returns true if j represents a free-version, false otherwise. 71 func (j xlMetaV2Version) FreeVersion() bool { 72 if j.Type == DeleteType { 73 return j.DeleteMarker.FreeVersion() 74 } 75 return false 76 } 77 78 // AddFreeVersion adds a free-version if needed for fi.VersionID version. 79 // Free-version will be added if fi.VersionID has transitioned. 80 func (x *xlMetaV2) AddFreeVersion(fi FileInfo) error { 81 var uv uuid.UUID 82 var err error 83 switch fi.VersionID { 84 case "", nullVersionID: 85 default: 86 uv, err = uuid.Parse(fi.VersionID) 87 if err != nil { 88 return err 89 } 90 } 91 92 for i, version := range x.versions { 93 if version.header.VersionID != uv || version.header.Type != ObjectType { 94 continue 95 } 96 // if uv has tiered content we add a 97 // free-version to track it for asynchronous 98 // deletion via scanner. 99 ver, err := x.getIdx(i) 100 if err != nil { 101 return err 102 } 103 104 if freeVersion, toFree := ver.ObjectV2.InitFreeVersion(fi); toFree { 105 return x.addVersion(freeVersion) 106 } 107 return nil 108 } 109 return nil 110 }