mirror of
https://github.com/minio/minio.git
synced 2025-11-09 05:34:56 -05:00
feat: bring new HDD related performance enhancements (#18239)
Optionally allows customers to enable - Enable an external cache to catch GET/HEAD responses - Enable skipping disks that are slow to respond in GET/HEAD when we have already achieved a quorum
This commit is contained in:
@@ -1100,7 +1100,7 @@ func (s *xlStorage) moveToTrash(filePath string, recursive, force bool) error {
|
||||
targetPath := pathutil.Join(s.drivePath, minioMetaTmpDeletedBucket, pathUUID)
|
||||
|
||||
if recursive {
|
||||
if err := renameAll(filePath, targetPath, s.drivePath); err != nil {
|
||||
if err := renameAll(filePath, targetPath, pathutil.Join(s.drivePath, minioMetaTmpDeletedBucket)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
@@ -1127,8 +1127,19 @@ func (s *xlStorage) DeleteVersion(ctx context.Context, volume, path string, fi F
|
||||
})
|
||||
}
|
||||
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Validate file path length, before reading.
|
||||
filePath := pathJoin(volumeDir, path)
|
||||
if err = checkPathLength(filePath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var legacyJSON bool
|
||||
buf, err := s.ReadAll(ctx, volume, pathJoin(path, xlStorageFormatFile))
|
||||
buf, _, err := s.readAllData(ctx, volume, volumeDir, pathJoin(filePath, xlStorageFormatFile), false)
|
||||
if err != nil {
|
||||
if !errors.Is(err, errFileNotFound) {
|
||||
return err
|
||||
@@ -1161,11 +1172,6 @@ func (s *xlStorage) DeleteVersion(ctx context.Context, volume, path string, fi F
|
||||
return errFileNotFound
|
||||
}
|
||||
|
||||
volumeDir, err := s.getVolDir(volume)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if legacyJSON {
|
||||
// Delete the meta file, if there are no more versions the
|
||||
// top level parent is automatically removed.
|
||||
@@ -1217,12 +1223,6 @@ func (s *xlStorage) DeleteVersion(ctx context.Context, volume, path string, fi F
|
||||
return s.WriteAll(ctx, volume, pathJoin(path, xlStorageFormatFile), buf)
|
||||
}
|
||||
|
||||
// No more versions, this is the last version purge everything.
|
||||
filePath := pathJoin(volumeDir, path)
|
||||
if err = checkPathLength(filePath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.deleteFile(volumeDir, filePath, true, false)
|
||||
}
|
||||
|
||||
@@ -1371,10 +1371,15 @@ func (s *xlStorage) renameLegacyMetadata(volumeDir, path string) (err error) {
|
||||
}
|
||||
|
||||
func (s *xlStorage) readRaw(ctx context.Context, volume, volumeDir, filePath string, readData bool) (buf []byte, dmTime time.Time, err error) {
|
||||
if filePath == "" {
|
||||
return nil, dmTime, errFileNotFound
|
||||
}
|
||||
|
||||
xlPath := pathJoin(filePath, xlStorageFormatFile)
|
||||
if readData {
|
||||
buf, dmTime, err = s.readAllData(ctx, volume, volumeDir, pathJoin(filePath, xlStorageFormatFile), true)
|
||||
buf, dmTime, err = s.readAllData(ctx, volume, volumeDir, xlPath, true)
|
||||
} else {
|
||||
buf, dmTime, err = s.readMetadataWithDMTime(ctx, pathJoin(filePath, xlStorageFormatFile))
|
||||
buf, dmTime, err = s.readMetadataWithDMTime(ctx, xlPath)
|
||||
if err != nil {
|
||||
if osIsNotExist(err) {
|
||||
if !skipAccessChecks(volume) {
|
||||
@@ -1387,18 +1392,21 @@ func (s *xlStorage) readRaw(ctx context.Context, volume, volumeDir, filePath str
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if err == errFileNotFound {
|
||||
buf, dmTime, err = s.readAllData(ctx, volume, volumeDir, pathJoin(filePath, xlStorageFormatFileV1), true)
|
||||
if err != nil {
|
||||
return nil, time.Time{}, err
|
||||
}
|
||||
} else {
|
||||
s.RLock()
|
||||
legacy := s.formatLegacy
|
||||
s.RUnlock()
|
||||
|
||||
if err != nil && errors.Is(err, errFileNotFound) && legacy {
|
||||
buf, dmTime, err = s.readAllData(ctx, volume, volumeDir, pathJoin(filePath, xlStorageFormatFileV1), true)
|
||||
if err != nil {
|
||||
return nil, time.Time{}, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(buf) == 0 {
|
||||
if err != nil {
|
||||
return nil, time.Time{}, err
|
||||
}
|
||||
return nil, time.Time{}, errFileNotFound
|
||||
}
|
||||
|
||||
@@ -1440,6 +1448,7 @@ func (s *xlStorage) ReadVersion(ctx context.Context, volume, path, versionID str
|
||||
if err != nil {
|
||||
return fi, err
|
||||
}
|
||||
|
||||
// Validate file path length, before reading.
|
||||
filePath := pathJoin(volumeDir, path)
|
||||
if err = checkPathLength(filePath); err != nil {
|
||||
@@ -1532,6 +1541,10 @@ func (s *xlStorage) ReadVersion(ctx context.Context, volume, path, versionID str
|
||||
}
|
||||
|
||||
func (s *xlStorage) readAllData(ctx context.Context, volume, volumeDir string, filePath string, sync bool) (buf []byte, dmTime time.Time, err error) {
|
||||
if filePath == "" {
|
||||
return nil, dmTime, errFileNotFound
|
||||
}
|
||||
|
||||
if contextCanceled(ctx) {
|
||||
return nil, time.Time{}, ctx.Err()
|
||||
}
|
||||
@@ -1593,7 +1606,7 @@ func (s *xlStorage) readAllData(ctx context.Context, volume, volumeDir string, f
|
||||
// Get size for precise allocation.
|
||||
stat, err := f.Stat()
|
||||
if err != nil {
|
||||
buf, err = io.ReadAll(diskHealthReader(ctx, r))
|
||||
buf, err = io.ReadAll(r)
|
||||
return buf, dmTime, osErrToFileErr(err)
|
||||
}
|
||||
if stat.IsDir() {
|
||||
@@ -1612,7 +1625,7 @@ func (s *xlStorage) readAllData(ctx context.Context, volume, volumeDir string, f
|
||||
dr.SmallFile = sz <= xioutil.BlockSizeSmall*2
|
||||
}
|
||||
// Read file...
|
||||
_, err = io.ReadFull(diskHealthReader(ctx, r), buf)
|
||||
_, err = io.ReadFull(r, buf)
|
||||
|
||||
return buf, stat.ModTime().UTC(), osErrToFileErr(err)
|
||||
}
|
||||
@@ -1641,7 +1654,7 @@ func (s *xlStorage) ReadAll(ctx context.Context, volume string, path string) (bu
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf, _, err = s.readAllData(ctx, volume, volumeDir, filePath, true)
|
||||
buf, _, err = s.readAllData(ctx, volume, volumeDir, filePath, false)
|
||||
return buf, err
|
||||
}
|
||||
|
||||
@@ -2225,10 +2238,10 @@ func (s *xlStorage) Delete(ctx context.Context, volume string, path string, dele
|
||||
|
||||
func skipAccessChecks(volume string) (ok bool) {
|
||||
for _, prefix := range []string{
|
||||
minioMetaBucket,
|
||||
minioMetaMultipartBucket,
|
||||
minioMetaTmpDeletedBucket,
|
||||
minioMetaTmpBucket,
|
||||
minioMetaMultipartBucket,
|
||||
minioMetaBucket,
|
||||
} {
|
||||
if strings.HasPrefix(volume, prefix) {
|
||||
return true
|
||||
@@ -2408,7 +2421,7 @@ func (s *xlStorage) RenameData(ctx context.Context, srcVolume, srcPath string, f
|
||||
}
|
||||
|
||||
// legacy data dir means its old content, honor system umask.
|
||||
if err = mkdirAll(legacyDataPath, 0o777, s.drivePath); err != nil {
|
||||
if err = mkdirAll(legacyDataPath, 0o777, dstVolumeDir); err != nil {
|
||||
// any failed mkdir-calls delete them.
|
||||
s.deleteFile(dstVolumeDir, legacyDataPath, true, false)
|
||||
return 0, osErrToFileErr(err)
|
||||
@@ -2526,7 +2539,7 @@ func (s *xlStorage) RenameData(ctx context.Context, srcVolume, srcPath string, f
|
||||
// on a versioned bucket.
|
||||
s.moveToTrash(legacyDataPath, true, false)
|
||||
}
|
||||
if err = renameAll(srcDataPath, dstDataPath, s.drivePath); err != nil {
|
||||
if err = renameAll(srcDataPath, dstDataPath, dstVolumeDir); err != nil {
|
||||
if legacyPreserved {
|
||||
// Any failed rename calls un-roll previous transaction.
|
||||
s.deleteFile(dstVolumeDir, legacyDataPath, true, false)
|
||||
@@ -2537,7 +2550,7 @@ func (s *xlStorage) RenameData(ctx context.Context, srcVolume, srcPath string, f
|
||||
}
|
||||
|
||||
// Commit meta-file
|
||||
if err = renameAll(srcFilePath, dstFilePath, s.drivePath); err != nil {
|
||||
if err = renameAll(srcFilePath, dstFilePath, dstVolumeDir); err != nil {
|
||||
if legacyPreserved {
|
||||
// Any failed rename calls un-roll previous transaction.
|
||||
s.deleteFile(dstVolumeDir, legacyDataPath, true, false)
|
||||
@@ -2647,7 +2660,7 @@ func (s *xlStorage) RenameFile(ctx context.Context, srcVolume, srcPath, dstVolum
|
||||
}
|
||||
}
|
||||
|
||||
if err = renameAll(srcFilePath, dstFilePath, s.drivePath); err != nil {
|
||||
if err = renameAll(srcFilePath, dstFilePath, dstVolumeDir); err != nil {
|
||||
if isSysErrNotEmpty(err) || isSysErrNotDir(err) {
|
||||
return errFileAccessDenied
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user