Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Side by Side Diff: third_party/leveldatabase/env_chromium.cc

Issue 11445030: Add sync of parent directory when creating or renaming a file. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Correct flag to open() for directory. Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 1 // Copyright (c) 2011 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 <deque> 5 #include <deque>
6 #include <errno.h> 6 #include <errno.h>
7 #include <stdio.h> 7 #include <stdio.h>
8 #include "base/at_exit.h" 8 #include "base/at_exit.h"
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 13 matching lines...) Expand all
24 #include "leveldb/env.h" 24 #include "leveldb/env.h"
25 #include "leveldb/slice.h" 25 #include "leveldb/slice.h"
26 #include "port/port.h" 26 #include "port/port.h"
27 #include "util/logging.h" 27 #include "util/logging.h"
28 28
29 #if defined(OS_WIN) 29 #if defined(OS_WIN)
30 #include <io.h> 30 #include <io.h>
31 #include "base/win/win_util.h" 31 #include "base/win/win_util.h"
32 #endif 32 #endif
33 33
34 #if !defined(OS_WIN)
35 #include <fcntl.h>
36 #endif
37
34 namespace { 38 namespace {
35 39
36 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID) || \ 40 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID) || \
37 defined(OS_OPENBSD) 41 defined(OS_OPENBSD)
38 // The following are glibc-specific 42 // The following are glibc-specific
39 43
40 size_t fread_unlocked(void *ptr, size_t size, size_t n, FILE *file) { 44 size_t fread_unlocked(void *ptr, size_t size, size_t n, FILE *file) {
41 return fread(ptr, size, n, file); 45 return fread(ptr, size, n, file);
42 } 46 }
43 47
(...skipping 19 matching lines...) Expand all
63 67
64 // Wide-char safe fopen wrapper. 68 // Wide-char safe fopen wrapper.
65 FILE* fopen_internal(const char* fname, const char* mode) { 69 FILE* fopen_internal(const char* fname, const char* mode) {
66 #if defined(OS_WIN) 70 #if defined(OS_WIN)
67 return _wfopen(UTF8ToUTF16(fname).c_str(), ASCIIToUTF16(mode).c_str()); 71 return _wfopen(UTF8ToUTF16(fname).c_str(), ASCIIToUTF16(mode).c_str());
68 #else 72 #else
69 return fopen(fname, mode); 73 return fopen(fname, mode);
70 #endif 74 #endif
71 } 75 }
72 76
77 ::FilePath CreateFilePath(const std::string& file_path) {
78 #if defined(OS_WIN)
79 return FilePath(UTF8ToUTF16(file_path));
80 #else
81 return FilePath(file_path);
82 #endif
83 }
84
85 std::string FilePathToString(const ::FilePath& file_path) {
86 #if defined(OS_WIN)
87 return UTF16ToUTF8(file_path.value());
88 #else
89 return file_path.value();
90 #endif
91 }
92
93 bool sync_parent(const std::string& fname) {
94 #if !defined(OS_WIN)
dgrogan 2013/05/28 22:02:19 What was the impetus for skipping this on windows?
ericu 2013/05/28 22:05:25 I asked Siggi, and he said that on Windows there w
95 FilePath parent_dir = CreateFilePath(fname).DirName();
96 int parent_fd = open(FilePathToString(parent_dir).c_str(), O_RDONLY);
97 if (parent_fd < 0)
98 return false;
99 fsync(parent_fd);
100 close(parent_fd);
101 #endif
102 return true;
103 }
104
73 enum UmaEntry { 105 enum UmaEntry {
74 kSequentialFileRead, 106 kSequentialFileRead,
75 kSequentialFileSkip, 107 kSequentialFileSkip,
76 kRandomAccessFileRead, 108 kRandomAccessFileRead,
77 kWritableFileAppend, 109 kWritableFileAppend,
78 kWritableFileClose, 110 kWritableFileClose,
79 kWritableFileFlush, 111 kWritableFileFlush,
80 kWritableFileSync, 112 kWritableFileSync,
81 kNewSequentialFile, 113 kNewSequentialFile,
82 kNewRandomAccessFile, 114 kNewRandomAccessFile,
(...skipping 18 matching lines...) Expand all
101 133
102 namespace leveldb { 134 namespace leveldb {
103 135
104 namespace { 136 namespace {
105 137
106 class Thread; 138 class Thread;
107 139
108 static const ::FilePath::CharType kLevelDBTestDirectoryPrefix[] 140 static const ::FilePath::CharType kLevelDBTestDirectoryPrefix[]
109 = FILE_PATH_LITERAL("leveldb-test-"); 141 = FILE_PATH_LITERAL("leveldb-test-");
110 142
111 ::FilePath CreateFilePath(const std::string& file_path) {
112 #if defined(OS_WIN)
113 return FilePath(UTF8ToUTF16(file_path));
114 #else
115 return FilePath(file_path);
116 #endif
117 }
118
119 std::string FilePathToString(const ::FilePath& file_path) {
120 #if defined(OS_WIN)
121 return UTF16ToUTF8(file_path.value());
122 #else
123 return file_path.value();
124 #endif
125 }
126
127 // TODO(jorlow): This should be moved into Chromium's base. 143 // TODO(jorlow): This should be moved into Chromium's base.
128 const char* PlatformFileErrorString(const ::base::PlatformFileError& error) { 144 const char* PlatformFileErrorString(const ::base::PlatformFileError& error) {
129 switch (error) { 145 switch (error) {
130 case ::base::PLATFORM_FILE_ERROR_FAILED: 146 case ::base::PLATFORM_FILE_ERROR_FAILED:
131 return "Opening file failed."; 147 return "Opening file failed.";
132 case ::base::PLATFORM_FILE_ERROR_IN_USE: 148 case ::base::PLATFORM_FILE_ERROR_IN_USE:
133 return "File currently in use."; 149 return "File currently in use.";
134 case ::base::PLATFORM_FILE_ERROR_EXISTS: 150 case ::base::PLATFORM_FILE_ERROR_EXISTS:
135 return "File already exists."; 151 return "File already exists.";
136 case ::base::PLATFORM_FILE_ERROR_NOT_FOUND: 152 case ::base::PLATFORM_FILE_ERROR_NOT_FOUND:
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 } 337 }
322 338
323 virtual Status NewWritableFile(const std::string& fname, 339 virtual Status NewWritableFile(const std::string& fname,
324 WritableFile** result) { 340 WritableFile** result) {
325 *result = NULL; 341 *result = NULL;
326 FILE* f = fopen_internal(fname.c_str(), "wb"); 342 FILE* f = fopen_internal(fname.c_str(), "wb");
327 if (f == NULL) { 343 if (f == NULL) {
328 LogToUMA(kNewWritableFile); 344 LogToUMA(kNewWritableFile);
329 return Status::IOError(fname, strerror(errno)); 345 return Status::IOError(fname, strerror(errno));
330 } else { 346 } else {
347 if (!sync_parent(fname)) {
348 fclose(f);
349 return Status::IOError(fname, strerror(errno));
350 }
331 *result = new ChromiumWritableFile(fname, f); 351 *result = new ChromiumWritableFile(fname, f);
332 return Status::OK(); 352 return Status::OK();
333 } 353 }
334 } 354 }
335 355
336 virtual bool FileExists(const std::string& fname) { 356 virtual bool FileExists(const std::string& fname) {
337 return ::file_util::PathExists(CreateFilePath(fname)); 357 return ::file_util::PathExists(CreateFilePath(fname));
338 } 358 }
339 359
340 virtual Status GetChildren(const std::string& dir, 360 virtual Status GetChildren(const std::string& dir,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 *size = static_cast<uint64_t>(signed_size); 413 *size = static_cast<uint64_t>(signed_size);
394 } 414 }
395 return s; 415 return s;
396 } 416 }
397 417
398 virtual Status RenameFile(const std::string& src, const std::string& dst) { 418 virtual Status RenameFile(const std::string& src, const std::string& dst) {
399 Status result; 419 Status result;
400 if (!::file_util::ReplaceFile(CreateFilePath(src), CreateFilePath(dst))) { 420 if (!::file_util::ReplaceFile(CreateFilePath(src), CreateFilePath(dst))) {
401 result = Status::IOError(src, "Could not rename file."); 421 result = Status::IOError(src, "Could not rename file.");
402 LogToUMA(kRenamefile); 422 LogToUMA(kRenamefile);
423 } else {
424 sync_parent(dst);
425 if (src != dst)
426 sync_parent(src);
403 } 427 }
404 return result; 428 return result;
405 } 429 }
406 430
407 virtual Status LockFile(const std::string& fname, FileLock** lock) { 431 virtual Status LockFile(const std::string& fname, FileLock** lock) {
408 *lock = NULL; 432 *lock = NULL;
409 Status result; 433 Status result;
410 int flags = ::base::PLATFORM_FILE_OPEN_ALWAYS | 434 int flags = ::base::PLATFORM_FILE_OPEN_ALWAYS |
411 ::base::PLATFORM_FILE_READ | 435 ::base::PLATFORM_FILE_READ |
412 ::base::PLATFORM_FILE_WRITE | 436 ::base::PLATFORM_FILE_WRITE |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 return Status::OK(); 494 return Status::OK();
471 } 495 }
472 496
473 virtual Status NewLogger(const std::string& fname, Logger** result) { 497 virtual Status NewLogger(const std::string& fname, Logger** result) {
474 FILE* f = fopen_internal(fname.c_str(), "w"); 498 FILE* f = fopen_internal(fname.c_str(), "w");
475 if (f == NULL) { 499 if (f == NULL) {
476 *result = NULL; 500 *result = NULL;
477 LogToUMA(kNewLogger); 501 LogToUMA(kNewLogger);
478 return Status::IOError(fname, strerror(errno)); 502 return Status::IOError(fname, strerror(errno));
479 } else { 503 } else {
504 if (!sync_parent(fname)) {
505 fclose(f);
506 return Status::IOError(fname, strerror(errno));
507 }
480 *result = new ChromiumLogger(f); 508 *result = new ChromiumLogger(f);
481 return Status::OK(); 509 return Status::OK();
482 } 510 }
483 } 511 }
484 512
485 virtual uint64_t NowMicros() { 513 virtual uint64_t NowMicros() {
486 return ::base::TimeTicks::Now().ToInternalValue(); 514 return ::base::TimeTicks::Now().ToInternalValue();
487 } 515 }
488 516
489 virtual void SleepForMicroseconds(int micros) { 517 virtual void SleepForMicroseconds(int micros) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 ::base::LazyInstance<ChromiumEnv>::Leaky 615 ::base::LazyInstance<ChromiumEnv>::Leaky
588 default_env = LAZY_INSTANCE_INITIALIZER; 616 default_env = LAZY_INSTANCE_INITIALIZER;
589 617
590 } 618 }
591 619
592 Env* Env::Default() { 620 Env* Env::Default() {
593 return default_env.Pointer(); 621 return default_env.Pointer();
594 } 622 }
595 623
596 } 624 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698