mirror of
https://github.com/minio/minio.git
synced 2025-11-07 12:52:58 -05:00
fallback on etags if they match when mtime is not same (#17424)
on "unversioned" buckets there are situations when successive concurrent I/O can lead to an inconsistent state() with mtime while the etag might be the same for the object on disk. in such a scenario it is possible for us to allow reading of the object since etag matches and if etag matches we are guaranteed that we have enough copies the object will be readable and same. This PR allows fallback in such scenarios.
This commit is contained in:
@@ -328,7 +328,7 @@ func (fi FileInfo) ObjectToPartOffset(ctx context.Context, offset int64) (partIn
|
||||
return 0, 0, InvalidRange{}
|
||||
}
|
||||
|
||||
func findFileInfoInQuorum(ctx context.Context, metaArr []FileInfo, modTime time.Time, quorum int) (FileInfo, error) {
|
||||
func findFileInfoInQuorum(ctx context.Context, metaArr []FileInfo, modTime time.Time, etag string, quorum int) (FileInfo, error) {
|
||||
// with less quorum return error.
|
||||
if quorum < 1 {
|
||||
return FileInfo{}, errErasureReadQuorum
|
||||
@@ -336,9 +336,17 @@ func findFileInfoInQuorum(ctx context.Context, metaArr []FileInfo, modTime time.
|
||||
metaHashes := make([]string, len(metaArr))
|
||||
h := sha256.New()
|
||||
for i, meta := range metaArr {
|
||||
if meta.IsValid() && meta.ModTime.Equal(modTime) {
|
||||
if !meta.IsValid() {
|
||||
continue
|
||||
}
|
||||
etagOnly := modTime.Equal(timeSentinel) && (etag != "" && etag == meta.Metadata["etag"])
|
||||
mtimeValid := meta.ModTime.Equal(modTime)
|
||||
if mtimeValid || etagOnly {
|
||||
fmt.Fprintf(h, "%v", meta.XLV1)
|
||||
fmt.Fprintf(h, "%v", meta.GetDataDir())
|
||||
if !etagOnly {
|
||||
// Verify dataDir is same only when mtime is valid and etag is not considered.
|
||||
fmt.Fprintf(h, "%v", meta.GetDataDir())
|
||||
}
|
||||
for _, part := range meta.Parts {
|
||||
fmt.Fprintf(h, "part.%d", part.Number)
|
||||
}
|
||||
@@ -408,8 +416,8 @@ func pickValidDiskTimeWithQuorum(metaArr []FileInfo, quorum int) time.Time {
|
||||
|
||||
// pickValidFileInfo - picks one valid FileInfo content and returns from a
|
||||
// slice of FileInfo.
|
||||
func pickValidFileInfo(ctx context.Context, metaArr []FileInfo, modTime time.Time, quorum int) (FileInfo, error) {
|
||||
return findFileInfoInQuorum(ctx, metaArr, modTime, quorum)
|
||||
func pickValidFileInfo(ctx context.Context, metaArr []FileInfo, modTime time.Time, etag string, quorum int) (FileInfo, error) {
|
||||
return findFileInfoInQuorum(ctx, metaArr, modTime, etag, quorum)
|
||||
}
|
||||
|
||||
// writeUniqueFileInfo - writes unique `xl.meta` content for each disk concurrently.
|
||||
|
||||
Reference in New Issue
Block a user