diff options
-rw-r--r-- | base/file_util.cc | 4 | ||||
-rw-r--r-- | base/file_util.h | 6 | ||||
-rw-r--r-- | base/file_util_posix.cc | 9 | ||||
-rw-r--r-- | base/file_util_win.cc | 7 | ||||
-rw-r--r-- | third_party/leveldatabase/env_chromium.cc | 12 | ||||
-rw-r--r-- | tools/metrics/histograms/histograms.xml | 1 |
6 files changed, 31 insertions, 8 deletions
diff --git a/base/file_util.cc b/base/file_util.cc index 1479836..0d53162 100644 --- a/base/file_util.cc +++ b/base/file_util.cc @@ -185,6 +185,10 @@ FILE* CreateAndOpenTemporaryFile(FilePath* path) { return CreateAndOpenTemporaryFileInDir(directory, path); } +bool CreateDirectory(const base::FilePath& full_path) { + return CreateDirectoryAndGetError(full_path, NULL); +} + bool GetFileSize(const FilePath& file_path, int64* file_size) { base::PlatformFileInfo info; if (!GetFileInfo(file_path, &info)) diff --git a/base/file_util.h b/base/file_util.h index 13190dc..b75a18d 100644 --- a/base/file_util.h +++ b/base/file_util.h @@ -269,6 +269,12 @@ BASE_EXPORT bool CreateTemporaryDirInDir( // Creates a directory, as well as creating any parent directories, if they // don't exist. Returns 'true' on successful creation, or if the directory // already exists. The directory is only readable by the current user. +// Returns true on success, leaving *error unchanged. +// Returns false on failure and sets *error appropriately, if it is non-NULL. +BASE_EXPORT bool CreateDirectoryAndGetError(const base::FilePath& full_path, + base::PlatformFileError* error); + +// Backward-compatible convenience method for the above. BASE_EXPORT bool CreateDirectory(const base::FilePath& full_path); // Returns the file size. Returns true on success. diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc index 8723333..5d037bf 100644 --- a/base/file_util_posix.cc +++ b/base/file_util_posix.cc @@ -518,7 +518,8 @@ bool CreateNewTempDirectory(const FilePath::StringType& prefix, return CreateTemporaryDirInDirImpl(tmpdir, TempFileName(), new_temp_path); } -bool CreateDirectory(const FilePath& full_path) { +bool CreateDirectoryAndGetError(const FilePath& full_path, + base::PlatformFileError* error) { base::ThreadRestrictions::AssertIOAllowed(); // For call to mkdir(). std::vector<FilePath> subpaths; @@ -542,8 +543,12 @@ bool CreateDirectory(const FilePath& full_path) { // due to the the directory appearing out of thin air. This can occur if // two processes are trying to create the same file system tree at the same // time. Check to see if it exists and make sure it is a directory. - if (!DirectoryExists(*i)) + int saved_errno = errno; + if (!DirectoryExists(*i)) { + if (error) + *error = base::ErrnoToPlatformFileError(saved_errno); return false; + } } return true; } diff --git a/base/file_util_win.cc b/base/file_util_win.cc index 0566247..43af529 100644 --- a/base/file_util_win.cc +++ b/base/file_util_win.cc @@ -403,7 +403,8 @@ bool CreateNewTempDirectory(const FilePath::StringType& prefix, return CreateTemporaryDirInDir(system_temp_dir, prefix, new_temp_path); } -bool CreateDirectory(const FilePath& full_path) { +bool CreateDirectoryAndGetError(const FilePath& full_path, + base::PlatformFileError* error) { base::ThreadRestrictions::AssertIOAllowed(); // If the path exists, we've succeeded if it's a directory, failed otherwise. @@ -429,7 +430,7 @@ bool CreateDirectory(const FilePath& full_path) { if (parent_path.value() == full_path.value()) { return false; } - if (!CreateDirectory(parent_path)) { + if (!CreateDirectoryAndGetError(parent_path, error)) { DLOG(WARNING) << "Failed to create one of the parent directories."; return false; } @@ -443,6 +444,8 @@ bool CreateDirectory(const FilePath& full_path) { // race to create the same directory. return true; } else { + if (error) + *error = base::LastErrorToPlatformFileError(error_code); DLOG(WARNING) << "Failed to create directory " << full_path_str << ", last error is " << error_code << "."; return false; diff --git a/third_party/leveldatabase/env_chromium.cc b/third_party/leveldatabase/env_chromium.cc index 1d2a74e..71a5c88 100644 --- a/third_party/leveldatabase/env_chromium.cc +++ b/third_party/leveldatabase/env_chromium.cc @@ -616,10 +616,14 @@ Status ChromiumEnv::DeleteFile(const std::string& fname) { Status ChromiumEnv::CreateDir(const std::string& name) { Status result; - if (!::file_util::CreateDirectory(CreateFilePath(name))) { - result = MakeIOError(name, "Could not create directory.", kCreateDir); - RecordErrorAt(kCreateDir); - } + base::PlatformFileError error = base::PLATFORM_FILE_OK; + Retrier retrier(kCreateDir, this); + do { + if (::file_util::CreateDirectoryAndGetError(CreateFilePath(name), &error)) + return result; + } while (retrier.ShouldKeepTrying(error)); + result = MakeIOError(name, "Could not create directory.", kCreateDir); + RecordErrorAt(kCreateDir); return result; } diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index ea83436..8d29061 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -17089,6 +17089,7 @@ other types of suffix sets. <fieldtrial name="LevelDBEnvRetry" separator=""> <group name="RenameFile" label="RenameFile"/> <group name="LockFile" label="LockFile"/> + <group name="CreateDir" label="CreateDir"/> <affected-histogram name="LevelDBEnv.IDB.RetryRecoveredFromErrorIn"/> <affected-histogram name="LevelDBEnv.IDB.TimeUntilSuccessFor"/> <affected-histogram name="LevelDBEnv.RetryRecoveredFromErrorIn"/> |