@ -156,8 +156,8 @@ type xlMetaV2Object struct {
PartETags [ ] string ` json:"PartETags" msg:"PartETags" ` // Part ETags
PartETags [ ] string ` json:"PartETags" msg:"PartETags" ` // Part ETags
PartSizes [ ] int64 ` json:"PartSizes" msg:"PartSizes" ` // Part Sizes
PartSizes [ ] int64 ` json:"PartSizes" msg:"PartSizes" ` // Part Sizes
PartActualSizes [ ] int64 ` json:"PartASizes,omitempty" msg:"PartASizes,omitempty" ` // Part ActualSizes (compression)
PartActualSizes [ ] int64 ` json:"PartASizes,omitempty" msg:"PartASizes,omitempty" ` // Part ActualSizes (compression)
StatS ize int64 ` json:"Size" msg:"Size" ` // Object version size
Size int64 ` json:"Size" msg:"Size" ` // Object version size
Stat ModTime int64 ` json:"MTime" msg:"MTime" ` // Object version modified time
ModTime int64 ` json:"MTime" msg:"MTime" ` // Object version modified time
MetaSys map [ string ] [ ] byte ` json:"MetaSys,omitempty" msg:"MetaSys,omitempty" ` // Object version internal metadata
MetaSys map [ string ] [ ] byte ` json:"MetaSys,omitempty" msg:"MetaSys,omitempty" ` // Object version internal metadata
MetaUser map [ string ] string ` json:"MetaUsr,omitempty" msg:"MetaUsr,omitempty" ` // Object version metadata set by user
MetaUser map [ string ] string ` json:"MetaUsr,omitempty" msg:"MetaUsr,omitempty" ` // Object version metadata set by user
}
}
@ -184,7 +184,7 @@ func (j xlMetaV2Version) Valid() bool {
j . ObjectV2 . ErasureAlgorithm . valid ( ) &&
j . ObjectV2 . ErasureAlgorithm . valid ( ) &&
j . ObjectV2 . BitrotChecksumAlgo . valid ( ) &&
j . ObjectV2 . BitrotChecksumAlgo . valid ( ) &&
isXLMetaErasureInfoValid ( j . ObjectV2 . ErasureM , j . ObjectV2 . ErasureN ) &&
isXLMetaErasureInfoValid ( j . ObjectV2 . ErasureM , j . ObjectV2 . ErasureN ) &&
j . ObjectV2 . Stat ModTime > 0
j . ObjectV2 . ModTime > 0
case DeleteType :
case DeleteType :
return j . DeleteMarker != nil &&
return j . DeleteMarker != nil &&
j . DeleteMarker . ModTime > 0
j . DeleteMarker . ModTime > 0
@ -271,8 +271,8 @@ func (z *xlMetaV2) AddVersion(fi FileInfo) error {
ObjectV2 : & xlMetaV2Object {
ObjectV2 : & xlMetaV2Object {
VersionID : uv ,
VersionID : uv ,
DataDir : dd ,
DataDir : dd ,
StatS ize : fi . Size ,
Size : fi . Size ,
Stat ModTime: fi . ModTime . UnixNano ( ) ,
ModTime : fi . ModTime . UnixNano ( ) ,
ErasureAlgorithm : ReedSolomon ,
ErasureAlgorithm : ReedSolomon ,
ErasureM : fi . Erasure . DataBlocks ,
ErasureM : fi . Erasure . DataBlocks ,
ErasureN : fi . Erasure . ParityBlocks ,
ErasureN : fi . Erasure . ParityBlocks ,
@ -373,8 +373,8 @@ func (j xlMetaV2Object) ToFileInfo(volume, path string) (FileInfo, error) {
fi := FileInfo {
fi := FileInfo {
Volume : volume ,
Volume : volume ,
Name : path ,
Name : path ,
Size : j . StatS ize ,
Size : j . Size ,
ModTime : time . Unix ( 0 , j . Stat ModTime) . UTC ( ) ,
ModTime : time . Unix ( 0 , j . ModTime ) . UTC ( ) ,
VersionID : versionID ,
VersionID : versionID ,
}
}
fi . Parts = make ( [ ] ObjectPartInfo , len ( j . PartNumbers ) )
fi . Parts = make ( [ ] ObjectPartInfo , len ( j . PartNumbers ) )
@ -463,7 +463,7 @@ func (z xlMetaV2) TotalSize() int64 {
for i := range z . Versions {
for i := range z . Versions {
switch z . Versions [ i ] . Type {
switch z . Versions [ i ] . Type {
case ObjectType :
case ObjectType :
total += z . Versions [ i ] . ObjectV2 . StatS ize
total += z . Versions [ i ] . ObjectV2 . Size
case LegacyType :
case LegacyType :
total += z . Versions [ i ] . ObjectV1 . Stat . Size
total += z . Versions [ i ] . ObjectV1 . Stat . Size
}
}
@ -488,8 +488,6 @@ func (z xlMetaV2) ListVersions(volume, path string) (versions []FileInfo, modTim
fi , err = version . DeleteMarker . ToFileInfo ( volume , path )
fi , err = version . DeleteMarker . ToFileInfo ( volume , path )
case LegacyType :
case LegacyType :
fi , err = version . ObjectV1 . ToFileInfo ( volume , path )
fi , err = version . ObjectV1 . ToFileInfo ( volume , path )
default :
continue
}
}
if err != nil {
if err != nil {
return nil , latestModTime , err
return nil , latestModTime , err
@ -498,12 +496,7 @@ func (z xlMetaV2) ListVersions(volume, path string) (versions []FileInfo, modTim
latestModTime = fi . ModTime
latestModTime = fi . ModTime
latestVersionID = fi . VersionID
latestVersionID = fi . VersionID
}
}
switch version . Type {
versions = append ( versions , fi )
case LegacyType :
fallthrough
case ObjectType , DeleteType :
versions = append ( versions , fi )
}
}
}
// We didn't find the version in delete markers so latest version
// We didn't find the version in delete markers so latest version
@ -521,44 +514,53 @@ func (z xlMetaV2) ListVersions(volume, path string) (versions []FileInfo, modTim
// ToFileInfo converts xlMetaV2 into a common FileInfo datastructure
// ToFileInfo converts xlMetaV2 into a common FileInfo datastructure
// for consumption across callers.
// for consumption across callers.
func ( z xlMetaV2 ) ToFileInfo ( volume , path , versionID string ) ( FileInfo , error ) {
func ( z xlMetaV2 ) ToFileInfo ( volume , path , versionID string ) ( fi FileInfo , err error ) {
var uv uuid . UUID
var uv uuid . UUID
if versionID != "" {
if versionID != "" {
uv , _ = uuid . Parse ( versionID )
uv , _ = uuid . Parse ( versionID )
}
}
var latestModTime time . Time
var latestIndex int
for i , version := range z . Versions {
if ! version . Valid ( ) {
logger . LogIf ( GlobalContext , fmt . Errorf ( "invalid version detected %#v" , version ) )
return FileInfo { } , errFileNotFound
}
var modTime time . Time
switch version . Type {
case ObjectType :
modTime = time . Unix ( 0 , version . ObjectV2 . ModTime )
case DeleteType :
modTime = time . Unix ( 0 , version . DeleteMarker . ModTime )
case LegacyType :
modTime = version . ObjectV1 . Stat . ModTime
}
if modTime . After ( latestModTime ) {
latestModTime = modTime
latestIndex = i
}
}
if versionID == "" {
if versionID == "" {
var latestModTime time . Time
if len ( z . Versions ) >= 1 {
var latestIndex int
if ! z . Versions [ latestIndex ] . Valid ( ) {
for i , version := range z . Versions {
logger . LogIf ( GlobalContext , fmt . Errorf ( "invalid version detected %#v" , z . Versions [ latestIndex ] ) )
if ! version . Valid ( ) {
logger . LogIf ( GlobalContext , fmt . Errorf ( "invalid version detected %#v" , version ) )
return FileInfo { } , errFileNotFound
return FileInfo { } , errFileNotFound
}
}
var modTime time . Time
switch version . Type {
case ObjectType :
modTime = time . Unix ( 0 , version . ObjectV2 . StatModTime )
case DeleteType :
modTime = time . Unix ( 0 , version . DeleteMarker . ModTime )
case LegacyType :
modTime = version . ObjectV1 . Stat . ModTime
default :
continue
}
if modTime . After ( latestModTime ) {
latestModTime = modTime
latestIndex = i
}
}
if len ( z . Versions ) >= 1 {
switch z . Versions [ latestIndex ] . Type {
switch z . Versions [ latestIndex ] . Type {
case ObjectType :
case ObjectType :
return z . Versions [ latestIndex ] . ObjectV2 . ToFileInfo ( volume , path )
fi , err = z . Versions [ latestIndex ] . ObjectV2 . ToFileInfo ( volume , path )
fi . IsLatest = true
return fi , err
case DeleteType :
case DeleteType :
return z . Versions [ latestIndex ] . DeleteMarker . ToFileInfo ( volume , path )
fi , err = z . Versions [ latestIndex ] . DeleteMarker . ToFileInfo ( volume , path )
fi . IsLatest = true
return fi , err
case LegacyType :
case LegacyType :
return z . Versions [ latestIndex ] . ObjectV1 . ToFileInfo ( volume , path )
fi , err = z . Versions [ latestIndex ] . ObjectV1 . ToFileInfo ( volume , path )
fi . IsLatest = true
return fi , err
}
}
}
}
return FileInfo { } , errFileNotFound
return FileInfo { } , errFileNotFound
@ -575,23 +577,22 @@ func (z xlMetaV2) ToFileInfo(volume, path, versionID string) (FileInfo, error) {
switch version . Type {
switch version . Type {
case ObjectType :
case ObjectType :
if bytes . Equal ( version . ObjectV2 . VersionID [ : ] , uv [ : ] ) {
if bytes . Equal ( version . ObjectV2 . VersionID [ : ] , uv [ : ] ) {
return version . ObjectV2 . ToFileInfo ( volume , path )
fi , err = version . ObjectV2 . ToFileInfo ( volume , path )
fi . IsLatest = latestModTime . Equal ( fi . ModTime )
return fi , err
}
}
case LegacyType :
case LegacyType :
if version . ObjectV1 . VersionID == versionID {
if version . ObjectV1 . VersionID == versionID {
return version . ObjectV1 . ToFileInfo ( volume , path )
fi , err = version . ObjectV1 . ToFileInfo ( volume , path )
fi . IsLatest = latestModTime . Equal ( fi . ModTime )
return fi , err
}
}
case DeleteType :
case DeleteType :
if bytes . Equal ( version . DeleteMarker . VersionID [ : ] , uv [ : ] ) {
if bytes . Equal ( version . DeleteMarker . VersionID [ : ] , uv [ : ] ) {
return version . DeleteMarker . ToFileInfo ( volume , path )
fi , err = version . DeleteMarker . ToFileInfo ( volume , path )
}
fi . IsLatest = latestModTime . Equal ( fi . ModTime )
default :
return fi , err
logger . LogIf ( GlobalContext , fmt . Errorf ( "unknown version type: %v" , version . Type ) )
if versionID == "" {
return FileInfo { } , errFileNotFound
}
}
return FileInfo { } , errFileVersionNotFound
}
}
}
}