From d2d49f6c6c8a0ec4382da88dbf6bfeb596148a81 Mon Sep 17 00:00:00 2001 From: Anis Elleuch Date: Wed, 21 Feb 2018 00:33:26 +0100 Subject: [PATCH] xl: Avoid removing directory content in Delete API (#5548) Delete & Multi Delete API should not try to remove the directory content. The only permitted case is with zero size object with a trailing slash in its name. --- cmd/posix.go | 11 ++++++++--- cmd/xl-v1-object.go | 18 ++++++++++++++---- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/cmd/posix.go b/cmd/posix.go index 04e0a10ee..3ac6ebcdd 100644 --- a/cmd/posix.go +++ b/cmd/posix.go @@ -24,6 +24,7 @@ import ( slashpath "path" "path/filepath" "runtime" + "strings" "sync" "sync/atomic" "syscall" @@ -860,9 +861,13 @@ func deleteFile(basePath, deletePath string) error { return err } - // Recursively go down the next path and delete again. - // Errors for parent directories shouldn't trickle down. - deleteFile(basePath, slashpath.Dir(deletePath)) + // Trailing slash is removed when found to ensure + // slashpath.Dir() to work as intended. + deletePath = strings.TrimSuffix(deletePath, slashSeparator) + deletePath = slashpath.Dir(deletePath) + + // Delete parent directory. Errors for parent directories shouldn't trickle down. + deleteFile(basePath, deletePath) return nil } diff --git a/cmd/xl-v1-object.go b/cmd/xl-v1-object.go index c1e7ccfee..7b41202cf 100644 --- a/cmd/xl-v1-object.go +++ b/cmd/xl-v1-object.go @@ -777,8 +777,11 @@ func (xl xlObjects) deleteObject(bucket, object string) error { var writeQuorum int var err error + + isDir := hasSuffix(object, slashSeparator) + // If its a directory request, no need to read metadata. - if !hasSuffix(object, slashSeparator) { + if !isDir { // Read metadata associated with the object from all disks. metaArr, errs := readAllXLMetadata(xl.getDisks(), bucket, object) @@ -800,13 +803,20 @@ func (xl xlObjects) deleteObject(bucket, object string) error { continue } wg.Add(1) - go func(index int, disk StorageAPI) { + go func(index int, disk StorageAPI, isDir bool) { defer wg.Done() - err := cleanupDir(disk, bucket, object) + var err error + if isDir { + // DeleteFile() simply tries to remove a directory + // and will succeed only if that directory is empty. + err = disk.DeleteFile(bucket, object) + } else { + err = cleanupDir(disk, bucket, object) + } if err != nil && errors.Cause(err) != errVolumeNotFound { dErrs[index] = err } - }(index, disk) + }(index, disk, isDir) } // Wait for all routines to finish.