OLD | NEW |
---|---|
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 "chrome/browser/value_store/leveldb_value_store.h" | 5 #include "chrome/browser/value_store/leveldb_value_store.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
262 scoped_ptr<base::Value> next_value; | 262 scoped_ptr<base::Value> next_value; |
263 whole_db.RemoveWithoutPathExpansion(next_key, &next_value); | 263 whole_db.RemoveWithoutPathExpansion(next_key, &next_value); |
264 changes->push_back( | 264 changes->push_back( |
265 ValueStoreChange(next_key, next_value.release(), NULL)); | 265 ValueStoreChange(next_key, next_value.release(), NULL)); |
266 } | 266 } |
267 | 267 |
268 DeleteDbFile(); | 268 DeleteDbFile(); |
269 return MakeWriteResult(changes.Pass()); | 269 return MakeWriteResult(changes.Pass()); |
270 } | 270 } |
271 | 271 |
272 bool LeveldbValueStore::Restore() { | |
273 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
274 | |
275 ReadResult result = Get(); | |
276 std::string previous_key; | |
277 while (result->IsCorrupted()) { | |
278 // If we don't have a specific corrupted key, or we've tried and failed to | |
279 // clear this specific key, or we fail to restore the key, then wipe the | |
280 // whole database. | |
281 if (!result->error().key.get() || *result->error().key == previous_key || | |
282 !RestoreKey(*result->error().key)) { | |
283 DeleteDbFile(); | |
284 result = Get(); | |
285 break; | |
286 } | |
287 | |
288 // Otherwise, re-Get() the database to check if there is still any | |
289 // corruption. | |
290 previous_key = *result->error().key; | |
291 result = Get(); | |
292 } | |
293 | |
294 // If we still have an error, it means we've tried deleting the database file, | |
295 // and failed. There's nothing more we can do. | |
296 return !result->IsCorrupted(); | |
not at google - send to devlin
2014/02/19 21:25:29
I guess another complication with all this is if i
Devlin
2014/02/19 23:12:28
Yeah...
I don't think that we can get a corrupted
| |
297 } | |
298 | |
299 bool LeveldbValueStore::RestoreKey(const std::string& key) { | |
300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
301 | |
302 ReadResult result = Get(key); | |
303 if (result->IsCorrupted()) { | |
304 leveldb::WriteBatch batch; | |
305 batch.Delete(key); | |
306 scoped_ptr<ValueStore::Error> error = WriteToDb(&batch); | |
307 // If we can't delete the key, the restore failed. | |
308 if (error.get()) | |
309 return false; | |
310 result = Get(key); | |
311 } | |
312 | |
313 // The restore succeeded if there is no corruption error. | |
314 return !result->IsCorrupted(); | |
315 } | |
316 | |
317 bool LeveldbValueStore::WriteToDbForTest(leveldb::WriteBatch* batch) { | |
318 return !WriteToDb(batch).get(); | |
319 } | |
320 | |
272 scoped_ptr<ValueStore::Error> LeveldbValueStore::EnsureDbIsOpen() { | 321 scoped_ptr<ValueStore::Error> LeveldbValueStore::EnsureDbIsOpen() { |
273 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 322 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
274 | 323 |
275 if (db_) | 324 if (db_) |
276 return util::NoError(); | 325 return util::NoError(); |
277 | 326 |
278 leveldb::Options options; | 327 leveldb::Options options; |
279 options.max_open_files = 0; // Use minimum. | 328 options.max_open_files = 0; // Use minimum. |
280 options.create_if_missing = true; | 329 options.create_if_missing = true; |
281 | 330 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
382 CHECK(!status.ok()); | 431 CHECK(!status.ok()); |
383 CHECK(!status.IsNotFound()); // not an error | 432 CHECK(!status.IsNotFound()); // not an error |
384 | 433 |
385 std::string message = status.ToString(); | 434 std::string message = status.ToString(); |
386 // The message may contain |db_path_|, which may be considered sensitive | 435 // The message may contain |db_path_|, which may be considered sensitive |
387 // data, and those strings are passed to the extension, so strip it out. | 436 // data, and those strings are passed to the extension, so strip it out. |
388 ReplaceSubstringsAfterOffset(&message, 0u, db_path_.AsUTF8Unsafe(), "..."); | 437 ReplaceSubstringsAfterOffset(&message, 0u, db_path_.AsUTF8Unsafe(), "..."); |
389 | 438 |
390 return Error::Create(CORRUPTION, message, key.Pass()); | 439 return Error::Create(CORRUPTION, message, key.Pass()); |
391 } | 440 } |
OLD | NEW |