Unified · Split
| @@ -163,7 +163,11 @@ func (h *healingTracker) save(ctx context.Context) error { · 162 unmodified lines | ||
| 163 | 163 | func (h *healingTracker) delete(ctx context.Context) error { |
| 164 | 164 | return h.disk.Delete(ctx, minioMetaBucket, |
| 165 | 165 | pathJoin(bucketMetaPrefix, slashSeparator, healingTrackerFilename), |
| 166 | − false) | |
| 166 | + DeleteOptions{ | |
| 167 | + Recursive: false, | |
| 168 | + Force: false, | |
| 169 | + }, | |
| 170 | + ) | |
| 167 | 171 | } |
| 168 | 172 | |
| 169 | 173 | func (h *healingTracker) isHealed(bucket string) bool { |
| @@ -196,7 +196,10 @@ func benchmarkErasureEncode(data, parity, dataDown, parityDown int, size int64, · 195 unmodified lines | ||
| 196 | 196 | if disk == OfflineDisk { |
| 197 | 197 | continue |
| 198 | 198 | } |
| 199 | − disk.Delete(context.Background(), "testbucket", "object", false) | |
| 199 | + disk.Delete(context.Background(), "testbucket", "object", DeleteOptions{ | |
| 200 | + Recursive: false, | |
| 201 | + Force: false, | |
| 202 | + }) | |
| 200 | 203 | writers[i] = newBitrotWriter(disk, "testbucket", "object", erasure.ShardFileSize(size), DefaultBitrotAlgorithm, erasure.ShardSize()) |
| 201 | 204 | } |
| 202 | 205 | _, err := erasure.Encode(context.Background(), bytes.NewReader(content), writers, buffer, erasure.dataBlocks+1) |
| @@ -218,7 +218,10 @@ func TestListOnlineDisks(t *testing.T) { · 217 unmodified lines | ||
| 218 | 218 | // and check if that disk |
| 219 | 219 | // appears in outDatedDisks. |
| 220 | 220 | tamperedIndex = index |
| 221 | − dErr := erasureDisks[index].Delete(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), false) | |
| 221 | + dErr := erasureDisks[index].Delete(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), DeleteOptions{ | |
| 222 | + Recursive: false, | |
| 223 | + Force: false, | |
| 224 | + }) | |
| 222 | 225 | if dErr != nil { |
| 223 | 226 | t.Fatalf("Failed to delete %s - %v", filepath.Join(object, "part.1"), dErr) |
| 224 | 227 | } |
| @@ -395,7 +398,10 @@ func TestListOnlineDisksSmallObjects(t *testing.T) { · 170 unmodified lines | ||
| 395 | 398 | // and check if that disk |
| 396 | 399 | // appears in outDatedDisks. |
| 397 | 400 | tamperedIndex = index |
| 398 | − dErr := erasureDisks[index].Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), false) | |
| 401 | + dErr := erasureDisks[index].Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{ | |
| 402 | + Recursive: false, | |
| 403 | + Force: false, | |
| 404 | + }) | |
| 399 | 405 | if dErr != nil { |
| 400 | 406 | t.Fatalf("Failed to delete %s - %v", pathJoin(object, xlStorageFormatFile), dErr) |
| 401 | 407 | } |
| @@ -655,7 +655,10 @@ func (er erasureObjects) healObjectDir(ctx context.Context, bucket, object strin · 654 unmodified lines | ||
| 655 | 655 | wg.Add(1) |
| 656 | 656 | go func(index int, disk StorageAPI) { |
| 657 | 657 | defer wg.Done() |
| 658 | − _ = disk.Delete(ctx, bucket, object, false) | |
| 658 | + _ = disk.Delete(ctx, bucket, object, DeleteOptions{ | |
| 659 | + Recursive: false, | |
| 660 | + Force: false, | |
| 661 | + }) | |
| 659 | 662 | }(index, disk) |
| 660 | 663 | } |
| 661 | 664 | wg.Wait() |
| @@ -610,7 +610,10 @@ func TestHealCorrectQuorum(t *testing.T) { · 609 unmodified lines | ||
| 610 | 610 | } |
| 611 | 611 | |
| 612 | 612 | for i := 0; i < nfi.Erasure.ParityBlocks; i++ { |
| 613 | − erasureDisks[i].Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), false) | |
| 613 | + erasureDisks[i].Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{ | |
| 614 | + Recursive: false, | |
| 615 | + Force: false, | |
| 616 | + }) | |
| 614 | 617 | } |
| 615 | 618 | |
| 616 | 619 | // Try healing now, it should heal the content properly. |
| @@ -634,7 +637,10 @@ func TestHealCorrectQuorum(t *testing.T) { · 17 unmodified lines | ||
| 634 | 637 | } |
| 635 | 638 | |
| 636 | 639 | for i := 0; i < nfi.Erasure.ParityBlocks; i++ { |
| 637 | − erasureDisks[i].Delete(context.Background(), minioMetaBucket, pathJoin(cfgFile, xlStorageFormatFile), false) | |
| 640 | + erasureDisks[i].Delete(context.Background(), minioMetaBucket, pathJoin(cfgFile, xlStorageFormatFile), DeleteOptions{ | |
| 641 | + Recursive: false, | |
| 642 | + Force: false, | |
| 643 | + }) | |
| 638 | 644 | } |
| 639 | 645 | |
| 640 | 646 | // Try healing now, it should heal the content properly. |
| @@ -714,7 +720,10 @@ func TestHealObjectCorruptedPools(t *testing.T) { · 73 unmodified lines | ||
| 714 | 720 | er := set.sets[0] |
| 715 | 721 | erasureDisks := er.getDisks() |
| 716 | 722 | firstDisk := erasureDisks[0] |
| 717 | − err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), false) | |
| 723 | + err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{ | |
| 724 | + Recursive: false, | |
| 725 | + Force: false, | |
| 726 | + }) | |
| 718 | 727 | if err != nil { |
| 719 | 728 | t.Fatalf("Failed to delete a file - %v", err) |
| 720 | 729 | } |
| @@ -734,7 +743,10 @@ func TestHealObjectCorruptedPools(t *testing.T) { · 13 unmodified lines | ||
| 734 | 743 | t.Errorf("Expected xl.meta file to be present but stat failed - %v", err) |
| 735 | 744 | } |
| 736 | 745 | |
| 737 | − err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), false) | |
| 746 | + err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), DeleteOptions{ | |
| 747 | + Recursive: false, | |
| 748 | + Force: false, | |
| 749 | + }) | |
| 738 | 750 | if err != nil { |
| 739 | 751 | t.Errorf("Failure during deleting part.1 - %v", err) |
| 740 | 752 | } |
| @@ -761,7 +773,10 @@ func TestHealObjectCorruptedPools(t *testing.T) { · 20 unmodified lines | ||
| 761 | 773 | t.Fatalf("FileInfo not equal after healing: %v != %v", fi, nfi) |
| 762 | 774 | } |
| 763 | 775 | |
| 764 | − err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), false) | |
| 776 | + err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), DeleteOptions{ | |
| 777 | + Recursive: false, | |
| 778 | + Force: false, | |
| 779 | + }) | |
| 765 | 780 | if err != nil { |
| 766 | 781 | t.Errorf("Failure during deleting part.1 - %v", err) |
| 767 | 782 | } |
| @@ -792,7 +807,10 @@ func TestHealObjectCorruptedPools(t *testing.T) { · 24 unmodified lines | ||
| 792 | 807 | // Test 4: checks if HealObject returns an error when xl.meta is not found |
| 793 | 808 | // in more than read quorum number of disks, to create a corrupted situation. |
| 794 | 809 | for i := 0; i <= nfi.Erasure.DataBlocks; i++ { |
| 795 | − erasureDisks[i].Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), false) | |
| 810 | + erasureDisks[i].Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{ | |
| 811 | + Recursive: false, | |
| 812 | + Force: false, | |
| 813 | + }) | |
| 796 | 814 | } |
| 797 | 815 | |
| 798 | 816 | // Try healing now, expect to receive errFileNotFound. |
| @@ -884,7 +902,10 @@ func TestHealObjectCorruptedXLMeta(t *testing.T) { · 85 unmodified lines | ||
| 884 | 902 | t.Fatalf("Failed to getLatestFileInfo - %v", err) |
| 885 | 903 | } |
| 886 | 904 | |
| 887 | − err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), false) | |
| 905 | + err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{ | |
| 906 | + Recursive: false, | |
| 907 | + Force: false, | |
| 908 | + }) | |
| 888 | 909 | if err != nil { |
| 889 | 910 | t.Fatalf("Failed to delete a file - %v", err) |
| 890 | 911 | } |
| @@ -936,7 +957,10 @@ func TestHealObjectCorruptedXLMeta(t *testing.T) { · 45 unmodified lines | ||
| 936 | 957 | // Test 3: checks if HealObject returns an error when xl.meta is not found |
| 937 | 958 | // in more than read quorum number of disks, to create a corrupted situation. |
| 938 | 959 | for i := 0; i <= nfi2.Erasure.DataBlocks; i++ { |
| 939 | − erasureDisks[i].Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), false) | |
| 960 | + erasureDisks[i].Delete(context.Background(), bucket, pathJoin(object, xlStorageFormatFile), DeleteOptions{ | |
| 961 | + Recursive: false, | |
| 962 | + Force: false, | |
| 963 | + }) | |
| 940 | 964 | } |
| 941 | 965 | |
| 942 | 966 | // Try healing now, expect to receive errFileNotFound. |
| @@ -1033,7 +1057,10 @@ func TestHealObjectCorruptedParts(t *testing.T) { · 90 unmodified lines | ||
| 1033 | 1057 | } |
| 1034 | 1058 | |
| 1035 | 1059 | // Test 1, remove part.1 |
| 1036 | − err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), false) | |
| 1060 | + err = firstDisk.Delete(context.Background(), bucket, pathJoin(object, fi.DataDir, "part.1"), DeleteOptions{ | |
| 1061 | + Recursive: false, | |
| 1062 | + Force: false, | |
| 1063 | + }) | |
| 1037 | 1064 | if err != nil { |
| 1038 | 1065 | t.Fatalf("Failed to delete a file - %v", err) |
| 1039 | 1066 | } |
| @@ -1078,7 +1105,10 @@ func TestHealObjectCorruptedParts(t *testing.T) { · 38 unmodified lines | ||
| 1078 | 1105 | t.Fatalf("Failed to write a file - %v", err) |
| 1079 | 1106 | } |
| 1080 | 1107 | |
| 1081 | − err = secondDisk.Delete(context.Background(), bucket, object, true) | |
| 1108 | + err = secondDisk.Delete(context.Background(), bucket, object, DeleteOptions{ | |
| 1109 | + Recursive: true, | |
| 1110 | + Force: false, | |
| 1111 | + }) | |
| 1082 | 1112 | if err != nil { |
| 1083 | 1113 | t.Fatalf("Failed to delete a file - %v", err) |
| 1084 | 1114 | } |
| @@ -1166,7 +1196,10 @@ func TestHealObjectErasure(t *testing.T) { · 81 unmodified lines | ||
| 1166 | 1196 | } |
| 1167 | 1197 | |
| 1168 | 1198 | // Delete the whole object folder |
| 1169 | − err = firstDisk.Delete(context.Background(), bucket, object, true) | |
| 1199 | + err = firstDisk.Delete(context.Background(), bucket, object, DeleteOptions{ | |
| 1200 | + Recursive: true, | |
| 1201 | + Force: false, | |
| 1202 | + }) | |
| 1170 | 1203 | if err != nil { |
| 1171 | 1204 | t.Fatalf("Failed to delete a file - %v", err) |
| 1172 | 1205 | } |
| @@ -91,7 +91,10 @@ func (er erasureObjects) removeObjectPart(bucket, object, uploadID, dataDir stri · 90 unmodified lines | ||
| 91 | 91 | // Ignoring failure to remove parts that weren't present in CompleteMultipartUpload |
| 92 | 92 | // requests. xl.meta is the authoritative source of truth on which parts constitute |
| 93 | 93 | // the object. The presence of parts that don't belong in the object doesn't affect correctness. |
| 94 | − _ = storageDisks[index].Delete(context.TODO(), minioMetaMultipartBucket, curpartPath, false) | |
| 94 | + _ = storageDisks[index].Delete(context.TODO(), minioMetaMultipartBucket, curpartPath, DeleteOptions{ | |
| 95 | + Recursive: false, | |
| 96 | + Force: false, | |
| 97 | + }) | |
| 95 | 98 | return nil |
| 96 | 99 | }, index) |
| 97 | 100 | } |
| @@ -138,7 +141,10 @@ func (er erasureObjects) deleteAll(ctx context.Context, bucket, prefix string) { · 40 unmodified lines | ||
| 138 | 141 | wg.Add(1) |
| 139 | 142 | go func(disk StorageAPI) { |
| 140 | 143 | defer wg.Done() |
| 141 | − disk.Delete(ctx, bucket, prefix, true) | |
| 144 | + disk.Delete(ctx, bucket, prefix, DeleteOptions{ | |
| 145 | + Recursive: true, | |
| 146 | + Force: false, | |
| 147 | + }) | |
| 142 | 148 | }(disk) |
| 143 | 149 | } |
| 144 | 150 | wg.Wait() |
| @@ -1367,8 +1367,14 @@ func (er erasureObjects) deletePrefix(ctx context.Context, bucket, prefix string · 1366 unmodified lines | ||
| 1367 | 1367 | // Deletes |
| 1368 | 1368 | // - The prefix and its children |
| 1369 | 1369 | // - The prefix__XLDIR__ |
| 1370 | − defer disks[index].Delete(ctx, bucket, dirPrefix, true) | |
| 1371 | − return disks[index].Delete(ctx, bucket, prefix, true) | |
| 1370 | + defer disks[index].Delete(ctx, bucket, dirPrefix, DeleteOptions{ | |
| 1371 | + Recursive: true, | |
| 1372 | + Force: true, | |
| 1373 | + }) | |
| 1374 | + return disks[index].Delete(ctx, bucket, prefix, DeleteOptions{ | |
| 1375 | + Recursive: true, | |
| 1376 | + Force: true, | |
| 1377 | + }) | |
| 1372 | 1378 | }, index) |
| 1373 | 1379 | } |
| 1374 | 1380 | for _, err := range g.Wait() { |
| @@ -528,7 +528,10 @@ func TestGetObjectNoQuorum(t *testing.T) { · 527 unmodified lines | ||
| 528 | 528 | files, _ := disk.ListDir(ctx, bucket, object, -1) |
| 529 | 529 | for _, file := range files { |
| 530 | 530 | if file != "xl.meta" { |
| 531 | − disk.Delete(ctx, bucket, pathJoin(object, file), true) | |
| 531 | + disk.Delete(ctx, bucket, pathJoin(object, file), DeleteOptions{ | |
| 532 | + Recursive: true, | |
| 533 | + Force: false, | |
| 534 | + }) | |
| 532 | 535 | } |
| 533 | 536 | } |
| 534 | 537 | } |
| @@ -629,7 +632,10 @@ func TestHeadObjectNoQuorum(t *testing.T) { · 94 unmodified lines | ||
| 629 | 632 | files, _ := disk.ListDir(ctx, bucket, object, -1) |
| 630 | 633 | for _, file := range files { |
| 631 | 634 | if file != "xl.meta" { |
| 632 | − disk.Delete(ctx, bucket, pathJoin(object, file), true) | |
| 635 | + disk.Delete(ctx, bucket, pathJoin(object, file), DeleteOptions{ | |
| 636 | + Recursive: true, | |
| 637 | + Force: false, | |
| 638 | + }) | |
| 633 | 639 | } |
| 634 | 640 | } |
| 635 | 641 | } |
| @@ -1321,8 +1321,14 @@ func (es *erasureSingle) DeleteObjects(ctx context.Context, bucket string, objec · 1320 unmodified lines | ||
| 1321 | 1321 | |
| 1322 | 1322 | func (es *erasureSingle) deletePrefix(ctx context.Context, bucket, prefix string) error { |
| 1323 | 1323 | dirPrefix := encodeDirObject(prefix) |
| 1324 | − defer es.disk.Delete(ctx, bucket, dirPrefix, true) | |
| 1325 | − return es.disk.Delete(ctx, bucket, prefix, true) | |
| 1324 | + defer es.disk.Delete(ctx, bucket, dirPrefix, DeleteOptions{ | |
| 1325 | + Recursive: true, | |
| 1326 | + Force: true, | |
| 1327 | + }) | |
| 1328 | + return es.disk.Delete(ctx, bucket, prefix, DeleteOptions{ | |
| 1329 | + Recursive: true, | |
| 1330 | + Force: true, | |
| 1331 | + }) | |
| 1326 | 1332 | } |
| 1327 | 1333 | |
| 1328 | 1334 | // DeleteObject - deletes an object, this call doesn't necessary reply |
| @@ -1916,7 +1922,10 @@ func (es *erasureSingle) removeObjectPart(bucket, object, uploadID, dataDir stri · 587 unmodified lines | ||
| 1916 | 1922 | // Ignoring failure to remove parts that weren't present in CompleteMultipartUpload |
| 1917 | 1923 | // requests. xl.meta is the authoritative source of truth on which parts constitute |
| 1918 | 1924 | // the object. The presence of parts that don't belong in the object doesn't affect correctness. |
| 1919 | − _ = storageDisks[index].Delete(context.TODO(), minioMetaMultipartBucket, curpartPath, false) | |
| 1925 | + _ = storageDisks[index].Delete(context.TODO(), minioMetaMultipartBucket, curpartPath, DeleteOptions{ | |
| 1926 | + Recursive: false, | |
| 1927 | + Force: false, | |
| 1928 | + }) | |
| 1920 | 1929 | return nil |
| 1921 | 1930 | }, index) |
| 1922 | 1931 | } |
| @@ -1954,7 +1963,10 @@ func (es *erasureSingle) cleanupStaleUploadsOnDisk(ctx context.Context, disk Sto · 31 unmodified lines | ||
| 1954 | 1963 | } |
| 1955 | 1964 | wait := es.deletedCleanupSleeper.Timer(ctx) |
| 1956 | 1965 | if now.Sub(vi.Created) > expiry { |
| 1957 | − disk.Delete(ctx, minioMetaTmpBucket, tmpDir, true) | |
| 1966 | + disk.Delete(ctx, minioMetaTmpBucket, tmpDir, DeleteOptions{ | |
| 1967 | + Recursive: true, | |
| 1968 | + Force: false, | |
| 1969 | + }) | |
| 1958 | 1970 | } |
| 1959 | 1971 | wait() |
| 1960 | 1972 | return nil |
| @@ -367,7 +367,10 @@ func saveFormatErasure(disk StorageAPI, format *formatErasureV3, heal bool) erro · 366 unmodified lines | ||
| 367 | 367 | tmpFormat := mustGetUUID() |
| 368 | 368 | |
| 369 | 369 | // Purge any existing temporary file, okay to ignore errors here. |
| 370 | − defer disk.Delete(context.TODO(), minioMetaBucket, tmpFormat, false) | |
| 370 | + defer disk.Delete(context.TODO(), minioMetaBucket, tmpFormat, DeleteOptions{ | |
| 371 | + Recursive: false, | |
| 372 | + Force: false, | |
| 373 | + }) | |
| 371 | 374 | |
| 372 | 375 | // write to unique file. |
| 373 | 376 | if err = disk.WriteAll(context.TODO(), minioMetaBucket, tmpFormat, formatBytes); err != nil { |
| @@ -221,11 +221,11 @@ func (d *naughtyDisk) CheckParts(ctx context.Context, volume string, path string · 220 unmodified lines | ||
| 221 | 221 | return d.disk.CheckParts(ctx, volume, path, fi) |
| 222 | 222 | } |
| 223 | 223 | |
| 224 | −func (d *naughtyDisk) Delete(ctx context.Context, volume string, path string, recursive bool) (err error) { | |
| 224 | +func (d *naughtyDisk) Delete(ctx context.Context, volume string, path string, deleteOpts DeleteOptions) (err error) { | |
| 225 | 225 | if err := d.calcError(); err != nil { |
| 226 | 226 | return err |
| 227 | 227 | } |
| 228 | − return d.disk.Delete(ctx, volume, path, recursive) | |
| 228 | + return d.disk.Delete(ctx, volume, path, deleteOpts) | |
| 229 | 229 | } |
| 230 | 230 | |
| 231 | 231 | func (d *naughtyDisk) DeleteVersions(ctx context.Context, volume string, versions []FileInfoVersions) []error { |
| @@ -21,6 +21,13 @@ import ( · 20 unmodified lines | ||
| 21 | 21 | "time" |
| 22 | 22 | ) |
| 23 | 23 | |
| 24 | +// DeleteOptions represents the disk level delete options available for the APIs | |
| 25 | +//msgp:ignore DeleteOptions | |
| 26 | +type DeleteOptions struct { | |
| 27 | + Recursive bool | |
| 28 | + Force bool | |
| 29 | +} | |
| 30 | + | |
| 24 | 31 | //go:generate msgp -file=$GOFILE |
| 25 | 32 | |
| 26 | 33 | // DiskInfo is an extended type which returns current |
| @@ -95,7 +95,7 @@ type StorageAPI interface { · 94 unmodified lines | ||
| 95 | 95 | ReadFileStream(ctx context.Context, volume, path string, offset, length int64) (io.ReadCloser, error) |
| 96 | 96 | RenameFile(ctx context.Context, srcVolume, srcPath, dstVolume, dstPath string) error |
| 97 | 97 | CheckParts(ctx context.Context, volume string, path string, fi FileInfo) error |
| 98 | − Delete(ctx context.Context, volume string, path string, recursive bool) (err error) | |
| 98 | + Delete(ctx context.Context, volume string, path string, deleteOpts DeleteOptions) (err error) | |
| 99 | 99 | VerifyFile(ctx context.Context, volume, path string, fi FileInfo) error |
| 100 | 100 | StatInfoFile(ctx context.Context, volume, path string, glob bool) (stat []StatInfo, err error) |
| 101 | 101 | |
| @@ -223,7 +223,7 @@ func (p *unrecognizedDisk) CheckParts(ctx context.Context, volume string, path s · 121 unmodified lines | ||
| 223 | 223 | return errDiskNotFound |
| 224 | 224 | } |
| 225 | 225 | |
| 226 | −func (p *unrecognizedDisk) Delete(ctx context.Context, volume string, path string, recursive bool) (err error) { | |
| 226 | +func (p *unrecognizedDisk) Delete(ctx context.Context, volume string, path string, deleteOpts DeleteOptions) (err error) { | |
| 227 | 227 | return errDiskNotFound |
| 228 | 228 | } |
| 229 | 229 | |
| @@ -581,11 +581,12 @@ func (client *storageRESTClient) ListDir(ctx context.Context, volume, dirPath st · 580 unmodified lines | ||
| 581 | 581 | } |
| 582 | 582 | |
| 583 | 583 | // DeleteFile - deletes a file. |
| 584 | −func (client *storageRESTClient) Delete(ctx context.Context, volume string, path string, recursive bool) error { | |
| 584 | +func (client *storageRESTClient) Delete(ctx context.Context, volume string, path string, deleteOpts DeleteOptions) error { | |
| 585 | 585 | values := make(url.Values) |
| 586 | 586 | values.Set(storageRESTVolume, volume) |
| 587 | 587 | values.Set(storageRESTFilePath, path) |
| 588 | − values.Set(storageRESTRecursive, strconv.FormatBool(recursive)) | |
| 588 | + values.Set(storageRESTRecursive, strconv.FormatBool(deleteOpts.Recursive)) | |
| 589 | + values.Set(storageRESTForceDelete, strconv.FormatBool(deleteOpts.Force)) | |
| 589 | 590 | |
| 590 | 591 | respBody, err := client.call(ctx, storageRESTMethodDeleteFile, values, nil, -1) |
| 591 | 592 | defer xhttp.DrainBody(respBody) |
| @@ -652,8 +652,15 @@ func (s *storageRESTServer) DeleteFileHandler(w http.ResponseWriter, r *http.Req · 651 unmodified lines | ||
| 652 | 652 | s.writeErrorResponse(w, err) |
| 653 | 653 | return |
| 654 | 654 | } |
| 655 | − | |
| 656 | − err = s.storage.Delete(r.Context(), volume, filePath, recursive) | |
| 655 | + force, err := strconv.ParseBool(r.Form.Get(storageRESTForceDelete)) | |
| 656 | + if err != nil { | |
| 657 | + s.writeErrorResponse(w, err) | |
| 658 | + return | |
| 659 | + } | |
| 660 | + err = s.storage.Delete(r.Context(), volume, filePath, DeleteOptions{ | |
| 661 | + Recursive: recursive, | |
| 662 | + Force: force, | |
| 663 | + }) | |
| 657 | 664 | if err != nil { |
| 658 | 665 | s.writeErrorResponse(w, err) |
| 659 | 666 | } |
| @@ -383,7 +383,10 @@ func testStorageAPIDeleteFile(t *testing.T, storage StorageAPI) { · 382 unmodified lines | ||
| 383 | 383 | } |
| 384 | 384 | |
| 385 | 385 | for i, testCase := range testCases { |
| 386 | − err := storage.Delete(context.Background(), testCase.volumeName, testCase.objectName, false) | |
| 386 | + err := storage.Delete(context.Background(), testCase.volumeName, testCase.objectName, DeleteOptions{ | |
| 387 | + Recursive: false, | |
| 388 | + Force: false, | |
| 389 | + }) | |
| 387 | 390 | expectErr := (err != nil) |
| 388 | 391 | |
| 389 | 392 | if expectErr != testCase.expectErr { |
| @@ -382,14 +382,14 @@ func (p *xlStorageDiskIDCheck) CheckParts(ctx context.Context, volume string, pa · 381 unmodified lines | ||
| 382 | 382 | return p.storage.CheckParts(ctx, volume, path, fi) |
| 383 | 383 | } |
| 384 | 384 | |
| 385 | −func (p *xlStorageDiskIDCheck) Delete(ctx context.Context, volume string, path string, recursive bool) (err error) { | |
| 385 | +func (p *xlStorageDiskIDCheck) Delete(ctx context.Context, volume string, path string, deleteOpts DeleteOptions) (err error) { | |
| 386 | 386 | ctx, done, err := p.TrackDiskHealth(ctx, storageMetricDelete, volume, path) |
| 387 | 387 | if err != nil { |
| 388 | 388 | return err |
| 389 | 389 | } |
| 390 | 390 | defer done(&err) |
| 391 | 391 | |
| 392 | − return p.storage.Delete(ctx, volume, path, recursive) | |
| 392 | + return p.storage.Delete(ctx, volume, path, deleteOpts) | |
| 393 | 393 | } |
| 394 | 394 | |
| 395 | 395 | // DeleteVersions deletes slice of versions, it can be same object |
| @@ -768,7 +768,10 @@ func (p *xlStorageDiskIDCheck) monitorDiskStatus() { · 372 unmodified lines | ||
| 768 | 768 | if err != nil || len(b) != 10001 { |
| 769 | 769 | continue |
| 770 | 770 | } |
| 771 | − err = p.storage.Delete(context.Background(), minioMetaTmpBucket, fn, false) | |
| 771 | + err = p.storage.Delete(context.Background(), minioMetaTmpBucket, fn, DeleteOptions{ | |
| 772 | + Recursive: false, | |
| 773 | + Force: false, | |
| 774 | + }) | |
| 772 | 775 | if err == nil { |
| 773 | 776 | logger.Info("Able to read+write, bringing disk %s online.", p.storage.String()) |
| 774 | 777 | atomic.StoreInt32(&p.health.status, diskHealthOK) |
| @@ -818,7 +818,7 @@ func (s *xlStorage) DeleteVol(ctx context.Context, volume string, forceDelete bo · 817 unmodified lines | ||
| 818 | 818 | } |
| 819 | 819 | |
| 820 | 820 | if forceDelete { |
| 821 | − err = s.moveToTrash(volumeDir, true) | |
| 821 | + err = s.moveToTrash(volumeDir, true, true) | |
| 822 | 822 | } else { |
| 823 | 823 | err = Remove(volumeDir) |
| 824 | 824 | } |
| @@ -903,7 +903,7 @@ func (s *xlStorage) deleteVersions(ctx context.Context, volume, path string, fis · 78 unmodified lines | ||
| 903 | 903 | if !isXL2V1Format(buf) { |
| 904 | 904 | // Delete the meta file, if there are no more versions the |
| 905 | 905 | // top level parent is automatically removed. |
| 906 | − return s.deleteFile(volumeDir, pathJoin(volumeDir, path), true) | |
| 906 | + return s.deleteFile(volumeDir, pathJoin(volumeDir, path), true, false) | |
| 907 | 907 | } |
| 908 | 908 | |
| 909 | 909 | var xlMeta xlMetaV2 |
| @@ -939,7 +939,7 @@ func (s *xlStorage) deleteVersions(ctx context.Context, volume, path string, fis · 29 unmodified lines | ||
| 939 | 939 | if err = checkPathLength(filePath); err != nil { |
| 940 | 940 | return err |
| 941 | 941 | } |
| 942 | − if err = s.moveToTrash(filePath, true); err != nil { | |
| 942 | + if err = s.moveToTrash(filePath, true, false); err != nil { | |
| 943 | 943 | if err != errFileNotFound { |
| 944 | 944 | return err |
| 945 | 945 | } |
| @@ -959,9 +959,9 @@ func (s *xlStorage) deleteVersions(ctx context.Context, volume, path string, fis · 13 unmodified lines | ||
| 959 | 959 | } |
| 960 | 960 | |
| 961 | 961 | // Move xl.meta to trash |
| 962 | − err = s.moveToTrash(pathJoin(volumeDir, path, xlStorageFormatFile), false) | |
| 962 | + err = s.moveToTrash(pathJoin(volumeDir, path, xlStorageFormatFile), false, false) | |
| 963 | 963 | if err == nil || err == errFileNotFound { |
| 964 | − s.deleteFile(volumeDir, pathJoin(volumeDir, path), false) | |
| 964 | + s.deleteFile(volumeDir, pathJoin(volumeDir, path), false, false) | |
| 965 | 965 | } |
| 966 | 966 | return err |
| 967 | 967 | } |
| @@ -985,19 +985,36 @@ func (s *xlStorage) DeleteVersions(ctx context.Context, volume string, versions · 17 unmodified lines | ||
| 985 | 985 | return errs |
| 986 | 986 | } |
| 987 | 987 | |
| 988 | −func (s *xlStorage) moveToTrash(filePath string, recursive bool) error { | |
| 988 | +func (s *xlStorage) moveToTrash(filePath string, recursive, force bool) error { | |
| 989 | 989 | pathUUID := mustGetUUID() |
| 990 | + targetPath := pathutil.Join(s.diskPath, minioMetaTmpDeletedBucket, pathUUID) | |
| 991 | + | |
| 992 | + var renameFn func(source, target string) error | |
| 990 | 993 | if recursive { |
| 991 | − return renameAll(filePath, pathutil.Join(s.diskPath, minioMetaTmpDeletedBucket, pathUUID)) | |
| 994 | + renameFn = renameAll | |
| 995 | + } else { | |
| 996 | + renameFn = Rename | |
| 997 | + } | |
| 998 | + | |
| 999 | + if err := renameFn(filePath, targetPath); err != nil { | |
| 1000 | + return err | |
| 992 | 1001 | } |
| 993 | − return Rename(filePath, pathutil.Join(s.diskPath, minioMetaTmpDeletedBucket, pathUUID)) | |
| 1002 | + // immediately purge the target | |
| 1003 | + if force { | |
| 1004 | + removeAll(targetPath) | |
| 1005 | + } | |
| 1006 | + | |
| 1007 | + return nil | |
| 994 | 1008 | } |
| 995 | 1009 | |
| 996 | 1010 | // DeleteVersion - deletes FileInfo metadata for path at `xl.meta`. forceDelMarker |
| 997 | 1011 | // will force creating a new `xl.meta` to create a new delete marker |
| 998 | 1012 | func (s *xlStorage) DeleteVersion(ctx context.Context, volume, path string, fi FileInfo, forceDelMarker bool) error { |
| 999 | 1013 | if HasSuffix(path, SlashSeparator) { |
| 1000 | − return s.Delete(ctx, volume, path, false) | |
| 1014 | + return s.Delete(ctx, volume, path, DeleteOptions{ | |
| 1015 | + Recursive: false, | |
| 1016 | + Force: false, | |
| 1017 | + }) | |
| 1001 | 1018 | } |
| 1002 | 1019 | |
| 1003 | 1020 | buf, err := s.ReadAll(ctx, volume, pathJoin(path, xlStorageFormatFile)) |
| @@ -1035,7 +1052,7 @@ func (s *xlStorage) DeleteVersion(ctx context.Context, volume, path string, fi F · 31 unmodified lines | ||
| 1035 | 1052 | if !isXL2V1Format(buf) { |
| 1036 | 1053 | // Delete the meta file, if there are no more versions the |
| 1037 | 1054 | // top level parent is automatically removed. |
| 1038 | − return s.deleteFile(volumeDir, pathJoin(volumeDir, path), true) | |
| 1055 | + return s.deleteFile(volumeDir, pathJoin(volumeDir, path), true, false) | |
| 1039 | 1056 | } |
| 1040 | 1057 | |
| 1041 | 1058 | var xlMeta xlMetaV2 |
| @@ -1065,7 +1082,7 @@ func (s *xlStorage) DeleteVersion(ctx context.Context, volume, path string, fi F · 23 unmodified lines | ||
| 1065 | 1082 | if err = checkPathLength(filePath); err != nil { |
| 1066 | 1083 | return err |
| 1067 | 1084 | } |
| 1068 | − if err = s.moveToTrash(filePath, true); err != nil { | |
| 1085 | + if err = s.moveToTrash(filePath, true, false); err != nil { | |
| 1069 | 1086 | if err != errFileNotFound { |
| 1070 | 1087 | return err |
| 1071 | 1088 | } |
| @@ -1088,9 +1105,9 @@ func (s *xlStorage) DeleteVersion(ctx context.Context, volume, path string, fi F · 16 unmodified lines | ||
| 1088 | 1105 | return err |
| 1089 | 1106 | } |
| 1090 | 1107 | |
| 1091 | − err = s.moveToTrash(filePath, false) | |
| 1108 | + err = s.moveToTrash(filePath, false, false) | |
| 1092 | 1109 | if err == nil || err == errFileNotFound { |
| 1093 | − s.deleteFile(volumeDir, pathJoin(volumeDir, path), false) | |
| 1110 | + s.deleteFile(volumeDir, pathJoin(volumeDir, path), false, false) | |
| 1094 | 1111 | } |
| 1095 | 1112 | return err |
| 1096 | 1113 | } |
| @@ -2014,7 +2031,7 @@ func (s *xlStorage) CheckParts(ctx context.Context, volume string, path string, · 917 unmodified lines | ||
| 2014 | 2031 | // move up the tree, deleting empty parent directories until it finds one |
| 2015 | 2032 | // with files in it. Returns nil for a non-empty directory even when |
| 2016 | 2033 | // recursive is set to false. |
| 2017 | −func (s *xlStorage) deleteFile(basePath, deletePath string, recursive bool) error { | |
| 2034 | +func (s *xlStorage) deleteFile(basePath, deletePath string, recursive, force bool) error { | |
| 2018 | 2035 | if basePath == "" || deletePath == "" { |
| 2019 | 2036 | return nil |
| 2020 | 2037 | } |
| @@ -2027,7 +2044,7 @@ func (s *xlStorage) deleteFile(basePath, deletePath string, recursive bool) erro · 6 unmodified lines | ||
| 2027 | 2044 | |
| 2028 | 2045 | var err error |
| 2029 | 2046 | if recursive { |
| 2030 | − err = s.moveToTrash(deletePath, true) | |
| 2047 | + err = s.moveToTrash(deletePath, true, force) | |
| 2031 | 2048 | } else { |
| 2032 | 2049 | err = Remove(deletePath) |
| 2033 | 2050 | } |
| @@ -2060,13 +2077,13 @@ func (s *xlStorage) deleteFile(basePath, deletePath string, recursive bool) erro · 26 unmodified lines | ||
| 2060 | 2077 | |
| 2061 | 2078 | // Delete parent directory obviously not recursively. Errors for |
| 2062 | 2079 | // parent directories shouldn't trickle down. |
| 2063 | − s.deleteFile(basePath, deletePath, false) | |
| 2080 | + s.deleteFile(basePath, deletePath, false, false) | |
| 2064 | 2081 | |
| 2065 | 2082 | return nil |
| 2066 | 2083 | } |
| 2067 | 2084 | |
| 2068 | 2085 | // DeleteFile - delete a file at path. |
| 2069 | −func (s *xlStorage) Delete(ctx context.Context, volume string, path string, recursive bool) (err error) { | |
| 2086 | +func (s *xlStorage) Delete(ctx context.Context, volume string, path string, deleteOpts DeleteOptions) (err error) { | |
| 2070 | 2087 | volumeDir, err := s.getVolDir(volume) |
| 2071 | 2088 | if err != nil { |
| 2072 | 2089 | return err |
| @@ -2092,7 +2109,7 @@ func (s *xlStorage) Delete(ctx context.Context, volume string, path string, recu · 19 unmodified lines | ||
| 2092 | 2109 | } |
| 2093 | 2110 | |
| 2094 | 2111 | // Delete file and delete parent directory as well if it's empty. |
| 2095 | − return s.deleteFile(volumeDir, filePath, recursive) | |
| 2112 | + return s.deleteFile(volumeDir, filePath, deleteOpts.Recursive, deleteOpts.Force) | |
| 2096 | 2113 | } |
| 2097 | 2114 | |
| 2098 | 2115 | func skipAccessChecks(volume string) (ok bool) { |
| @@ -2270,7 +2287,7 @@ func (s *xlStorage) RenameData(ctx context.Context, srcVolume, srcPath string, f · 171 unmodified lines | ||
| 2270 | 2287 | // legacy data dir means its old content, honor system umask. |
| 2271 | 2288 | if err = mkdirAll(legacyDataPath, 0o777); err != nil { |
| 2272 | 2289 | // any failed mkdir-calls delete them. |
| 2273 | − s.deleteFile(dstVolumeDir, legacyDataPath, true) | |
| 2290 | + s.deleteFile(dstVolumeDir, legacyDataPath, true, false) | |
| 2274 | 2291 | return osErrToFileErr(err) |
| 2275 | 2292 | } |
| 2276 | 2293 | |
| @@ -2282,7 +2299,7 @@ func (s *xlStorage) RenameData(ctx context.Context, srcVolume, srcPath string, f · 5 unmodified lines | ||
| 2282 | 2299 | |
| 2283 | 2300 | if err = Rename(pathJoin(currentDataPath, entry), pathJoin(legacyDataPath, entry)); err != nil { |
| 2284 | 2301 | // Any failed rename calls un-roll previous transaction. |
| 2285 | − s.deleteFile(dstVolumeDir, legacyDataPath, true) | |
| 2302 | + s.deleteFile(dstVolumeDir, legacyDataPath, true, false) | |
| 2286 | 2303 | |
| 2287 | 2304 | return osErrToFileErr(err) |
| 2288 | 2305 | } |
| @@ -2327,7 +2344,7 @@ func (s *xlStorage) RenameData(ctx context.Context, srcVolume, srcPath string, f · 38 unmodified lines | ||
| 2327 | 2344 | if err = xlMeta.AddVersion(fi); err != nil { |
| 2328 | 2345 | if legacyPreserved { |
| 2329 | 2346 | // Any failed rename calls un-roll previous transaction. |
| 2330 | − s.deleteFile(dstVolumeDir, legacyDataPath, true) | |
| 2347 | + s.deleteFile(dstVolumeDir, legacyDataPath, true, false) | |
| 2331 | 2348 | } |
| 2332 | 2349 | return err |
| 2333 | 2350 | } |
| @@ -2338,7 +2355,7 @@ func (s *xlStorage) RenameData(ctx context.Context, srcVolume, srcPath string, f · 4 unmodified lines | ||
| 2338 | 2355 | logger.LogIf(ctx, err) |
| 2339 | 2356 | if legacyPreserved { |
| 2340 | 2357 | // Any failed rename calls un-roll previous transaction. |
| 2341 | − s.deleteFile(dstVolumeDir, legacyDataPath, true) | |
| 2358 | + s.deleteFile(dstVolumeDir, legacyDataPath, true, false) | |
| 2342 | 2359 | } |
| 2343 | 2360 | return errFileCorrupt |
| 2344 | 2361 | } |
| @@ -2347,7 +2364,7 @@ func (s *xlStorage) RenameData(ctx context.Context, srcVolume, srcPath string, f · 2 unmodified lines | ||
| 2347 | 2364 | if err = s.WriteAll(ctx, srcVolume, pathJoin(srcPath, xlStorageFormatFile), dstBuf); err != nil { |
| 2348 | 2365 | if legacyPreserved { |
| 2349 | 2366 | // Any failed rename calls un-roll previous transaction. |
| 2350 | − s.deleteFile(dstVolumeDir, legacyDataPath, true) | |
| 2367 | + s.deleteFile(dstVolumeDir, legacyDataPath, true, false) | |
| 2351 | 2368 | } |
| 2352 | 2369 | return osErrToFileErr(err) |
| 2353 | 2370 | } |
| @@ -2355,19 +2372,19 @@ func (s *xlStorage) RenameData(ctx context.Context, srcVolume, srcPath string, f · 1 unmodified line | ||
| 2355 | 2372 | |
| 2356 | 2373 | // renameAll only for objects that have xl.meta not saved inline. |
| 2357 | 2374 | if len(fi.Data) == 0 && fi.Size > 0 { |
| 2358 | − s.moveToTrash(dstDataPath, true) | |
| 2375 | + s.moveToTrash(dstDataPath, true, false) | |
| 2359 | 2376 | if healing { |
| 2360 | 2377 | // If we are healing we should purge any legacyDataPath content, |
| 2361 | 2378 | // that was previously preserved during PutObject() call |
| 2362 | 2379 | // on a versioned bucket. |
| 2363 | − s.moveToTrash(legacyDataPath, true) | |
| 2380 | + s.moveToTrash(legacyDataPath, true, false) | |
| 2364 | 2381 | } |
| 2365 | 2382 | if err = renameAll(srcDataPath, dstDataPath); err != nil { |
| 2366 | 2383 | if legacyPreserved { |
| 2367 | 2384 | // Any failed rename calls un-roll previous transaction. |
| 2368 | − s.deleteFile(dstVolumeDir, legacyDataPath, true) | |
| 2385 | + s.deleteFile(dstVolumeDir, legacyDataPath, true, false) | |
| 2369 | 2386 | } |
| 2370 | − s.deleteFile(dstVolumeDir, dstDataPath, false) | |
| 2387 | + s.deleteFile(dstVolumeDir, dstDataPath, false, false) | |
| 2371 | 2388 | return osErrToFileErr(err) |
| 2372 | 2389 | } |
| 2373 | 2390 | } |
| @@ -2376,9 +2393,9 @@ func (s *xlStorage) RenameData(ctx context.Context, srcVolume, srcPath string, f · 2 unmodified lines | ||
| 2376 | 2393 | if err = renameAll(srcFilePath, dstFilePath); err != nil { |
| 2377 | 2394 | if legacyPreserved { |
| 2378 | 2395 | // Any failed rename calls un-roll previous transaction. |
| 2379 | − s.deleteFile(dstVolumeDir, legacyDataPath, true) | |
| 2396 | + s.deleteFile(dstVolumeDir, legacyDataPath, true, false) | |
| 2380 | 2397 | } |
| 2381 | − s.deleteFile(dstVolumeDir, dstFilePath, false) | |
| 2398 | + s.deleteFile(dstVolumeDir, dstFilePath, false, false) | |
| 2382 | 2399 | return osErrToFileErr(err) |
| 2383 | 2400 | } |
| 2384 | 2401 | |
| @@ -2386,16 +2403,16 @@ func (s *xlStorage) RenameData(ctx context.Context, srcVolume, srcPath string, f · 1 unmodified line | ||
| 2386 | 2403 | // movement, this is to ensure that previous data references can co-exist for |
| 2387 | 2404 | // any recoverability. |
| 2388 | 2405 | if oldDstDataPath != "" { |
| 2389 | − s.moveToTrash(oldDstDataPath, true) | |
| 2406 | + s.moveToTrash(oldDstDataPath, true, false) | |
| 2390 | 2407 | } |
| 2391 | 2408 | } else { |
| 2392 | 2409 | // Write meta-file directly, no data |
| 2393 | 2410 | if err = s.WriteAll(ctx, dstVolume, pathJoin(dstPath, xlStorageFormatFile), dstBuf); err != nil { |
| 2394 | 2411 | if legacyPreserved { |
| 2395 | 2412 | // Any failed rename calls un-roll previous transaction. |
| 2396 | − s.deleteFile(dstVolumeDir, legacyDataPath, true) | |
| 2413 | + s.deleteFile(dstVolumeDir, legacyDataPath, true, false) | |
| 2397 | 2414 | } |
| 2398 | − s.deleteFile(dstVolumeDir, dstFilePath, false) | |
| 2415 | + s.deleteFile(dstVolumeDir, dstFilePath, false, false) | |
| 2399 | 2416 | return err |
| 2400 | 2417 | } |
| 2401 | 2418 | } |
| @@ -2484,7 +2501,7 @@ func (s *xlStorage) RenameFile(ctx context.Context, srcVolume, srcPath, dstVolum · 82 unmodified lines | ||
| 2484 | 2501 | |
| 2485 | 2502 | // Remove parent dir of the source file if empty |
| 2486 | 2503 | parentDir := pathutil.Dir(srcFilePath) |
| 2487 | − s.deleteFile(srcVolumeDir, parentDir, false) | |
| 2504 | + s.deleteFile(srcVolumeDir, parentDir, false, false) | |
| 2488 | 2505 | |
| 2489 | 2506 | return nil |
| 2490 | 2507 | } |
| @@ -933,14 +933,20 @@ func TestXLStorageListDir(t *testing.T) { · 932 unmodified lines | ||
| 933 | 933 | t.Fatalf("Unable to initialize xlStorage, %s", err) |
| 934 | 934 | } |
| 935 | 935 | |
| 936 | − if err = xlStorageNew.Delete(context.Background(), "mybucket", "myobject", false); err != errVolumeAccessDenied { | |
| 936 | + if err = xlStorageNew.Delete(context.Background(), "mybucket", "myobject", DeleteOptions{ | |
| 937 | + Recursive: false, | |
| 938 | + Force: false, | |
| 939 | + }); err != errVolumeAccessDenied { | |
| 937 | 940 | t.Errorf("expected: %s, got: %s", errVolumeAccessDenied, err) |
| 938 | 941 | } |
| 939 | 942 | } |
| 940 | 943 | |
| 941 | 944 | // TestXLStorage for delete on an removed disk. |
| 942 | 945 | // should fail with disk not found. |
| 943 | − err = xlStorageDeletedStorage.Delete(context.Background(), "del-vol", "my-file", false) | |
| 946 | + err = xlStorageDeletedStorage.Delete(context.Background(), "del-vol", "my-file", DeleteOptions{ | |
| 947 | + Recursive: false, | |
| 948 | + Force: false, | |
| 949 | + }) | |
| 944 | 950 | if err != errDiskNotFound { |
| 945 | 951 | t.Errorf("Expected: \"Disk not found\", got \"%s\"", err) |
| 946 | 952 | } |
| @@ -1029,7 +1035,10 @@ func TestXLStorageDeleteFile(t *testing.T) { · 82 unmodified lines | ||
| 1029 | 1035 | } |
| 1030 | 1036 | |
| 1031 | 1037 | for i, testCase := range testCases { |
| 1032 | − if err = xlStorage.Delete(context.Background(), testCase.srcVol, testCase.srcPath, false); err != testCase.expectedErr { | |
| 1038 | + if err = xlStorage.Delete(context.Background(), testCase.srcVol, testCase.srcPath, DeleteOptions{ | |
| 1039 | + Recursive: false, | |
| 1040 | + Force: false, | |
| 1041 | + }); err != testCase.expectedErr { | |
| 1033 | 1042 | t.Errorf("TestXLStorage case %d: Expected: \"%s\", got: \"%s\"", i+1, testCase.expectedErr, err) |
| 1034 | 1043 | } |
| 1035 | 1044 | } |
| @@ -1054,7 +1063,10 @@ func TestXLStorageDeleteFile(t *testing.T) { · 18 unmodified lines | ||
| 1054 | 1063 | t.Fatalf("Unable to initialize xlStorage, %s", err) |
| 1055 | 1064 | } |
| 1056 | 1065 | |
| 1057 | − if err = xlStorageNew.Delete(context.Background(), "mybucket", "myobject", false); err != errVolumeAccessDenied { | |
| 1066 | + if err = xlStorageNew.Delete(context.Background(), "mybucket", "myobject", DeleteOptions{ | |
| 1067 | + Recursive: false, | |
| 1068 | + Force: false, | |
| 1069 | + }); err != errVolumeAccessDenied { | |
| 1058 | 1070 | t.Errorf("expected: %s, got: %s", errVolumeAccessDenied, err) |
| 1059 | 1071 | } |
| 1060 | 1072 | } |
| @@ -1072,7 +1084,10 @@ func TestXLStorageDeleteFile(t *testing.T) { · 11 unmodified lines | ||
| 1072 | 1084 | |
| 1073 | 1085 | // TestXLStorage for delete on an removed disk. |
| 1074 | 1086 | // should fail with disk not found. |
| 1075 | − err = xlStorageDeletedStorage.Delete(context.Background(), "del-vol", "my-file", false) | |
| 1087 | + err = xlStorageDeletedStorage.Delete(context.Background(), "del-vol", "my-file", DeleteOptions{ | |
| 1088 | + Recursive: false, | |
| 1089 | + Force: false, | |
| 1090 | + }) | |
| 1076 | 1091 | if err != errDiskNotFound { |
| 1077 | 1092 | t.Errorf("Expected: \"Disk not found\", got \"%s\"", err) |
| 1078 | 1093 | } |
| @@ -1907,7 +1922,10 @@ func TestXLStorageVerifyFile(t *testing.T) { · 828 unmodified lines | ||
| 1907 | 1922 | t.Fatal("expected to fail bitrot check") |
| 1908 | 1923 | } |
| 1909 | 1924 | |
| 1910 | − if err := storage.Delete(context.Background(), volName, fileName, false); err != nil { | |
| 1925 | + if err := storage.Delete(context.Background(), volName, fileName, DeleteOptions{ | |
| 1926 | + Recursive: false, | |
| 1927 | + Force: false, | |
| 1928 | + }); err != nil { | |
| 1911 | 1929 | t.Fatal(err) |
| 1912 | 1930 | } |
| 1913 | 1931 | |
| @@ -70,7 +70,10 @@ func TestUNCPaths(t *testing.T) { · 69 unmodified lines | ||
| 70 | 70 | } else if err == nil && !test.pass { |
| 71 | 71 | t.Error(err) |
| 72 | 72 | } |
| 73 | − fs.Delete(context.Background(), "voldir", test.objName, false) | |
| 73 | + fs.Delete(context.Background(), "voldir", test.objName, DeleteOptions{ | |
| 74 | + Recursive: false, | |
| 75 | + Force: false, | |
| 76 | + }) | |
| 74 | 77 | }) |
| 75 | 78 | } |
| 76 | 79 | } |