mirror of
https://github.com/minio/minio.git
synced 2024-12-24 22:25:54 -05:00
xl: Make it clear when to create delete marker for a non existant object (#11423)
This commit is contained in:
parent
a71e0483c9
commit
b3f81e75f6
@ -709,7 +709,7 @@ func (er erasureObjects) purgeObjectDangling(ctx context.Context, bucket, object
|
|||||||
if versionID == "" {
|
if versionID == "" {
|
||||||
err = er.deleteObject(ctx, bucket, object, writeQuorum)
|
err = er.deleteObject(ctx, bucket, object, writeQuorum)
|
||||||
} else {
|
} else {
|
||||||
err = er.deleteObjectVersion(ctx, bucket, object, writeQuorum, FileInfo{VersionID: versionID})
|
err = er.deleteObjectVersion(ctx, bucket, object, writeQuorum, FileInfo{VersionID: versionID}, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If Delete was successful, make sure to return the appropriate error
|
// If Delete was successful, make sure to return the appropriate error
|
||||||
|
@ -414,7 +414,7 @@ func (er erasureObjects) getObjectFileInfo(ctx context.Context, bucket, object s
|
|||||||
er.deleteObjectVersion(ctx, bucket, object, 1, FileInfo{
|
er.deleteObjectVersion(ctx, bucket, object, 1, FileInfo{
|
||||||
Name: object,
|
Name: object,
|
||||||
VersionID: opts.VersionID,
|
VersionID: opts.VersionID,
|
||||||
})
|
}, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -800,7 +800,7 @@ func (er erasureObjects) putObject(ctx context.Context, bucket string, object st
|
|||||||
return fi.ToObjectInfo(bucket, object), nil
|
return fi.ToObjectInfo(bucket, object), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (er erasureObjects) deleteObjectVersion(ctx context.Context, bucket, object string, writeQuorum int, fi FileInfo) error {
|
func (er erasureObjects) deleteObjectVersion(ctx context.Context, bucket, object string, writeQuorum int, fi FileInfo, forceDelMarker bool) error {
|
||||||
defer ObjectPathUpdated(pathJoin(bucket, object))
|
defer ObjectPathUpdated(pathJoin(bucket, object))
|
||||||
disks := er.getDisks()
|
disks := er.getDisks()
|
||||||
g := errgroup.WithNErrs(len(disks))
|
g := errgroup.WithNErrs(len(disks))
|
||||||
@ -810,7 +810,7 @@ func (er erasureObjects) deleteObjectVersion(ctx context.Context, bucket, object
|
|||||||
if disks[index] == nil {
|
if disks[index] == nil {
|
||||||
return errDiskNotFound
|
return errDiskNotFound
|
||||||
}
|
}
|
||||||
return disks[index].DeleteVersion(ctx, bucket, object, fi)
|
return disks[index].DeleteVersion(ctx, bucket, object, fi, forceDelMarker)
|
||||||
}, index)
|
}, index)
|
||||||
}
|
}
|
||||||
// return errors if any during deletion
|
// return errors if any during deletion
|
||||||
@ -1098,7 +1098,7 @@ func (er erasureObjects) DeleteObject(ctx context.Context, bucket, object string
|
|||||||
// version as delete marker
|
// version as delete marker
|
||||||
// Add delete marker, since we don't have any version specified explicitly.
|
// Add delete marker, since we don't have any version specified explicitly.
|
||||||
// Or if a particular version id needs to be replicated.
|
// Or if a particular version id needs to be replicated.
|
||||||
if err = er.deleteObjectVersion(ctx, bucket, object, writeQuorum, fi); err != nil {
|
if err = er.deleteObjectVersion(ctx, bucket, object, writeQuorum, fi, opts.DeleteMarker); err != nil {
|
||||||
return objInfo, toObjectErr(err, bucket, object)
|
return objInfo, toObjectErr(err, bucket, object)
|
||||||
}
|
}
|
||||||
return fi.ToObjectInfo(bucket, object), nil
|
return fi.ToObjectInfo(bucket, object), nil
|
||||||
@ -1115,7 +1115,7 @@ func (er erasureObjects) DeleteObject(ctx context.Context, bucket, object string
|
|||||||
DeleteMarkerReplicationStatus: opts.DeleteMarkerReplicationStatus,
|
DeleteMarkerReplicationStatus: opts.DeleteMarkerReplicationStatus,
|
||||||
VersionPurgeStatus: opts.VersionPurgeStatus,
|
VersionPurgeStatus: opts.VersionPurgeStatus,
|
||||||
TransitionStatus: opts.TransitionStatus,
|
TransitionStatus: opts.TransitionStatus,
|
||||||
}); err != nil {
|
}, opts.DeleteMarker); err != nil {
|
||||||
return objInfo, toObjectErr(err, bucket, object)
|
return objInfo, toObjectErr(err, bucket, object)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,11 +245,11 @@ func (d *naughtyDisk) WriteMetadata(ctx context.Context, volume, path string, fi
|
|||||||
return d.disk.WriteMetadata(ctx, volume, path, fi)
|
return d.disk.WriteMetadata(ctx, volume, path, fi)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *naughtyDisk) DeleteVersion(ctx context.Context, volume, path string, fi FileInfo) (err error) {
|
func (d *naughtyDisk) DeleteVersion(ctx context.Context, volume, path string, fi FileInfo, forceDelMarker bool) (err error) {
|
||||||
if err := d.calcError(); err != nil {
|
if err := d.calcError(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return d.disk.DeleteVersion(ctx, volume, path, fi)
|
return d.disk.DeleteVersion(ctx, volume, path, fi, forceDelMarker)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *naughtyDisk) ReadVersion(ctx context.Context, volume, path, versionID string, readData bool) (fi FileInfo, err error) {
|
func (d *naughtyDisk) ReadVersion(ctx context.Context, volume, path, versionID string, readData bool) (fi FileInfo, err error) {
|
||||||
|
@ -55,7 +55,7 @@ type StorageAPI interface {
|
|||||||
WalkVersions(ctx context.Context, volume, dirPath, marker string, recursive bool, endWalkCh <-chan struct{}) (chan FileInfoVersions, error)
|
WalkVersions(ctx context.Context, volume, dirPath, marker string, recursive bool, endWalkCh <-chan struct{}) (chan FileInfoVersions, error)
|
||||||
|
|
||||||
// Metadata operations
|
// Metadata operations
|
||||||
DeleteVersion(ctx context.Context, volume, path string, fi FileInfo) error
|
DeleteVersion(ctx context.Context, volume, path string, fi FileInfo, forceDelMarker bool) error
|
||||||
DeleteVersions(ctx context.Context, volume string, versions []FileInfo) []error
|
DeleteVersions(ctx context.Context, volume string, versions []FileInfo) []error
|
||||||
WriteMetadata(ctx context.Context, volume, path string, fi FileInfo) error
|
WriteMetadata(ctx context.Context, volume, path string, fi FileInfo) error
|
||||||
ReadVersion(ctx context.Context, volume, path, versionID string, readData bool) (FileInfo, error)
|
ReadVersion(ctx context.Context, volume, path, versionID string, readData bool) (FileInfo, error)
|
||||||
|
@ -332,10 +332,11 @@ func (client *storageRESTClient) WriteMetadata(ctx context.Context, volume, path
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *storageRESTClient) DeleteVersion(ctx context.Context, volume, path string, fi FileInfo) error {
|
func (client *storageRESTClient) DeleteVersion(ctx context.Context, volume, path string, fi FileInfo, forceDelMarker bool) error {
|
||||||
values := make(url.Values)
|
values := make(url.Values)
|
||||||
values.Set(storageRESTVolume, volume)
|
values.Set(storageRESTVolume, volume)
|
||||||
values.Set(storageRESTFilePath, path)
|
values.Set(storageRESTFilePath, path)
|
||||||
|
values.Set(storageRESTForceDelMarker, strconv.FormatBool(forceDelMarker))
|
||||||
|
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
if err := msgp.Encode(&buffer, &fi); err != nil {
|
if err := msgp.Encode(&buffer, &fi); err != nil {
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
const (
|
const (
|
||||||
storageRESTVersion = "v26" // Add NumVersions/SuccessorModTime fields in FileInfo
|
storageRESTVersion = "v27" // Add force-delete-marker to DeleteVersion
|
||||||
storageRESTVersionPrefix = SlashSeparator + storageRESTVersion
|
storageRESTVersionPrefix = SlashSeparator + storageRESTVersion
|
||||||
storageRESTPrefix = minioReservedBucketPath + "/storage"
|
storageRESTPrefix = minioReservedBucketPath + "/storage"
|
||||||
)
|
)
|
||||||
@ -58,6 +58,7 @@ const (
|
|||||||
storageRESTVolumes = "volumes"
|
storageRESTVolumes = "volumes"
|
||||||
storageRESTDirPath = "dir-path"
|
storageRESTDirPath = "dir-path"
|
||||||
storageRESTFilePath = "file-path"
|
storageRESTFilePath = "file-path"
|
||||||
|
storageRESTForceDelMarker = "force-delete-marker"
|
||||||
storageRESTVersionID = "version-id"
|
storageRESTVersionID = "version-id"
|
||||||
storageRESTReadData = "read-data"
|
storageRESTReadData = "read-data"
|
||||||
storageRESTTotalVersions = "total-versions"
|
storageRESTTotalVersions = "total-versions"
|
||||||
|
@ -300,6 +300,11 @@ func (s *storageRESTServer) DeleteVersionHandler(w http.ResponseWriter, r *http.
|
|||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
volume := vars[storageRESTVolume]
|
volume := vars[storageRESTVolume]
|
||||||
filePath := vars[storageRESTFilePath]
|
filePath := vars[storageRESTFilePath]
|
||||||
|
forceDelMarker, err := strconv.ParseBool(vars[storageRESTForceDelMarker])
|
||||||
|
if err != nil {
|
||||||
|
s.writeErrorResponse(w, errInvalidArgument)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if r.ContentLength < 0 {
|
if r.ContentLength < 0 {
|
||||||
s.writeErrorResponse(w, errInvalidArgument)
|
s.writeErrorResponse(w, errInvalidArgument)
|
||||||
@ -312,7 +317,7 @@ func (s *storageRESTServer) DeleteVersionHandler(w http.ResponseWriter, r *http.
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := s.storage.DeleteVersion(r.Context(), volume, filePath, fi)
|
err = s.storage.DeleteVersion(r.Context(), volume, filePath, fi, forceDelMarker)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.writeErrorResponse(w, err)
|
s.writeErrorResponse(w, err)
|
||||||
}
|
}
|
||||||
@ -1038,7 +1043,7 @@ func registerStorageRESTHandlers(router *mux.Router, endpointServerPools Endpoin
|
|||||||
subrouter.Methods(http.MethodPost).Path(storageRESTVersionPrefix + storageRESTMethodWriteMetadata).HandlerFunc(httpTraceHdrs(server.WriteMetadataHandler)).
|
subrouter.Methods(http.MethodPost).Path(storageRESTVersionPrefix + storageRESTMethodWriteMetadata).HandlerFunc(httpTraceHdrs(server.WriteMetadataHandler)).
|
||||||
Queries(restQueries(storageRESTVolume, storageRESTFilePath)...)
|
Queries(restQueries(storageRESTVolume, storageRESTFilePath)...)
|
||||||
subrouter.Methods(http.MethodPost).Path(storageRESTVersionPrefix + storageRESTMethodDeleteVersion).HandlerFunc(httpTraceHdrs(server.DeleteVersionHandler)).
|
subrouter.Methods(http.MethodPost).Path(storageRESTVersionPrefix + storageRESTMethodDeleteVersion).HandlerFunc(httpTraceHdrs(server.DeleteVersionHandler)).
|
||||||
Queries(restQueries(storageRESTVolume, storageRESTFilePath)...)
|
Queries(restQueries(storageRESTVolume, storageRESTFilePath, storageRESTForceDelMarker)...)
|
||||||
subrouter.Methods(http.MethodPost).Path(storageRESTVersionPrefix + storageRESTMethodReadVersion).HandlerFunc(httpTraceHdrs(server.ReadVersionHandler)).
|
subrouter.Methods(http.MethodPost).Path(storageRESTVersionPrefix + storageRESTMethodReadVersion).HandlerFunc(httpTraceHdrs(server.ReadVersionHandler)).
|
||||||
Queries(restQueries(storageRESTVolume, storageRESTFilePath, storageRESTVersionID, storageRESTReadData)...)
|
Queries(restQueries(storageRESTVolume, storageRESTFilePath, storageRESTVersionID, storageRESTReadData)...)
|
||||||
subrouter.Methods(http.MethodPost).Path(storageRESTVersionPrefix + storageRESTMethodRenameData).HandlerFunc(httpTraceHdrs(server.RenameDataHandler)).
|
subrouter.Methods(http.MethodPost).Path(storageRESTVersionPrefix + storageRESTMethodRenameData).HandlerFunc(httpTraceHdrs(server.RenameDataHandler)).
|
||||||
|
@ -256,12 +256,12 @@ func (p *xlStorageDiskIDCheck) WriteAll(ctx context.Context, volume string, path
|
|||||||
return p.storage.WriteAll(ctx, volume, path, b)
|
return p.storage.WriteAll(ctx, volume, path, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *xlStorageDiskIDCheck) DeleteVersion(ctx context.Context, volume, path string, fi FileInfo) (err error) {
|
func (p *xlStorageDiskIDCheck) DeleteVersion(ctx context.Context, volume, path string, fi FileInfo, forceDelMarker bool) (err error) {
|
||||||
if err = p.checkDiskStale(); err != nil {
|
if err = p.checkDiskStale(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.storage.DeleteVersion(ctx, volume, path, fi)
|
return p.storage.DeleteVersion(ctx, volume, path, fi, forceDelMarker)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *xlStorageDiskIDCheck) WriteMetadata(ctx context.Context, volume, path string, fi FileInfo) (err error) {
|
func (p *xlStorageDiskIDCheck) WriteMetadata(ctx context.Context, volume, path string, fi FileInfo) (err error) {
|
||||||
|
@ -878,7 +878,7 @@ func (s *xlStorage) ListDir(ctx context.Context, volume, dirPath string, count i
|
|||||||
func (s *xlStorage) DeleteVersions(ctx context.Context, volume string, versions []FileInfo) []error {
|
func (s *xlStorage) DeleteVersions(ctx context.Context, volume string, versions []FileInfo) []error {
|
||||||
errs := make([]error, len(versions))
|
errs := make([]error, len(versions))
|
||||||
for i, version := range versions {
|
for i, version := range versions {
|
||||||
if err := s.DeleteVersion(ctx, volume, version.Name, version); err != nil {
|
if err := s.DeleteVersion(ctx, volume, version.Name, version, false); err != nil {
|
||||||
errs[i] = err
|
errs[i] = err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -886,9 +886,9 @@ func (s *xlStorage) DeleteVersions(ctx context.Context, volume string, versions
|
|||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteVersion - deletes FileInfo metadata for path at `xl.meta`. Create a fresh
|
// DeleteVersion - deletes FileInfo metadata for path at `xl.meta`. forceDelMarker
|
||||||
// `xl.meta` if it does not exist and we creating a new delete-marker.
|
// will force creating a new `xl.meta` to create a new delete marker
|
||||||
func (s *xlStorage) DeleteVersion(ctx context.Context, volume, path string, fi FileInfo) error {
|
func (s *xlStorage) DeleteVersion(ctx context.Context, volume, path string, fi FileInfo, forceDelMarker bool) error {
|
||||||
if HasSuffix(path, SlashSeparator) {
|
if HasSuffix(path, SlashSeparator) {
|
||||||
return s.Delete(ctx, volume, path, false)
|
return s.Delete(ctx, volume, path, false)
|
||||||
}
|
}
|
||||||
@ -898,7 +898,7 @@ func (s *xlStorage) DeleteVersion(ctx context.Context, volume, path string, fi F
|
|||||||
if err != errFileNotFound {
|
if err != errFileNotFound {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if fi.Deleted {
|
if fi.Deleted && forceDelMarker {
|
||||||
// Create a new xl.meta with a delete marker in it
|
// Create a new xl.meta with a delete marker in it
|
||||||
return s.WriteMetadata(ctx, volume, path, fi)
|
return s.WriteMetadata(ctx, volume, path, fi)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user