diff --git a/copy.go b/copy.go index 0d99a03..d87676e 100644 --- a/copy.go +++ b/copy.go @@ -121,15 +121,22 @@ func (c *Copyer) write(ctx context.Context, job *writeJob, ch chan<- *baseJob, c continue } - if err := os.MkdirAll(path.Dir(target), os.ModePerm); err != nil { - job.fail(target, fmt.Errorf("mkdir dst dir fail, %w", mappingError(err))) + if err := mappingError(os.MkdirAll(path.Dir(target), os.ModePerm)); err != nil { + if checkErrorAbort(err) { + noSpaceDevices.Add(dev) + } + + job.fail(target, fmt.Errorf("mkdir dst dir fail, %w", err)) continue } file, err := os.OpenFile(target, c.createFlag, job.mode) - if err != nil { - // if no space - job.fail(target, fmt.Errorf("open dst file fail, %w", mappingError(err))) + if err = mappingError(err); err != nil { + if checkErrorAbort(err) { + noSpaceDevices.Add(dev) + } + + job.fail(target, fmt.Errorf("open dst file fail, %w", err)) continue } @@ -155,7 +162,12 @@ func (c *Copyer) write(ctx context.Context, job *writeJob, ch chan<- *baseJob, c c.reportError(job.path, target, fmt.Errorf("delete failed file has error, %w", err)) } - job.fail(target, fmt.Errorf("write dst file fail, %w", mappingError(rerr))) + rerr = mappingError(rerr) + if checkErrorAbort(rerr) { + noSpaceDevices.Add(dev) + } + + job.fail(target, fmt.Errorf("write dst file fail, %w", rerr)) }() defer file.Close() diff --git a/disk_usage.go b/disk_usage.go index 091378c..0377e08 100644 --- a/disk_usage.go +++ b/disk_usage.go @@ -22,6 +22,10 @@ var ( {from: syscall.EROFS, to: ErrTargetDropToReadonly}, {from: syscall.EIO, to: ErrTargetDropToReadonly}, } + abortErrors = []error{ + ErrTargetNoSpace, + ErrTargetDropToReadonly, + } ) type errorPair struct { @@ -81,3 +85,13 @@ func mappingError(err error) error { return err } + +func checkErrorAbort(err error) bool { + for _, e := range abortErrors { + if errors.Is(err, e) { + return true + } + } + + return false +}