@@ -2367,6 +2367,41 @@ func (s *xlStorage) AppendFile(ctx context.Context, volume string, path string,
2367
2367
return nil
2368
2368
}
2369
2369
2370
+ // checkPart is a light check of an existing and size of a part, without doing a bitrot operation
2371
+ // For any unexpected error, return checkPartUnknown (zero)
2372
+ func (s * xlStorage ) checkPart (volumeDir , path , dataDir string , partNum int , expectedSize int64 , skipAccessCheck bool ) (resp int ) {
2373
+ partPath := pathJoin (path , dataDir , fmt .Sprintf ("part.%d" , partNum ))
2374
+ filePath := pathJoin (volumeDir , partPath )
2375
+ st , err := Lstat (filePath )
2376
+ if err != nil {
2377
+ if osIsNotExist (err ) {
2378
+ if ! skipAccessCheck {
2379
+ // Stat a volume entry.
2380
+ if verr := Access (volumeDir ); verr != nil {
2381
+ if osIsNotExist (verr ) {
2382
+ resp = checkPartVolumeNotFound
2383
+ }
2384
+ return
2385
+ }
2386
+ }
2387
+ }
2388
+ if osErrToFileErr (err ) == errFileNotFound {
2389
+ resp = checkPartFileNotFound
2390
+ }
2391
+ return
2392
+ }
2393
+ if st .Mode ().IsDir () {
2394
+ resp = checkPartFileNotFound
2395
+ return
2396
+ }
2397
+ // Check if shard is truncated.
2398
+ if st .Size () < expectedSize {
2399
+ resp = checkPartFileCorrupt
2400
+ return
2401
+ }
2402
+ return checkPartSuccess
2403
+ }
2404
+
2370
2405
// CheckParts check if path has necessary parts available.
2371
2406
func (s * xlStorage ) CheckParts (ctx context.Context , volume string , path string , fi FileInfo ) (* CheckPartsResp , error ) {
2372
2407
volumeDir , err := s .getVolDir (volume )
@@ -2385,36 +2420,12 @@ func (s *xlStorage) CheckParts(ctx context.Context, volume string, path string,
2385
2420
}
2386
2421
2387
2422
for i , part := range fi .Parts {
2388
- partPath := pathJoin ( path , fi . DataDir , fmt . Sprintf ( "part.%d" , part . Number ))
2389
- filePath := pathJoin (volumeDir , partPath )
2390
- st , err := Lstat ( filePath )
2423
+ resp . Results [ i ], err = xioutil . WithDeadline [ int ]( ctx , globalDriveConfig . GetMaxTimeout (), func ( ctx context. Context ) ( int , error ) {
2424
+ return s . checkPart (volumeDir , path , fi . DataDir , part . Number , fi . Erasure . ShardFileSize ( part . Size ), skipAccessChecks ( volume )), nil
2425
+ } )
2391
2426
if err != nil {
2392
- if osIsNotExist (err ) {
2393
- if ! skipAccessChecks (volume ) {
2394
- // Stat a volume entry.
2395
- if verr := Access (volumeDir ); verr != nil {
2396
- if osIsNotExist (verr ) {
2397
- resp .Results [i ] = checkPartVolumeNotFound
2398
- }
2399
- continue
2400
- }
2401
- }
2402
- }
2403
- if osErrToFileErr (err ) == errFileNotFound {
2404
- resp .Results [i ] = checkPartFileNotFound
2405
- }
2406
- continue
2407
- }
2408
- if st .Mode ().IsDir () {
2409
- resp .Results [i ] = checkPartFileNotFound
2410
- continue
2411
- }
2412
- // Check if shard is truncated.
2413
- if st .Size () < fi .Erasure .ShardFileSize (part .Size ) {
2414
- resp .Results [i ] = checkPartFileCorrupt
2415
- continue
2427
+ return nil , err
2416
2428
}
2417
- resp .Results [i ] = checkPartSuccess
2418
2429
}
2419
2430
2420
2431
return & resp , nil
@@ -2546,17 +2557,7 @@ func (s *xlStorage) Delete(ctx context.Context, volume string, path string, dele
2546
2557
}
2547
2558
2548
2559
func skipAccessChecks (volume string ) (ok bool ) {
2549
- for _ , prefix := range []string {
2550
- minioMetaTmpDeletedBucket ,
2551
- minioMetaTmpBucket ,
2552
- minioMetaMultipartBucket ,
2553
- minioMetaBucket ,
2554
- } {
2555
- if strings .HasPrefix (volume , prefix ) {
2556
- return true
2557
- }
2558
- }
2559
- return ok
2560
+ return strings .HasPrefix (volume , minioMetaBucket )
2560
2561
}
2561
2562
2562
2563
// RenameData - rename source path to destination path atomically, metadata and data directory.
0 commit comments