| OLD | NEW |
| 1 // Copyright (c) 2013 The LevelDB Authors. All rights reserved. | 1 // Copyright (c) 2013 The LevelDB Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. See the AUTHORS file for names of contributors. | 3 // found in the LICENSE file. See the AUTHORS file for names of contributors. |
| 4 | 4 |
| 5 #include "base/debug/trace_event.h" | 5 #include "base/debug/trace_event.h" |
| 6 #include "base/files/file.h" |
| 6 #include "base/files/file_path.h" | 7 #include "base/files/file_path.h" |
| 7 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 8 #include "base/win/win_util.h" | 9 #include "base/win/win_util.h" |
| 9 #include "chromium_logger.h" | 10 #include "chromium_logger.h" |
| 10 #include "env_chromium_stdio.h" | 11 #include "env_chromium_stdio.h" |
| 11 #include "env_chromium_win.h" | 12 #include "env_chromium_win.h" |
| 12 | 13 |
| 13 using namespace leveldb; | 14 using namespace leveldb; |
| 14 | 15 |
| 15 namespace leveldb_env { | 16 namespace leveldb_env { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 return MakeIOErrorWin( | 84 return MakeIOErrorWin( |
| 84 filename_, GetWindowsErrorMessage(err), kSequentialFileSkip, err); | 85 filename_, GetWindowsErrorMessage(err), kSequentialFileSkip, err); |
| 85 } | 86 } |
| 86 return Status::OK(); | 87 return Status::OK(); |
| 87 } | 88 } |
| 88 }; | 89 }; |
| 89 | 90 |
| 90 class ChromiumRandomAccessFileWin : public RandomAccessFile { | 91 class ChromiumRandomAccessFileWin : public RandomAccessFile { |
| 91 private: | 92 private: |
| 92 std::string filename_; | 93 std::string filename_; |
| 93 ::base::PlatformFile file_; | 94 mutable ::base::File file_; |
| 94 const UMALogger* uma_logger_; | 95 const UMALogger* uma_logger_; |
| 95 | 96 |
| 96 public: | 97 public: |
| 97 ChromiumRandomAccessFileWin(const std::string& fname, | 98 ChromiumRandomAccessFileWin(const std::string& fname, |
| 98 ::base::PlatformFile file, | 99 ::base::File file, |
| 99 const UMALogger* uma_logger) | 100 const UMALogger* uma_logger) |
| 100 : filename_(fname), file_(file), uma_logger_(uma_logger) {} | 101 : filename_(fname), file_(file.Pass()), uma_logger_(uma_logger) {} |
| 101 virtual ~ChromiumRandomAccessFileWin() { ::base::ClosePlatformFile(file_); } | 102 virtual ~ChromiumRandomAccessFileWin() {} |
| 102 | 103 |
| 103 virtual Status Read(uint64_t offset, size_t n, Slice* result, char* scratch) | 104 virtual Status Read(uint64_t offset, size_t n, Slice* result, char* scratch) |
| 104 const { | 105 const { |
| 105 Status s; | 106 Status s; |
| 106 int r = ::base::ReadPlatformFile(file_, offset, scratch, n); | 107 int r = file_.Read(offset, scratch, n); |
| 107 *result = Slice(scratch, (r < 0) ? 0 : r); | 108 *result = Slice(scratch, (r < 0) ? 0 : r); |
| 108 if (r < 0) { | 109 if (r < 0) { |
| 109 // An error: return a non-ok status | 110 // An error: return a non-ok status |
| 110 s = MakeIOError( | 111 s = MakeIOError( |
| 111 filename_, "Could not perform read", kRandomAccessFileRead); | 112 filename_, "Could not perform read", kRandomAccessFileRead); |
| 112 uma_logger_->RecordErrorAt(kRandomAccessFileRead); | 113 uma_logger_->RecordErrorAt(kRandomAccessFileRead); |
| 113 } | 114 } |
| 114 return s; | 115 return s; |
| 115 } | 116 } |
| 116 }; | 117 }; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 Status s = SyncParent(); | 179 Status s = SyncParent(); |
| 179 if (!s.ok()) | 180 if (!s.ok()) |
| 180 return s; | 181 return s; |
| 181 tracker_->DidSyncDir(filename_); | 182 tracker_->DidSyncDir(filename_); |
| 182 } | 183 } |
| 183 | 184 |
| 184 DWORD written(0); | 185 DWORD written(0); |
| 185 if (!WriteFile(file_, data.data(), data.size(), &written, NULL)) { | 186 if (!WriteFile(file_, data.data(), data.size(), &written, NULL)) { |
| 186 DWORD err = GetLastError(); | 187 DWORD err = GetLastError(); |
| 187 uma_logger_->RecordOSError(kWritableFileAppend, | 188 uma_logger_->RecordOSError(kWritableFileAppend, |
| 188 base::LastErrorToPlatformFileError(err)); | 189 base::File::OSErrorToFileError(err)); |
| 189 return MakeIOErrorWin( | 190 return MakeIOErrorWin( |
| 190 filename_, GetWindowsErrorMessage(err), kWritableFileAppend, err); | 191 filename_, GetWindowsErrorMessage(err), kWritableFileAppend, err); |
| 191 } | 192 } |
| 192 return Status::OK(); | 193 return Status::OK(); |
| 193 } | 194 } |
| 194 | 195 |
| 195 Status ChromiumWritableFileWin::Close() { | 196 Status ChromiumWritableFileWin::Close() { |
| 196 Status result; | 197 Status result; |
| 197 DCHECK(file_ != INVALID_HANDLE_VALUE); | 198 DCHECK(file_ != INVALID_HANDLE_VALUE); |
| 198 if (!CloseHandle(file_)) { | 199 if (!CloseHandle(file_)) { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 } | 256 } |
| 256 } | 257 } |
| 257 | 258 |
| 258 void ChromiumEnvWin::RecordOpenFilesLimit(const std::string& type) { | 259 void ChromiumEnvWin::RecordOpenFilesLimit(const std::string& type) { |
| 259 // The Windows POSIX implementation (which this class doesn't use) | 260 // The Windows POSIX implementation (which this class doesn't use) |
| 260 // has an open file limit, but when using the Win32 API this is limited by | 261 // has an open file limit, but when using the Win32 API this is limited by |
| 261 // available memory, so no value to report. | 262 // available memory, so no value to report. |
| 262 } | 263 } |
| 263 | 264 |
| 264 Status ChromiumEnvWin::NewRandomAccessFile(const std::string& fname, | 265 Status ChromiumEnvWin::NewRandomAccessFile(const std::string& fname, |
| 265 RandomAccessFile** result) { | 266 RandomAccessFile** result) { |
| 266 int flags = ::base::PLATFORM_FILE_READ | ::base::PLATFORM_FILE_OPEN; | 267 int flags = ::base::File::FLAG_READ | ::base::File::FLAG_OPEN; |
| 267 bool created; | 268 ::base::File file(ChromiumEnv::CreateFilePath(fname), flags); |
| 268 ::base::PlatformFileError error_code; | 269 if (file.IsValid()) { |
| 269 ::base::PlatformFile file = ::base::CreatePlatformFile( | 270 *result = new ChromiumRandomAccessFileWin(fname, file.Pass(), this); |
| 270 ChromiumEnv::CreateFilePath(fname), flags, &created, &error_code); | |
| 271 if (error_code == ::base::PLATFORM_FILE_OK) { | |
| 272 *result = new ChromiumRandomAccessFileWin(fname, file, this); | |
| 273 RecordOpenFilesLimit("Success"); | 271 RecordOpenFilesLimit("Success"); |
| 274 return Status::OK(); | 272 return Status::OK(); |
| 275 } | 273 } |
| 276 if (error_code == ::base::PLATFORM_FILE_ERROR_TOO_MANY_OPENED) | 274 ::base::File::Error error_code = file.error_details(); |
| 275 if (error_code == ::base::File::FILE_ERROR_TOO_MANY_OPENED) |
| 277 RecordOpenFilesLimit("TooManyOpened"); | 276 RecordOpenFilesLimit("TooManyOpened"); |
| 278 else | 277 else |
| 279 RecordOpenFilesLimit("OtherError"); | 278 RecordOpenFilesLimit("OtherError"); |
| 280 *result = NULL; | 279 *result = NULL; |
| 281 RecordOSError(kNewRandomAccessFile, error_code); | 280 RecordOSError(kNewRandomAccessFile, error_code); |
| 282 return MakeIOErrorWin(fname, | 281 return MakeIOErrorWin(fname, |
| 283 PlatformFileErrorString(error_code), | 282 FileErrorString(error_code), |
| 284 kNewRandomAccessFile, | 283 kNewRandomAccessFile, |
| 285 error_code); | 284 error_code); |
| 286 } | 285 } |
| 287 | 286 |
| 288 Status ChromiumEnvWin::NewWritableFile(const std::string& fname, | 287 Status ChromiumEnvWin::NewWritableFile(const std::string& fname, |
| 289 WritableFile** result) { | 288 WritableFile** result) { |
| 290 *result = NULL; | 289 *result = NULL; |
| 291 HANDLE f = CreateFile(base::UTF8ToUTF16(fname).c_str(), | 290 HANDLE f = CreateFile(base::UTF8ToUTF16(fname).c_str(), |
| 292 GENERIC_WRITE, | 291 GENERIC_WRITE, |
| 293 FILE_SHARE_READ, | 292 FILE_SHARE_READ, |
| 294 NULL, | 293 NULL, |
| 295 CREATE_ALWAYS, | 294 CREATE_ALWAYS, |
| 296 FILE_ATTRIBUTE_NORMAL, | 295 FILE_ATTRIBUTE_NORMAL, |
| 297 NULL); | 296 NULL); |
| 298 if (f == INVALID_HANDLE_VALUE) { | 297 if (f == INVALID_HANDLE_VALUE) { |
| 299 DWORD err = GetLastError(); | 298 DWORD err = GetLastError(); |
| 300 RecordErrorAt(kNewWritableFile); | 299 RecordErrorAt(kNewWritableFile); |
| 301 return MakeIOErrorWin( | 300 return MakeIOErrorWin( |
| 302 fname, GetWindowsErrorMessage(err), kNewWritableFile, err); | 301 fname, GetWindowsErrorMessage(err), kNewWritableFile, err); |
| 303 } else { | 302 } else { |
| 304 *result = new ChromiumWritableFileWin(fname, f, this, this, make_backup_); | 303 *result = new ChromiumWritableFileWin(fname, f, this, this, make_backup_); |
| 305 return Status::OK(); | 304 return Status::OK(); |
| 306 } | 305 } |
| 307 } | 306 } |
| 308 | 307 |
| 309 base::PlatformFileError ChromiumEnvWin::GetDirectoryEntries( | 308 base::File::Error ChromiumEnvWin::GetDirectoryEntries( |
| 310 const base::FilePath& dir_param, | 309 const base::FilePath& dir_param, |
| 311 std::vector<base::FilePath>* result) const { | 310 std::vector<base::FilePath>* result) const { |
| 312 result->clear(); | 311 result->clear(); |
| 313 base::FilePath dir_filepath = dir_param.Append(FILE_PATH_LITERAL("*")); | 312 base::FilePath dir_filepath = dir_param.Append(FILE_PATH_LITERAL("*")); |
| 314 WIN32_FIND_DATA find_data; | 313 WIN32_FIND_DATA find_data; |
| 315 HANDLE find_handle = FindFirstFile(dir_filepath.value().c_str(), &find_data); | 314 HANDLE find_handle = FindFirstFile(dir_filepath.value().c_str(), &find_data); |
| 316 if (find_handle == INVALID_HANDLE_VALUE) { | 315 if (find_handle == INVALID_HANDLE_VALUE) { |
| 317 DWORD last_error = GetLastError(); | 316 DWORD last_error = GetLastError(); |
| 318 if (last_error == ERROR_FILE_NOT_FOUND) | 317 if (last_error == ERROR_FILE_NOT_FOUND) |
| 319 return base::PLATFORM_FILE_OK; | 318 return base::File::FILE_OK; |
| 320 return base::LastErrorToPlatformFileError(last_error); | 319 return base::File::OSErrorToFileError(last_error); |
| 321 } | 320 } |
| 322 do { | 321 do { |
| 323 base::FilePath filepath(find_data.cFileName); | 322 base::FilePath filepath(find_data.cFileName); |
| 324 base::FilePath::StringType basename = filepath.BaseName().value(); | 323 base::FilePath::StringType basename = filepath.BaseName().value(); |
| 325 if (basename == FILE_PATH_LITERAL(".") || | 324 if (basename == FILE_PATH_LITERAL(".") || |
| 326 basename == FILE_PATH_LITERAL("..")) | 325 basename == FILE_PATH_LITERAL("..")) |
| 327 continue; | 326 continue; |
| 328 result->push_back(filepath.BaseName()); | 327 result->push_back(filepath.BaseName()); |
| 329 } while (FindNextFile(find_handle, &find_data)); | 328 } while (FindNextFile(find_handle, &find_data)); |
| 330 DWORD last_error = GetLastError(); | 329 DWORD last_error = GetLastError(); |
| 331 base::PlatformFileError return_value = base::PLATFORM_FILE_OK; | 330 base::File::Error return_value = base::File::FILE_OK; |
| 332 if (last_error != ERROR_NO_MORE_FILES) | 331 if (last_error != ERROR_NO_MORE_FILES) |
| 333 return_value = base::LastErrorToPlatformFileError(last_error); | 332 return_value = base::File::OSErrorToFileError(last_error); |
| 334 FindClose(find_handle); | 333 FindClose(find_handle); |
| 335 return return_value; | 334 return return_value; |
| 336 } | 335 } |
| 337 | 336 |
| 338 Status ChromiumEnvWin::NewLogger(const std::string& fname, Logger** result) { | 337 Status ChromiumEnvWin::NewLogger(const std::string& fname, Logger** result) { |
| 339 FILE* f = _wfopen(base::UTF8ToUTF16(fname).c_str(), L"w"); | 338 FILE* f = _wfopen(base::UTF8ToUTF16(fname).c_str(), L"w"); |
| 340 if (f == NULL) { | 339 if (f == NULL) { |
| 341 *result = NULL; | 340 *result = NULL; |
| 342 int saved_errno = errno; | 341 int saved_errno = errno; |
| 343 RecordOSError(kNewLogger, saved_errno); | 342 RecordOSError(kNewLogger, saved_errno); |
| 344 return MakeIOError(fname, strerror(saved_errno), kNewLogger, saved_errno); | 343 return MakeIOError(fname, strerror(saved_errno), kNewLogger, saved_errno); |
| 345 } else { | 344 } else { |
| 346 *result = new ChromiumLogger(f); | 345 *result = new ChromiumLogger(f); |
| 347 return Status::OK(); | 346 return Status::OK(); |
| 348 } | 347 } |
| 349 } | 348 } |
| 350 | 349 |
| 351 void ChromiumEnvWin::RecordOSError(MethodID method, DWORD error) const { | 350 void ChromiumEnvWin::RecordOSError(MethodID method, DWORD error) const { |
| 352 RecordErrorAt(method); | 351 RecordErrorAt(method); |
| 353 GetOSErrorHistogram(method, ERANGE + 1)->Add(error); | 352 GetOSErrorHistogram(method, ERANGE + 1)->Add(error); |
| 354 } | 353 } |
| 355 | 354 |
| 356 } // namespace leveldb_env | 355 } // namespace leveldb_env |
| OLD | NEW |