mirror of
https://github.com/pgsty/minio.git
synced 2026-07-23 22:16:15 +03:00
Improve listing consistency with version merging (#13723)
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user