Improve listing consistency with version merging (#13723)

This commit is contained in:
Klaus Post
2021-12-02 11:29:16 -08:00
committed by GitHub
parent 8309ddd486
commit 3db931dc0e
16 changed files with 926 additions and 294 deletions
+58 -93
View File
@@ -18,122 +18,87 @@
package cmd
import (
"fmt"
jsoniter "github.com/json-iterator/go"
"github.com/minio/minio/internal/logger"
"github.com/zeebo/xxh3"
)
func getFileInfoVersions(xlMetaBuf []byte, volume, path string) (FileInfoVersions, error) {
if isXL2V1Format(xlMetaBuf) {
var versions []FileInfo
var err error
if buf, _ := isIndexedMetaV2(xlMetaBuf); buf != nil {
versions, err = buf.ListVersions(volume, path)
fivs, err := getAllFileInfoVersions(xlMetaBuf, volume, path)
if err != nil {
return fivs, err
}
n := 0
for _, fi := range fivs.Versions {
// Filter our tier object delete marker
if !fi.TierFreeVersion() {
fivs.Versions[n] = fi
n++
} else {
var xlMeta xlMetaV2
if err := xlMeta.Load(xlMetaBuf); err != nil {
return FileInfoVersions{}, err
}
versions, err = xlMeta.ListVersions(volume, path)
fivs.FreeVersions = append(fivs.FreeVersions, fi)
}
if err != nil || len(versions) == 0 {
}
fivs.Versions = fivs.Versions[:n]
// Update numversions
for i := range fivs.Versions {
fivs.Versions[i].NumVersions = n
}
return fivs, nil
}
func getAllFileInfoVersions(xlMetaBuf []byte, volume, path string) (FileInfoVersions, error) {
var versions []FileInfo
var err error
if buf, _ := isIndexedMetaV2(xlMetaBuf); buf != nil {
versions, err = buf.ListVersions(volume, path)
} else {
var xlMeta xlMetaV2
if err := xlMeta.LoadOrConvert(xlMetaBuf); err != nil {
return FileInfoVersions{}, err
}
var freeVersions []FileInfo
n := 0
for _, fi := range versions {
if fi.TierFreeVersion() {
freeVersions = append(freeVersions, fi)
continue
}
versions[n] = fi
n++
}
versions = versions[:n]
for _, ver := range versions {
ver.NumVersions = n
}
return FileInfoVersions{
Volume: volume,
Name: path,
Versions: versions,
FreeVersions: freeVersions,
LatestModTime: versions[0].ModTime,
}, nil
versions, err = xlMeta.ListVersions(volume, path)
}
xlMeta := &xlMetaV1Object{}
var json = jsoniter.ConfigCompatibleWithStandardLibrary
if err := json.Unmarshal(xlMetaBuf, xlMeta); err != nil {
return FileInfoVersions{}, errFileCorrupt
}
fi, err := xlMeta.ToFileInfo(volume, path)
if err != nil {
if err != nil || len(versions) == 0 {
return FileInfoVersions{}, err
}
fi.IsLatest = true // No versions so current version is latest.
fi.NumVersions = 1 // just this version
return FileInfoVersions{
Volume: volume,
Name: path,
Versions: []FileInfo{fi},
LatestModTime: fi.ModTime,
Versions: versions,
LatestModTime: versions[0].ModTime,
}, nil
}
func getFileInfo(xlMetaBuf []byte, volume, path, versionID string, data bool) (FileInfo, error) {
if isXL2V1Format(xlMetaBuf) {
var fi FileInfo
var err error
var inData xlMetaInlineData
if buf, data := isIndexedMetaV2(xlMetaBuf); buf != nil {
inData = data
fi, err = buf.ToFileInfo(volume, path, versionID)
} else {
var xlMeta xlMetaV2
if err := xlMeta.Load(xlMetaBuf); err != nil {
return FileInfo{}, err
}
inData = xlMeta.data
fi, err = xlMeta.ToFileInfo(volume, path, versionID)
var fi FileInfo
var err error
var inData xlMetaInlineData
if buf, data := isIndexedMetaV2(xlMetaBuf); buf != nil {
inData = data
fi, err = buf.ToFileInfo(volume, path, versionID)
} else {
var xlMeta xlMetaV2
if err := xlMeta.LoadOrConvert(xlMetaBuf); err != nil {
return FileInfo{}, err
}
if !data || err != nil {
return fi, err
}
versionID := fi.VersionID
if versionID == "" {
versionID = nullVersionID
}
fi.Data = inData.find(versionID)
if len(fi.Data) == 0 {
// PR #11758 used DataDir, preserve it
// for users who might have used master
// branch
fi.Data = inData.find(fi.DataDir)
}
return fi, nil
inData = xlMeta.data
fi, err = xlMeta.ToFileInfo(volume, path, versionID)
}
xlMeta := &xlMetaV1Object{}
var json = jsoniter.ConfigCompatibleWithStandardLibrary
if err := json.Unmarshal(xlMetaBuf, xlMeta); err != nil {
logger.LogIf(GlobalContext, fmt.Errorf("unable to unmarshal json object: %v", err))
return FileInfo{}, errFileCorrupt
if !data || err != nil {
return fi, err
}
fi, err := xlMeta.ToFileInfo(volume, path)
if err != nil {
return FileInfo{}, err
versionID = fi.VersionID
if versionID == "" {
versionID = nullVersionID
}
fi.XLV1 = true // indicates older version
fi.IsLatest = true // No versions so current version is latest.
return fi, err
fi.Data = inData.find(versionID)
if len(fi.Data) == 0 {
// PR #11758 used DataDir, preserve it
// for users who might have used master
// branch
fi.Data = inData.find(fi.DataDir)
}
return fi, nil
}
// getXLDiskLoc will return the pool/set/disk id if it can be located in the object layer.