diff --git a/cmd/data-scanner.go b/cmd/data-scanner.go index 25b5c5cd0..1ad432991 100644 --- a/cmd/data-scanner.go +++ b/cmd/data-scanner.go @@ -797,42 +797,39 @@ type actionMeta struct { var applyActionsLogPrefix = color.Green("applyActions:") -// applyActions will apply lifecycle checks on to a scanned item. -// The resulting size on disk will always be returned. -// The metadata will be compared to consensus on the object layer before any changes are applied. -// If no metadata is supplied, -1 is returned if no action is taken. -func (i *scannerItem) applyActions(ctx context.Context, o ObjectLayer, meta actionMeta) (size int64) { +func (i *scannerItem) applyHealing(ctx context.Context, o ObjectLayer, meta actionMeta) (size int64) { + if i.debug { + if meta.oi.VersionID != "" { + console.Debugf(applyActionsLogPrefix+" heal checking: %v/%v v(%s)\n", i.bucket, i.objectPath(), meta.oi.VersionID) + } else { + console.Debugf(applyActionsLogPrefix+" heal checking: %v/%v\n", i.bucket, i.objectPath()) + } + } + healOpts := madmin.HealOpts{Remove: healDeleteDangling} + if meta.bitRotScan { + healOpts.ScanMode = madmin.HealDeepScan + } + res, err := o.HealObject(ctx, i.bucket, i.objectPath(), meta.oi.VersionID, healOpts) + if isErrObjectNotFound(err) || isErrVersionNotFound(err) { + return 0 + } + if err != nil && !errors.Is(err, NotImplemented{}) { + logger.LogIf(ctx, err) + return 0 + } + return res.ObjectSize +} + +func (i *scannerItem) applyLifecycle(ctx context.Context, o ObjectLayer, meta actionMeta) (applied bool, size int64) { size, err := meta.oi.GetActualSize() if i.debug { logger.LogIf(ctx, err) } - if i.heal { - if i.debug { - if meta.oi.VersionID != "" { - console.Debugf(applyActionsLogPrefix+" heal checking: %v/%v v(%s)\n", i.bucket, i.objectPath(), meta.oi.VersionID) - } else { - console.Debugf(applyActionsLogPrefix+" heal checking: %v/%v\n", i.bucket, i.objectPath()) - } - } - healOpts := madmin.HealOpts{Remove: healDeleteDangling} - if meta.bitRotScan { - healOpts.ScanMode = madmin.HealDeepScan - } - res, err := o.HealObject(ctx, i.bucket, i.objectPath(), meta.oi.VersionID, healOpts) - if isErrObjectNotFound(err) || isErrVersionNotFound(err) { - return 0 - } - if err != nil && !errors.Is(err, NotImplemented{}) { - logger.LogIf(ctx, err) - return 0 - } - size = res.ObjectSize - } if i.lifeCycle == nil { if i.debug { console.Debugf(applyActionsLogPrefix+" no lifecycle rules to apply: %q\n", i.objectPath()) } - return size + return false, size } versionID := meta.oi.VersionID @@ -866,7 +863,7 @@ func (i *scannerItem) applyActions(ctx context.Context, o ObjectLayer, meta acti if i.debug { console.Debugf(applyActionsLogPrefix+" object not expirable: %q\n", i.objectPath()) } - return size + return false, size } obj, err := o.GetObjectInfo(ctx, i.bucket, i.objectPath(), ObjectOptions{ @@ -878,19 +875,18 @@ func (i *scannerItem) applyActions(ctx context.Context, o ObjectLayer, meta acti if !obj.DeleteMarker { // if this is not a delete marker log and return // Do nothing - heal in the future. logger.LogIf(ctx, err) - return size + return false, size } case ObjectNotFound, VersionNotFound: // object not found or version not found return 0 - return 0 + return false, 0 default: // All other errors proceed. logger.LogIf(ctx, err) - return size + return false, size } } - var applied bool action = evalActionFromLifecycle(ctx, *i.lifeCycle, obj, i.debug) if action != lifecycle.NoneAction { applied = applyLifecycleAction(ctx, action, o, obj) @@ -899,9 +895,26 @@ func (i *scannerItem) applyActions(ctx context.Context, o ObjectLayer, meta acti if applied { switch action { case lifecycle.TransitionAction, lifecycle.TransitionVersionAction: - default: // for all lifecycle actions that remove data - return 0 + return true, size } + // For all other lifecycle actions that remove data + return true, 0 + } + + return false, size +} + +// applyActions will apply lifecycle checks on to a scanned item. +// The resulting size on disk will always be returned. +// The metadata will be compared to consensus on the object layer before any changes are applied. +// If no metadata is supplied, -1 is returned if no action is taken. +func (i *scannerItem) applyActions(ctx context.Context, o ObjectLayer, meta actionMeta) int64 { + applied, size := i.applyLifecycle(ctx, o, meta) + // For instance, an applied lifecycle means we remove/transitioned an object + // from the current deployment, which means we don't have to call healing + // routine even if we are asked to do via heal flag. + if !applied && i.heal { + size = i.applyHealing(ctx, o, meta) } return size }