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

Side by Side Diff: storage/browser/fileapi/sandbox_origin_database.cc

Issue 442383002: Move storage-related files from webkit/ to new top-level directory storage/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 4 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/browser/fileapi/sandbox_origin_database.h" 5 #include "storage/browser/fileapi/sandbox_origin_database.h"
6 6
7 #include <set> 7 #include <set>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/files/file_enumerator.h" 11 #include "base/files/file_enumerator.h"
12 #include "base/format_macros.h" 12 #include "base/format_macros.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
16 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_util.h" 17 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
19 #include "third_party/leveldatabase/src/include/leveldb/db.h" 19 #include "third_party/leveldatabase/src/include/leveldb/db.h"
20 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" 20 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
21 #include "webkit/common/fileapi/file_system_util.h" 21 #include "storage/common/fileapi/file_system_util.h"
22 22
23 namespace { 23 namespace {
24 24
25 const base::FilePath::CharType kOriginDatabaseName[] = 25 const base::FilePath::CharType kOriginDatabaseName[] =
26 FILE_PATH_LITERAL("Origins"); 26 FILE_PATH_LITERAL("Origins");
27 const char kOriginKeyPrefix[] = "ORIGIN:"; 27 const char kOriginKeyPrefix[] = "ORIGIN:";
28 const char kLastPathKey[] = "LAST_PATH"; 28 const char kLastPathKey[] = "LAST_PATH";
29 const int64 kMinimumReportIntervalHours = 1; 29 const int64 kMinimumReportIntervalHours = 1;
30 const char kInitStatusHistogramLabel[] = "FileSystem.OriginDatabaseInit"; 30 const char kInitStatusHistogramLabel[] = "FileSystem.OriginDatabaseInit";
31 const char kDatabaseRepairHistogramLabel[] = "FileSystem.OriginDatabaseRepair"; 31 const char kDatabaseRepairHistogramLabel[] = "FileSystem.OriginDatabaseRepair";
32 32
33 enum InitStatus { 33 enum InitStatus {
34 INIT_STATUS_OK = 0, 34 INIT_STATUS_OK = 0,
35 INIT_STATUS_CORRUPTION, 35 INIT_STATUS_CORRUPTION,
36 INIT_STATUS_IO_ERROR, 36 INIT_STATUS_IO_ERROR,
37 INIT_STATUS_UNKNOWN_ERROR, 37 INIT_STATUS_UNKNOWN_ERROR,
38 INIT_STATUS_MAX 38 INIT_STATUS_MAX
39 }; 39 };
40 40
41 enum RepairResult { 41 enum RepairResult { DB_REPAIR_SUCCEEDED = 0, DB_REPAIR_FAILED, DB_REPAIR_MAX };
42 DB_REPAIR_SUCCEEDED = 0,
43 DB_REPAIR_FAILED,
44 DB_REPAIR_MAX
45 };
46 42
47 std::string OriginToOriginKey(const std::string& origin) { 43 std::string OriginToOriginKey(const std::string& origin) {
48 std::string key(kOriginKeyPrefix); 44 std::string key(kOriginKeyPrefix);
49 return key + origin; 45 return key + origin;
50 } 46 }
51 47
52 const char* LastPathKey() { 48 const char* LastPathKey() {
53 return kLastPathKey; 49 return kLastPathKey;
54 } 50 }
55 51
56 } // namespace 52 } // namespace
57 53
58 namespace fileapi { 54 namespace storage {
59 55
60 SandboxOriginDatabase::SandboxOriginDatabase( 56 SandboxOriginDatabase::SandboxOriginDatabase(
61 const base::FilePath& file_system_directory, 57 const base::FilePath& file_system_directory,
62 leveldb::Env* env_override) 58 leveldb::Env* env_override)
63 : file_system_directory_(file_system_directory), 59 : file_system_directory_(file_system_directory),
64 env_override_(env_override) { 60 env_override_(env_override) {
65 } 61 }
66 62
67 SandboxOriginDatabase::~SandboxOriginDatabase() { 63 SandboxOriginDatabase::~SandboxOriginDatabase() {
68 } 64 }
(...skipping 28 matching lines...) Expand all
97 if (!status.IsCorruption() && !status.IsIOError()) 93 if (!status.IsCorruption() && !status.IsIOError())
98 return false; 94 return false;
99 95
100 switch (recovery_option) { 96 switch (recovery_option) {
101 case FAIL_ON_CORRUPTION: 97 case FAIL_ON_CORRUPTION:
102 return false; 98 return false;
103 case REPAIR_ON_CORRUPTION: 99 case REPAIR_ON_CORRUPTION:
104 LOG(WARNING) << "Attempting to repair SandboxOriginDatabase."; 100 LOG(WARNING) << "Attempting to repair SandboxOriginDatabase.";
105 101
106 if (RepairDatabase(path)) { 102 if (RepairDatabase(path)) {
107 UMA_HISTOGRAM_ENUMERATION(kDatabaseRepairHistogramLabel, 103 UMA_HISTOGRAM_ENUMERATION(
108 DB_REPAIR_SUCCEEDED, DB_REPAIR_MAX); 104 kDatabaseRepairHistogramLabel, DB_REPAIR_SUCCEEDED, DB_REPAIR_MAX);
109 LOG(WARNING) << "Repairing SandboxOriginDatabase completed."; 105 LOG(WARNING) << "Repairing SandboxOriginDatabase completed.";
110 return true; 106 return true;
111 } 107 }
112 UMA_HISTOGRAM_ENUMERATION(kDatabaseRepairHistogramLabel, 108 UMA_HISTOGRAM_ENUMERATION(
113 DB_REPAIR_FAILED, DB_REPAIR_MAX); 109 kDatabaseRepairHistogramLabel, DB_REPAIR_FAILED, DB_REPAIR_MAX);
114 // fall through 110 // fall through
115 case DELETE_ON_CORRUPTION: 111 case DELETE_ON_CORRUPTION:
116 if (!base::DeleteFile(file_system_directory_, true)) 112 if (!base::DeleteFile(file_system_directory_, true))
117 return false; 113 return false;
118 if (!base::CreateDirectory(file_system_directory_)) 114 if (!base::CreateDirectory(file_system_directory_))
119 return false; 115 return false;
120 return Init(init_option, FAIL_ON_CORRUPTION); 116 return Init(init_option, FAIL_ON_CORRUPTION);
121 } 117 }
122 NOTREACHED(); 118 NOTREACHED();
123 return false; 119 return false;
124 } 120 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 } else { 166 } else {
171 directories.erase(dir_itr); 167 directories.erase(dir_itr);
172 } 168 }
173 } 169 }
174 170
175 // Delete any directories not listed in the origins database. 171 // Delete any directories not listed in the origins database.
176 for (std::set<base::FilePath>::iterator dir_itr = directories.begin(); 172 for (std::set<base::FilePath>::iterator dir_itr = directories.begin();
177 dir_itr != directories.end(); 173 dir_itr != directories.end();
178 ++dir_itr) { 174 ++dir_itr) {
179 if (!base::DeleteFile(file_system_directory_.Append(*dir_itr), 175 if (!base::DeleteFile(file_system_directory_.Append(*dir_itr),
180 true /* recursive */)) { 176 true /* recursive */)) {
181 DropDatabase(); 177 DropDatabase();
182 return false; 178 return false;
183 } 179 }
184 } 180 }
185 181
186 return true; 182 return true;
187 } 183 }
188 184
189 void SandboxOriginDatabase::HandleError( 185 void SandboxOriginDatabase::HandleError(
190 const tracked_objects::Location& from_here, 186 const tracked_objects::Location& from_here,
191 const leveldb::Status& status) { 187 const leveldb::Status& status) {
192 db_.reset(); 188 db_.reset();
193 LOG(ERROR) << "SandboxOriginDatabase failed at: " 189 LOG(ERROR) << "SandboxOriginDatabase failed at: " << from_here.ToString()
194 << from_here.ToString() << " with error: " << status.ToString(); 190 << " with error: " << status.ToString();
195 } 191 }
196 192
197 void SandboxOriginDatabase::ReportInitStatus(const leveldb::Status& status) { 193 void SandboxOriginDatabase::ReportInitStatus(const leveldb::Status& status) {
198 base::Time now = base::Time::Now(); 194 base::Time now = base::Time::Now();
199 base::TimeDelta minimum_interval = 195 base::TimeDelta minimum_interval =
200 base::TimeDelta::FromHours(kMinimumReportIntervalHours); 196 base::TimeDelta::FromHours(kMinimumReportIntervalHours);
201 if (last_reported_time_ + minimum_interval >= now) 197 if (last_reported_time_ + minimum_interval >= now)
202 return; 198 return;
203 last_reported_time_ = now; 199 last_reported_time_ = now;
204 200
205 if (status.ok()) { 201 if (status.ok()) {
206 UMA_HISTOGRAM_ENUMERATION(kInitStatusHistogramLabel, 202 UMA_HISTOGRAM_ENUMERATION(
207 INIT_STATUS_OK, INIT_STATUS_MAX); 203 kInitStatusHistogramLabel, INIT_STATUS_OK, INIT_STATUS_MAX);
208 } else if (status.IsCorruption()) { 204 } else if (status.IsCorruption()) {
209 UMA_HISTOGRAM_ENUMERATION(kInitStatusHistogramLabel, 205 UMA_HISTOGRAM_ENUMERATION(
210 INIT_STATUS_CORRUPTION, INIT_STATUS_MAX); 206 kInitStatusHistogramLabel, INIT_STATUS_CORRUPTION, INIT_STATUS_MAX);
211 } else if (status.IsIOError()) { 207 } else if (status.IsIOError()) {
212 UMA_HISTOGRAM_ENUMERATION(kInitStatusHistogramLabel, 208 UMA_HISTOGRAM_ENUMERATION(
213 INIT_STATUS_IO_ERROR, INIT_STATUS_MAX); 209 kInitStatusHistogramLabel, INIT_STATUS_IO_ERROR, INIT_STATUS_MAX);
214 } else { 210 } else {
215 UMA_HISTOGRAM_ENUMERATION(kInitStatusHistogramLabel, 211 UMA_HISTOGRAM_ENUMERATION(
216 INIT_STATUS_UNKNOWN_ERROR, INIT_STATUS_MAX); 212 kInitStatusHistogramLabel, INIT_STATUS_UNKNOWN_ERROR, INIT_STATUS_MAX);
217 } 213 }
218 } 214 }
219 215
220 bool SandboxOriginDatabase::HasOriginPath(const std::string& origin) { 216 bool SandboxOriginDatabase::HasOriginPath(const std::string& origin) {
221 if (!Init(FAIL_IF_NONEXISTENT, REPAIR_ON_CORRUPTION)) 217 if (!Init(FAIL_IF_NONEXISTENT, REPAIR_ON_CORRUPTION))
222 return false; 218 return false;
223 if (origin.empty()) 219 if (origin.empty())
224 return false; 220 return false;
225 std::string path; 221 std::string path;
226 leveldb::Status status = 222 leveldb::Status status =
227 db_->Get(leveldb::ReadOptions(), OriginToOriginKey(origin), &path); 223 db_->Get(leveldb::ReadOptions(), OriginToOriginKey(origin), &path);
228 if (status.ok()) 224 if (status.ok())
229 return true; 225 return true;
230 if (status.IsNotFound()) 226 if (status.IsNotFound())
231 return false; 227 return false;
232 HandleError(FROM_HERE, status); 228 HandleError(FROM_HERE, status);
233 return false; 229 return false;
234 } 230 }
235 231
236 bool SandboxOriginDatabase::GetPathForOrigin( 232 bool SandboxOriginDatabase::GetPathForOrigin(const std::string& origin,
237 const std::string& origin, base::FilePath* directory) { 233 base::FilePath* directory) {
238 if (!Init(CREATE_IF_NONEXISTENT, REPAIR_ON_CORRUPTION)) 234 if (!Init(CREATE_IF_NONEXISTENT, REPAIR_ON_CORRUPTION))
239 return false; 235 return false;
240 DCHECK(directory); 236 DCHECK(directory);
241 if (origin.empty()) 237 if (origin.empty())
242 return false; 238 return false;
243 std::string path_string; 239 std::string path_string;
244 std::string origin_key = OriginToOriginKey(origin); 240 std::string origin_key = OriginToOriginKey(origin);
245 leveldb::Status status = 241 leveldb::Status status =
246 db_->Get(leveldb::ReadOptions(), origin_key, &path_string); 242 db_->Get(leveldb::ReadOptions(), origin_key, &path_string);
247 if (status.IsNotFound()) { 243 if (status.IsNotFound()) {
(...skipping 23 matching lines...) Expand all
271 if (!Init(CREATE_IF_NONEXISTENT, REPAIR_ON_CORRUPTION)) 267 if (!Init(CREATE_IF_NONEXISTENT, REPAIR_ON_CORRUPTION))
272 return false; 268 return false;
273 leveldb::Status status = 269 leveldb::Status status =
274 db_->Delete(leveldb::WriteOptions(), OriginToOriginKey(origin)); 270 db_->Delete(leveldb::WriteOptions(), OriginToOriginKey(origin));
275 if (status.ok() || status.IsNotFound()) 271 if (status.ok() || status.IsNotFound())
276 return true; 272 return true;
277 HandleError(FROM_HERE, status); 273 HandleError(FROM_HERE, status);
278 return false; 274 return false;
279 } 275 }
280 276
281 bool SandboxOriginDatabase::ListAllOrigins( 277 bool SandboxOriginDatabase::ListAllOrigins(std::vector<OriginRecord>* origins) {
282 std::vector<OriginRecord>* origins) {
283 DCHECK(origins); 278 DCHECK(origins);
284 if (!Init(CREATE_IF_NONEXISTENT, REPAIR_ON_CORRUPTION)) { 279 if (!Init(CREATE_IF_NONEXISTENT, REPAIR_ON_CORRUPTION)) {
285 origins->clear(); 280 origins->clear();
286 return false; 281 return false;
287 } 282 }
288 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions())); 283 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions()));
289 std::string origin_key_prefix = OriginToOriginKey(std::string()); 284 std::string origin_key_prefix = OriginToOriginKey(std::string());
290 iter->Seek(origin_key_prefix); 285 iter->Seek(origin_key_prefix);
291 origins->clear(); 286 origins->clear();
292 while (iter->Valid() && 287 while (iter->Valid() &&
293 StartsWithASCII(iter->key().ToString(), origin_key_prefix, true)) { 288 StartsWithASCII(iter->key().ToString(), origin_key_prefix, true)) {
294 std::string origin = 289 std::string origin =
295 iter->key().ToString().substr(origin_key_prefix.length()); 290 iter->key().ToString().substr(origin_key_prefix.length());
296 base::FilePath path = StringToFilePath(iter->value().ToString()); 291 base::FilePath path = StringToFilePath(iter->value().ToString());
297 origins->push_back(OriginRecord(origin, path)); 292 origins->push_back(OriginRecord(origin, path));
298 iter->Next(); 293 iter->Next();
299 } 294 }
300 return true; 295 return true;
301 } 296 }
302 297
303 void SandboxOriginDatabase::DropDatabase() { 298 void SandboxOriginDatabase::DropDatabase() {
304 db_.reset(); 299 db_.reset();
305 } 300 }
(...skipping 21 matching lines...) Expand all
327 } 322 }
328 // Verify that this is a totally new database, and initialize it. 323 // Verify that this is a totally new database, and initialize it.
329 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions())); 324 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions()));
330 iter->SeekToFirst(); 325 iter->SeekToFirst();
331 if (iter->Valid()) { // DB was not empty, but had no last path number! 326 if (iter->Valid()) { // DB was not empty, but had no last path number!
332 LOG(ERROR) << "File system origin database is corrupt!"; 327 LOG(ERROR) << "File system origin database is corrupt!";
333 return false; 328 return false;
334 } 329 }
335 // This is always the first write into the database. If we ever add a 330 // This is always the first write into the database. If we ever add a
336 // version number, they should go in in a single transaction. 331 // version number, they should go in in a single transaction.
337 status = 332 status = db_->Put(leveldb::WriteOptions(), LastPathKey(), std::string("-1"));
338 db_->Put(leveldb::WriteOptions(), LastPathKey(), std::string("-1"));
339 if (!status.ok()) { 333 if (!status.ok()) {
340 HandleError(FROM_HERE, status); 334 HandleError(FROM_HERE, status);
341 return false; 335 return false;
342 } 336 }
343 *number = -1; 337 *number = -1;
344 return true; 338 return true;
345 } 339 }
346 340
347 } // namespace fileapi 341 } // namespace storage
OLDNEW
« no previous file with comments | « storage/browser/fileapi/sandbox_origin_database.h ('k') | storage/browser/fileapi/sandbox_origin_database_interface.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698