From dd417e54766d05257c620f69d0defd4fe6c28fc3 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 4 May 2016 12:18:40 -0700 Subject: [PATCH] fs: Handle cases of PutObject for an existing prefix. (#1478) --- object-common.go | 9 ++++++--- object-errors.go | 2 +- posix.go | 19 ++++++++++++++++--- signature-v4-postpolicyform.go | 4 ++-- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/object-common.go b/object-common.go index e5bd39096..d28b7d3bb 100644 --- a/object-common.go +++ b/object-common.go @@ -138,14 +138,14 @@ func putObjectCommon(storage StorageAPI, bucket string, object string, size int6 if clErr := safeCloseAndRemove(fileWriter); clErr != nil { return "", clErr } - return "", toObjectErr(err) + return "", toObjectErr(err, bucket, object) } } else { if _, err = io.Copy(multiWriter, data); err != nil { if clErr := safeCloseAndRemove(fileWriter); clErr != nil { return "", clErr } - return "", err + return "", toObjectErr(err, bucket, object) } } @@ -169,7 +169,10 @@ func putObjectCommon(storage StorageAPI, bucket string, object string, size int6 } err = storage.RenameFile(minioMetaBucket, tempObj, bucket, object) if err != nil { - return "", err + if derr := storage.DeleteFile(minioMetaBucket, tempObj); derr != nil { + return "", derr + } + return "", toObjectErr(err, bucket, object) } // Return md5sum, successfully wrote object. diff --git a/object-errors.go b/object-errors.go index 30a18bd97..368fad118 100644 --- a/object-errors.go +++ b/object-errors.go @@ -40,7 +40,7 @@ func toObjectErr(err error, params ...string) error { return StorageInsufficientReadResources{} case errWriteQuorum: return StorageInsufficientWriteResources{} - case errIsNotRegular: + case errIsNotRegular, errFileAccessDenied: if len(params) >= 2 { return ObjectExistsAsPrefix{ Bucket: params[0], diff --git a/posix.go b/posix.go index a0fee714b..cb35c1193 100644 --- a/posix.go +++ b/posix.go @@ -596,12 +596,13 @@ func (s fsStorage) CreateFile(volume, path string) (writeCloser io.WriteCloser, }).Debugf("getVolumeDir failed with %s", err) return nil, err } - if err := checkDiskFree(s.diskPath, s.minFreeDisk); err != nil { + if err = checkDiskFree(s.diskPath, s.minFreeDisk); err != nil { return nil, err } filePath := filepath.Join(volumeDir, path) // Verify if the file already exists and is not of regular type. - if st, err := os.Stat(filePath); err == nil { + var st os.FileInfo + if st, err = os.Stat(filePath); err == nil { if st.IsDir() { log.WithFields(logrus.Fields{ "diskPath": s.diskPath, @@ -610,7 +611,15 @@ func (s fsStorage) CreateFile(volume, path string) (writeCloser io.WriteCloser, return nil, errIsNotRegular } } - return safe.CreateFileWithPrefix(filePath, "$tmpfile") + w, err := safe.CreateFileWithPrefix(filePath, "$tmpfile") + if err != nil { + // File path cannot be verified since one of the parents is a file. + if strings.Contains(err.Error(), "not a directory") { + return nil, errFileAccessDenied + } + return nil, err + } + return w, nil } // StatFile - get file info. @@ -753,6 +762,10 @@ func (s fsStorage) RenameFile(srcVolume, srcPath, dstVolume, dstPath string) err return err } if err = os.MkdirAll(path.Join(dstVolumeDir, path.Dir(dstPath)), 0755); err != nil { + // File path cannot be verified since one of the parents is a file. + if strings.Contains(err.Error(), "not a directory") { + return errFileAccessDenied + } log.Errorf("os.MkdirAll failed with %s", err) return err } diff --git a/signature-v4-postpolicyform.go b/signature-v4-postpolicyform.go index 0abf54d6b..e1f26289c 100644 --- a/signature-v4-postpolicyform.go +++ b/signature-v4-postpolicyform.go @@ -157,8 +157,8 @@ func checkPostPolicy(formValues map[string]string) APIErrorCode { return ErrSignatureVersionNotSupported } /// Decoding policy - policyBytes, e := base64.StdEncoding.DecodeString(formValues["Policy"]) - if e != nil { + policyBytes, err := base64.StdEncoding.DecodeString(formValues["Policy"]) + if err != nil { return ErrMalformedPOSTRequest } postPolicyForm, err := parsePostPolicyFormV4(string(policyBytes))