summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgrogan@chromium.org <dgrogan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-11 03:50:25 +0000
committerdgrogan@chromium.org <dgrogan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-11 03:50:25 +0000
commitcfd23d243ac040a088c65875aaf779aea0c29125 (patch)
treed3531b3a563d802eafcbc697f294b053c38aa98e
parentb6847730de55da964055d4965199196e3e6145dc (diff)
downloadchromium_src-cfd23d243ac040a088c65875aaf779aea0c29125.zip
chromium_src-cfd23d243ac040a088c65875aaf779aea0c29125.tar.gz
chromium_src-cfd23d243ac040a088c65875aaf779aea0c29125.tar.bz2
Make CreateDirectory return an error code instead of just a bool.
Make use of the new error code in IndexedDB, where we'll histogram which errors can be recovered from by retrying and which can't. We're going to try retrying CreateDirectory because LevelDB doesn't pay attention to what env_->CreateDir returns and a frequent error on the next operation (locking the lock file) is that the directory doesn't exist. I want to find out what's causing the directories to not be created in the first place, and which errors can be considered ephemeral. BUG=225051 Review URL: https://chromiumcodereview.appspot.com/15812007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@205386 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/file_util.cc4
-rw-r--r--base/file_util.h6
-rw-r--r--base/file_util_posix.cc9
-rw-r--r--base/file_util_win.cc7
-rw-r--r--third_party/leveldatabase/env_chromium.cc12
-rw-r--r--tools/metrics/histograms/histograms.xml1
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"/>