mirror of
https://github.com/minio/minio.git
synced 2025-04-17 01:10:29 -04:00
fix: delete dangling directories properly (#9222)
This commit is contained in:
parent
fdda5f98c6
commit
ba52a925f9
@ -483,7 +483,7 @@ func (xl xlObjects) healObject(ctx context.Context, bucket string, object string
|
|||||||
|
|
||||||
// healObjectDir - heals object directory specifically, this special call
|
// healObjectDir - heals object directory specifically, this special call
|
||||||
// is needed since we do not have a special backend format for directories.
|
// is needed since we do not have a special backend format for directories.
|
||||||
func (xl xlObjects) healObjectDir(ctx context.Context, bucket, object string, dryRun bool) (hr madmin.HealResultItem, err error) {
|
func (xl xlObjects) healObjectDir(ctx context.Context, bucket, object string, dryRun bool, remove bool) (hr madmin.HealResultItem, err error) {
|
||||||
storageDisks := xl.getDisks()
|
storageDisks := xl.getDisks()
|
||||||
|
|
||||||
// Initialize heal result object
|
// Initialize heal result object
|
||||||
@ -501,11 +501,10 @@ func (xl xlObjects) healObjectDir(ctx context.Context, bucket, object string, dr
|
|||||||
hr.After.Drives = make([]madmin.HealDriveInfo, len(storageDisks))
|
hr.After.Drives = make([]madmin.HealDriveInfo, len(storageDisks))
|
||||||
|
|
||||||
errs := statAllDirs(ctx, storageDisks, bucket, object)
|
errs := statAllDirs(ctx, storageDisks, bucket, object)
|
||||||
if isObjectDirDangling(errs) {
|
danglingObject := isObjectDirDangling(errs)
|
||||||
for i, err := range errs {
|
if danglingObject {
|
||||||
if err == nil {
|
if !dryRun && remove {
|
||||||
storageDisks[i].DeleteFile(bucket, object)
|
xl.deleteObject(ctx, bucket, object, hr.DataBlocks+1, true)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,8 +516,8 @@ func (xl xlObjects) healObjectDir(ctx context.Context, bucket, object string, dr
|
|||||||
}
|
}
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
hr.Before.Drives[i] = madmin.HealDriveInfo{State: madmin.DriveStateOk}
|
hr.Before.Drives[i] = madmin.HealDriveInfo{Endpoint: drive, State: madmin.DriveStateOk}
|
||||||
hr.After.Drives[i] = madmin.HealDriveInfo{State: madmin.DriveStateOk}
|
hr.After.Drives[i] = madmin.HealDriveInfo{Endpoint: drive, State: madmin.DriveStateOk}
|
||||||
case errDiskNotFound:
|
case errDiskNotFound:
|
||||||
hr.Before.Drives[i] = madmin.HealDriveInfo{State: madmin.DriveStateOffline}
|
hr.Before.Drives[i] = madmin.HealDriveInfo{State: madmin.DriveStateOffline}
|
||||||
hr.After.Drives[i] = madmin.HealDriveInfo{State: madmin.DriveStateOffline}
|
hr.After.Drives[i] = madmin.HealDriveInfo{State: madmin.DriveStateOffline}
|
||||||
@ -531,12 +530,11 @@ func (xl xlObjects) healObjectDir(ctx context.Context, bucket, object string, dr
|
|||||||
hr.After.Drives[i] = madmin.HealDriveInfo{Endpoint: drive, State: madmin.DriveStateCorrupt}
|
hr.After.Drives[i] = madmin.HealDriveInfo{Endpoint: drive, State: madmin.DriveStateCorrupt}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if dryRun {
|
if dryRun || danglingObject {
|
||||||
return hr, nil
|
return hr, nil
|
||||||
}
|
}
|
||||||
for i, err := range errs {
|
for i, err := range errs {
|
||||||
switch err {
|
if err == errVolumeNotFound || err == errFileNotFound {
|
||||||
case errVolumeNotFound, errFileNotFound:
|
|
||||||
// Bucket or prefix/directory not found
|
// Bucket or prefix/directory not found
|
||||||
merr := storageDisks[i].MakeVol(pathJoin(bucket, object))
|
merr := storageDisks[i].MakeVol(pathJoin(bucket, object))
|
||||||
switch merr {
|
switch merr {
|
||||||
@ -640,13 +638,22 @@ func statAllDirs(ctx context.Context, storageDisks []StorageAPI, bucket, prefix
|
|||||||
// if total disks - a combination of corrupted and missing
|
// if total disks - a combination of corrupted and missing
|
||||||
// files is lesser than N/2+1 number of disks.
|
// files is lesser than N/2+1 number of disks.
|
||||||
func isObjectDirDangling(errs []error) (ok bool) {
|
func isObjectDirDangling(errs []error) (ok bool) {
|
||||||
var notFoundDir int
|
var found int
|
||||||
|
var notFound int
|
||||||
|
var foundNotEmpty int
|
||||||
|
var otherFound int
|
||||||
for _, readErr := range errs {
|
for _, readErr := range errs {
|
||||||
if readErr == errFileNotFound {
|
if readErr == nil {
|
||||||
notFoundDir++
|
found++
|
||||||
|
} else if readErr == errFileNotFound || readErr == errVolumeNotFound {
|
||||||
|
notFound++
|
||||||
|
} else if readErr == errVolumeNotEmpty {
|
||||||
|
foundNotEmpty++
|
||||||
|
} else {
|
||||||
|
otherFound++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return notFoundDir > len(errs)/2
|
return found+foundNotEmpty+otherFound < notFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object is considered dangling/corrupted if any only
|
// Object is considered dangling/corrupted if any only
|
||||||
@ -709,7 +716,7 @@ func (xl xlObjects) HealObject(ctx context.Context, bucket, object string, opts
|
|||||||
|
|
||||||
// Healing directories handle it separately.
|
// Healing directories handle it separately.
|
||||||
if HasSuffix(object, SlashSeparator) {
|
if HasSuffix(object, SlashSeparator) {
|
||||||
return xl.healObjectDir(healCtx, bucket, object, opts.DryRun)
|
return xl.healObjectDir(healCtx, bucket, object, opts.DryRun, opts.Remove)
|
||||||
}
|
}
|
||||||
|
|
||||||
storageDisks := xl.getDisks()
|
storageDisks := xl.getDisks()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user