mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-19 20:44:28 +02:00
s3: count stored versions as bucket contents on delete (#11775)
* s3: count stored versions as bucket contents A <key>.versions directory holding version entries is user data; skipping it let bucketHasUserObjects report an empty bucket while the recursive delete dropped every stored version. * test: rename stale reserved-folders case in bucket delete test .versions directories are now descended into, so the case only holds because the folder is empty.
This commit is contained in:
1 parent
44bb697495
commit
602ddb31f2
2 files changed
+22
-7
No files matched your search
@@ -152,7 +152,7 @@ func TestBucketHasUserObjects_EmptyDirectories(t *testing.T) {
|
||||
wantHasUser: true,
|
||||
},
|
||||
{
|
||||
name: "bucket with only reserved folders (.uploads, *.versions)",
|
||||
name: "empty *.versions folder and .uploads do not count",
|
||||
entriesByDir: map[string][]*filer_pb.Entry{
|
||||
"/buckets/b": {
|
||||
{Name: s3_constants.MultipartUploadsFolder, IsDirectory: true},
|
||||
@@ -162,7 +162,7 @@ func TestBucketHasUserObjects_EmptyDirectories(t *testing.T) {
|
||||
wantHasUser: false,
|
||||
},
|
||||
{
|
||||
name: "nested versions-named directories are internal",
|
||||
name: "nested versions directory with stored versions counts",
|
||||
entriesByDir: map[string][]*filer_pb.Entry{
|
||||
"/buckets/b": {
|
||||
{Name: "logs", IsDirectory: true},
|
||||
@@ -174,6 +174,19 @@ func TestBucketHasUserObjects_EmptyDirectories(t *testing.T) {
|
||||
{Name: "v1", IsDirectory: false},
|
||||
},
|
||||
},
|
||||
wantHasUser: true,
|
||||
},
|
||||
{
|
||||
name: "nested versions directory left empty does not count",
|
||||
entriesByDir: map[string][]*filer_pb.Entry{
|
||||
"/buckets/b": {
|
||||
{Name: "logs", IsDirectory: true},
|
||||
},
|
||||
"/buckets/b/logs": {
|
||||
{Name: "foo" + s3_constants.VersionsFolder, IsDirectory: true},
|
||||
},
|
||||
"/buckets/b/logs/foo" + s3_constants.VersionsFolder: {},
|
||||
},
|
||||
wantHasUser: false,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -521,8 +521,9 @@ func (s3a *S3ApiServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
|
||||
// bucketHasUserObjects checks whether a bucket contains any user objects.
|
||||
// Empty directories left behind by deleted objects and internal folders
|
||||
// (.uploads, *.versions) do not count as user objects.
|
||||
// Empty directories left behind by deleted objects and the .uploads staging
|
||||
// folder do not count as user objects; stored versions inside a <key>.versions
|
||||
// directory do.
|
||||
func (s3a *S3ApiServer) bucketHasUserObjects(bucket string) (bool, error) {
|
||||
return s3a.dirHasUserObjects(s3a.option.BucketsPath + "/" + bucket)
|
||||
}
|
||||
@@ -556,9 +557,10 @@ func (s3a *S3ApiServer) dirHasUserObjects(root string) (bool, error) {
|
||||
if entry.IsDirectoryKeyObject() {
|
||||
return true, nil
|
||||
}
|
||||
// Internal folders are skipped by object listing at every level,
|
||||
// so a directory with a reserved name never counts.
|
||||
if isReservedDirectoryName(entry.Name) {
|
||||
// Multipart staging folders are invisible to object listing at
|
||||
// every level, so they never count. A <key>.versions directory
|
||||
// is descended into since it may still hold stored versions.
|
||||
if entry.Name == s3_constants.MultipartUploadsFolder {
|
||||
continue
|
||||
}
|
||||
dirs = append(dirs, dir+"/"+entry.Name)
|
||||
|
||||
Reference in new issue
Block a user