mirror of
https://github.com/minio/minio.git
synced 2025-05-21 17:43:48 -04:00
xl: fix DeleteFile() removing meta data files without updating it (#1433)
Fixes #1428 #1427
This commit is contained in:
parent
27c50a70cc
commit
84afec9ae0
@ -558,25 +558,29 @@ func (xl XL) DeleteFile(volume, path string) error {
|
|||||||
versions, err := listFileVersions(partsMetadata, errs)
|
versions, err := listFileVersions(partsMetadata, errs)
|
||||||
// Get highest file version.
|
// Get highest file version.
|
||||||
higherVersion := highestInt(versions)
|
higherVersion := highestInt(versions)
|
||||||
// Increment to have next higher version.
|
|
||||||
higherVersion++
|
|
||||||
|
|
||||||
// Take last meta data to use later
|
// find online disks and meta data of higherVersion
|
||||||
var mdata xlMetaV1
|
var mdata *xlMetaV1
|
||||||
onlineDisksCount := 0
|
onlineDiskCount := 0
|
||||||
for index, metadata := range partsMetadata {
|
for index, metadata := range partsMetadata {
|
||||||
if errs[index] == nil {
|
if errs[index] == nil {
|
||||||
mdata = metadata
|
onlineDiskCount++
|
||||||
onlineDisksCount++
|
if metadata.Stat.Version == higherVersion && mdata == nil {
|
||||||
|
mdata = &metadata
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if onlineDisksCount < xl.writeQuorum {
|
// return error if mdata is empty or onlineDiskCount doesn't meet write quorum
|
||||||
|
if mdata == nil || onlineDiskCount < xl.writeQuorum {
|
||||||
return errWriteQuorum
|
return errWriteQuorum
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Increment to have next higher version.
|
||||||
|
higherVersion++
|
||||||
|
|
||||||
xlMetaV1FilePath := slashpath.Join(path, xlMetaV1File)
|
xlMetaV1FilePath := slashpath.Join(path, xlMetaV1File)
|
||||||
deleteMetaData := (onlineDisksCount == len(xl.storageDisks))
|
deleteMetaData := (onlineDiskCount == len(xl.storageDisks))
|
||||||
|
|
||||||
// Set higher version to indicate file operation
|
// Set higher version to indicate file operation
|
||||||
mdata.Stat.Version = higherVersion
|
mdata.Stat.Version = higherVersion
|
||||||
@ -585,25 +589,16 @@ func (xl XL) DeleteFile(volume, path string) error {
|
|||||||
nsMutex.Lock(volume, path)
|
nsMutex.Lock(volume, path)
|
||||||
defer nsMutex.Unlock(volume, path)
|
defer nsMutex.Unlock(volume, path)
|
||||||
|
|
||||||
// Loop through and delete each chunks.
|
errCount := 0
|
||||||
|
// Update meta data file and remove part file
|
||||||
for index, disk := range xl.storageDisks {
|
for index, disk := range xl.storageDisks {
|
||||||
|
// no need to operate on failed disks
|
||||||
if errs[index] != nil {
|
if errs[index] != nil {
|
||||||
|
errCount++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: errors can be allowed up to len(xl.storageDisks) - xl.writeQuorum
|
// update meta data about delete operation
|
||||||
// TODO: Fix: meta data will be lost if deleteMetaData is true and anyone DeleteFile failure.
|
|
||||||
|
|
||||||
if deleteMetaData {
|
|
||||||
err = disk.DeleteFile(volume, xlMetaV1FilePath)
|
|
||||||
if err != nil {
|
|
||||||
log.WithFields(logrus.Fields{
|
|
||||||
"volume": volume,
|
|
||||||
"path": path,
|
|
||||||
}).Errorf("DeleteFile failed with %s", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var metadataWriter io.WriteCloser
|
var metadataWriter io.WriteCloser
|
||||||
metadataWriter, err = disk.CreateFile(volume, xlMetaV1FilePath)
|
metadataWriter, err = disk.CreateFile(volume, xlMetaV1FilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -611,6 +606,15 @@ func (xl XL) DeleteFile(volume, path string) error {
|
|||||||
"volume": volume,
|
"volume": volume,
|
||||||
"path": path,
|
"path": path,
|
||||||
}).Errorf("CreateFile failed with %s", err)
|
}).Errorf("CreateFile failed with %s", err)
|
||||||
|
|
||||||
|
errCount++
|
||||||
|
|
||||||
|
// We can safely allow CreateFile errors up to len(xl.storageDisks) - xl.writeQuorum
|
||||||
|
// otherwise return failure.
|
||||||
|
if errCount <= len(xl.storageDisks)-xl.writeQuorum {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,8 +625,16 @@ func (xl XL) DeleteFile(volume, path string) error {
|
|||||||
"path": path,
|
"path": path,
|
||||||
"diskIndex": index,
|
"diskIndex": index,
|
||||||
}).Errorf("Writing metadata failed with %s", err)
|
}).Errorf("Writing metadata failed with %s", err)
|
||||||
return err
|
|
||||||
|
errCount++
|
||||||
|
|
||||||
|
// We can safely allow CreateFile errors up to len(xl.storageDisks) - xl.writeQuorum
|
||||||
|
// otherwise return failure.
|
||||||
|
if errCount <= len(xl.storageDisks)-xl.writeQuorum {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
erasureFilePart := slashpath.Join(path, fmt.Sprintf("file.%d", index))
|
erasureFilePart := slashpath.Join(path, fmt.Sprintf("file.%d", index))
|
||||||
@ -632,9 +644,38 @@ func (xl XL) DeleteFile(volume, path string) error {
|
|||||||
"volume": volume,
|
"volume": volume,
|
||||||
"path": path,
|
"path": path,
|
||||||
}).Errorf("DeleteFile failed with %s", err)
|
}).Errorf("DeleteFile failed with %s", err)
|
||||||
|
|
||||||
|
errCount++
|
||||||
|
|
||||||
|
// We can safely allow CreateFile errors up to len(xl.storageDisks) - xl.writeQuorum
|
||||||
|
// otherwise return failure.
|
||||||
|
if errCount <= len(xl.storageDisks)-xl.writeQuorum {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove meta data file only if deleteMetaData is true.
|
||||||
|
if deleteMetaData {
|
||||||
|
for index, disk := range xl.storageDisks {
|
||||||
|
// no need to operate on failed disks
|
||||||
|
if errs[index] != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
err = disk.DeleteFile(volume, xlMetaV1FilePath)
|
||||||
|
if err != nil {
|
||||||
|
// No need to return the error as we updated the meta data file previously
|
||||||
|
log.WithFields(logrus.Fields{
|
||||||
|
"volume": volume,
|
||||||
|
"path": path,
|
||||||
|
}).Errorf("DeleteFile failed with %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user