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

Side by Side Diff: webkit/fileapi/file_system_origin_database.cc

Issue 9663021: Add database recovery for FileSystemOriginDatabase (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: bool -> enum Created 8 years, 9 months 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium 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. 3 // found in the LICENSE file.
4 4
5 #include "webkit/fileapi/file_system_origin_database.h" 5 #include "webkit/fileapi/file_system_origin_database.h"
6 6
7 #include "base/format_macros.h" 7 #include "base/format_macros.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/string_number_conversions.h" 10 #include "base/string_number_conversions.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 #if defined(OS_POSIX) 47 #if defined(OS_POSIX)
48 path_ = path.value(); 48 path_ = path.value();
49 #elif defined(OS_WIN) 49 #elif defined(OS_WIN)
50 path_ = base::SysWideToUTF8(path.value()); 50 path_ = base::SysWideToUTF8(path.value());
51 #endif 51 #endif
52 } 52 }
53 53
54 FileSystemOriginDatabase::~FileSystemOriginDatabase() { 54 FileSystemOriginDatabase::~FileSystemOriginDatabase() {
55 } 55 }
56 56
57 bool FileSystemOriginDatabase::Init() { 57 bool FileSystemOriginDatabase::Init(RecoveringOption recovering_option) {
58 if (db_.get()) 58 if (db_.get())
59 return true; 59 return true;
60 60
61 leveldb::Options options; 61 leveldb::Options options;
62 options.create_if_missing = true; 62 options.create_if_missing = true;
63 leveldb::DB* db; 63 leveldb::DB* db;
64 leveldb::Status status = leveldb::DB::Open(options, path_, &db); 64 leveldb::Status status = leveldb::DB::Open(options, path_, &db);
65 // TODO(tzik): Collect status metrics here.
65 if (status.ok()) { 66 if (status.ok()) {
66 db_.reset(db); 67 db_.reset(db);
67 return true; 68 return true;
68 } 69 }
69 HandleError(FROM_HERE, status); 70 HandleError(FROM_HERE, status);
71
72 if (recovering_option == LEAVE_ON_CORRUPTION)
73 return false;
74
75 DCHECK_EQ(REBUILD_ON_CORRUPTION, recovering_option);
76 LOG(WARNING) << "FileSystem API origin database is corrupted."
77 << " Attempting cleanup.";
78 if (leveldb::DestroyDB(path_, leveldb::Options()).ok()) {
michaeln 2012/03/11 17:40:10 once we've lost this database of all origins using
ericu 2012/03/12 19:46:01 Yes. If we lose the origins database, we have no
79 LOG(WARNING) << "FileSystem API origin database cleanup completed."
80 << " Reopening.";
81 return Init(LEAVE_ON_CORRUPTION);
82 }
83 LOG(WARNING) << "Failed to cleanup FileSystem API origin database.";
70 return false; 84 return false;
71 } 85 }
72 86
73 void FileSystemOriginDatabase::HandleError( 87 void FileSystemOriginDatabase::HandleError(
74 const tracked_objects::Location& from_here, leveldb::Status status) { 88 const tracked_objects::Location& from_here, leveldb::Status status) {
75 db_.reset(); 89 db_.reset();
76 LOG(ERROR) << "FileSystemOriginDatabase failed at: " 90 LOG(ERROR) << "FileSystemOriginDatabase failed at: "
77 << from_here.ToString() << " with error: " << status.ToString(); 91 << from_here.ToString() << " with error: " << status.ToString();
78 } 92 }
79 93
80 bool FileSystemOriginDatabase::HasOriginPath(const std::string& origin) { 94 bool FileSystemOriginDatabase::HasOriginPath(const std::string& origin) {
81 if (!Init()) 95 if (!Init(REBUILD_ON_CORRUPTION))
82 return false; 96 return false;
83 if (origin.empty()) 97 if (origin.empty())
84 return false; 98 return false;
85 std::string path; 99 std::string path;
86 leveldb::Status status = 100 leveldb::Status status =
87 db_->Get(leveldb::ReadOptions(), OriginToOriginKey(origin), &path); 101 db_->Get(leveldb::ReadOptions(), OriginToOriginKey(origin), &path);
88 if (status.ok()) 102 if (status.ok())
89 return true; 103 return true;
90 if (status.IsNotFound()) 104 if (status.IsNotFound())
91 return false; 105 return false;
92 HandleError(FROM_HERE, status); 106 HandleError(FROM_HERE, status);
93 return false; 107 return false;
94 } 108 }
95 109
96 bool FileSystemOriginDatabase::GetPathForOrigin( 110 bool FileSystemOriginDatabase::GetPathForOrigin(
97 const std::string& origin, FilePath* directory) { 111 const std::string& origin, FilePath* directory) {
98 if (!Init()) 112 if (!Init(REBUILD_ON_CORRUPTION))
99 return false; 113 return false;
100 DCHECK(directory); 114 DCHECK(directory);
101 if (origin.empty()) 115 if (origin.empty())
102 return false; 116 return false;
103 std::string path_string; 117 std::string path_string;
104 std::string origin_key = OriginToOriginKey(origin); 118 std::string origin_key = OriginToOriginKey(origin);
105 leveldb::Status status = 119 leveldb::Status status =
106 db_->Get(leveldb::ReadOptions(), origin_key, &path_string); 120 db_->Get(leveldb::ReadOptions(), origin_key, &path_string);
107 if (status.IsNotFound()) { 121 if (status.IsNotFound()) {
108 int last_path_number; 122 int last_path_number;
(...skipping 16 matching lines...) Expand all
125 #elif defined(OS_WIN) 139 #elif defined(OS_WIN)
126 *directory = FilePath(base::SysUTF8ToWide(path_string)); 140 *directory = FilePath(base::SysUTF8ToWide(path_string));
127 #endif 141 #endif
128 return true; 142 return true;
129 } 143 }
130 HandleError(FROM_HERE, status); 144 HandleError(FROM_HERE, status);
131 return false; 145 return false;
132 } 146 }
133 147
134 bool FileSystemOriginDatabase::RemovePathForOrigin(const std::string& origin) { 148 bool FileSystemOriginDatabase::RemovePathForOrigin(const std::string& origin) {
135 if (!Init()) 149 if (!Init(REBUILD_ON_CORRUPTION))
136 return false; 150 return false;
137 leveldb::Status status = 151 leveldb::Status status =
138 db_->Delete(leveldb::WriteOptions(), OriginToOriginKey(origin)); 152 db_->Delete(leveldb::WriteOptions(), OriginToOriginKey(origin));
139 if (status.ok() || status.IsNotFound()) 153 if (status.ok() || status.IsNotFound())
140 return true; 154 return true;
141 HandleError(FROM_HERE, status); 155 HandleError(FROM_HERE, status);
142 return false; 156 return false;
143 } 157 }
144 158
145 bool FileSystemOriginDatabase::ListAllOrigins( 159 bool FileSystemOriginDatabase::ListAllOrigins(
146 std::vector<OriginRecord>* origins) { 160 std::vector<OriginRecord>* origins) {
147 if (!Init()) 161 if (!Init(REBUILD_ON_CORRUPTION))
148 return false; 162 return false;
149 DCHECK(origins); 163 DCHECK(origins);
150 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions())); 164 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions()));
151 std::string origin_key_prefix = OriginToOriginKey(""); 165 std::string origin_key_prefix = OriginToOriginKey("");
152 iter->Seek(origin_key_prefix); 166 iter->Seek(origin_key_prefix);
153 origins->clear(); 167 origins->clear();
154 while(iter->Valid() && 168 while(iter->Valid() &&
155 StartsWithASCII(iter->key().ToString(), origin_key_prefix, true)) { 169 StartsWithASCII(iter->key().ToString(), origin_key_prefix, true)) {
156 std::string origin = 170 std::string origin =
157 iter->key().ToString().substr(origin_key_prefix.length()); 171 iter->key().ToString().substr(origin_key_prefix.length());
158 #if defined(OS_POSIX) 172 #if defined(OS_POSIX)
159 FilePath path = FilePath(iter->value().ToString()); 173 FilePath path = FilePath(iter->value().ToString());
160 #elif defined(OS_WIN) 174 #elif defined(OS_WIN)
161 FilePath path = FilePath(base::SysUTF8ToWide(iter->value().ToString())); 175 FilePath path = FilePath(base::SysUTF8ToWide(iter->value().ToString()));
162 #endif 176 #endif
163 origins->push_back(OriginRecord(origin, path)); 177 origins->push_back(OriginRecord(origin, path));
164 iter->Next(); 178 iter->Next();
165 } 179 }
166 return true; 180 return true;
167 } 181 }
168 182
169 void FileSystemOriginDatabase::DropDatabase() { 183 void FileSystemOriginDatabase::DropDatabase() {
170 db_.reset(); 184 db_.reset();
171 } 185 }
172 186
173 bool FileSystemOriginDatabase::GetLastPathNumber(int* number) { 187 bool FileSystemOriginDatabase::GetLastPathNumber(int* number) {
174 if (!Init()) 188 if (!Init(REBUILD_ON_CORRUPTION))
175 return false; 189 return false;
176 DCHECK(number); 190 DCHECK(number);
177 std::string number_string; 191 std::string number_string;
178 leveldb::Status status = 192 leveldb::Status status =
179 db_->Get(leveldb::ReadOptions(), LastPathKey(), &number_string); 193 db_->Get(leveldb::ReadOptions(), LastPathKey(), &number_string);
180 if (status.ok()) 194 if (status.ok())
181 return base::StringToInt(number_string, number); 195 return base::StringToInt(number_string, number);
182 if (!status.IsNotFound()) { 196 if (!status.IsNotFound()) {
183 HandleError(FROM_HERE, status); 197 HandleError(FROM_HERE, status);
184 return false; 198 return false;
(...skipping 11 matching lines...) Expand all
196 db_->Put(leveldb::WriteOptions(), LastPathKey(), std::string("-1")); 210 db_->Put(leveldb::WriteOptions(), LastPathKey(), std::string("-1"));
197 if (!status.ok()) { 211 if (!status.ok()) {
198 HandleError(FROM_HERE, status); 212 HandleError(FROM_HERE, status);
199 return false; 213 return false;
200 } 214 }
201 *number = -1; 215 *number = -1;
202 return true; 216 return true;
203 } 217 }
204 218
205 } // namespace fileapi 219 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698