fix: Preserve old data appropriately (#9873)

This PR fixes all the below scenarios
and handles them correctly.

- existing data/bucket is replaced with
  new content, no versioning enabled old
  structure vanishes.

- existing data/bucket - enable versioning
  before uploading any data, once versioning
  enabled upload new content, old content
  is preserved.

- suspend versioning on the bucket again, now
  upload content again the old content is purged
  since that is the default "null" version.

Additionally sync data after xl.json -> xl.meta
rename(), to avoid any surprises if there is a
crash during this rename operation.
master
Harshavardhana 4 years ago committed by GitHub
parent b912c8f035
commit 9626a981bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 23
      cmd/xl-storage.go

@ -1231,6 +1231,10 @@ func (s *xlStorage) renameLegacyMetadata(volume, path string) error {
srcFilePath := pathJoin(filePath, xlStorageFormatFileV1) srcFilePath := pathJoin(filePath, xlStorageFormatFileV1)
dstFilePath := pathJoin(filePath, xlStorageFormatFile) dstFilePath := pathJoin(filePath, xlStorageFormatFile)
// Renaming xl.json to xl.meta should be fully synced to disk.
defer globalSync()
if err = os.Rename(srcFilePath, dstFilePath); err != nil { if err = os.Rename(srcFilePath, dstFilePath); err != nil {
switch { switch {
case isSysErrNotDir(err): case isSysErrNotDir(err):
@ -2028,8 +2032,20 @@ func (s *xlStorage) RenameData(srcVolume, srcPath, dataDir, dstVolume, dstPath s
} }
dstBuf, err := ioutil.ReadFile(dstFilePath) dstBuf, err := ioutil.ReadFile(dstFilePath)
if err != nil && !os.IsNotExist(err) { if err != nil {
return osErrToFileErr(err) if !os.IsNotExist(err) {
return osErrToFileErr(err)
}
err = s.renameLegacyMetadata(dstVolume, dstPath)
if err != nil && err != errFileNotFound {
return err
}
if err == nil {
dstBuf, err = ioutil.ReadFile(dstFilePath)
if err != nil && !os.IsNotExist(err) {
return osErrToFileErr(err)
}
}
} }
var xlMeta xlMetaV2 var xlMeta xlMetaV2
@ -2093,6 +2109,9 @@ func (s *xlStorage) RenameData(srcVolume, srcPath, dataDir, dstVolume, dstPath s
return osErrToFileErr(err) return osErrToFileErr(err)
} }
// Sync all the directory operations.
globalSync()
for _, entry := range entries { for _, entry := range entries {
if entry == xlStorageFormatFile { if entry == xlStorageFormatFile {
continue continue

Loading…
Cancel
Save