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

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: add tests 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(bool cleanup_if_corrupted) {
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 (cleanup_if_corrupted && CheckIfDatabaseCorrupted(status)) {
73 LOG(WARNING) << "FileSystem API origin database is corrupted."
74 << " Attempting cleanup.";
75 if (leveldb::DestroyDB(path_, leveldb::Options()).ok()) {
76 LOG(WARNING) << "FileSystem API origin database cleanup completed."
77 << " Reopening.";
78 return Init(false);
79 }
80 LOG(WARNING) << "Failed to cleanup FileSystem API origin database.";
81 }
82
70 return false; 83 return false;
71 } 84 }
72 85
86 bool FileSystemOriginDatabase::CheckIfDatabaseCorrupted(
87 const leveldb::Status& status) const {
88 // TODO(tzik): Return status.code() == leveldb::Status::kCorruption, after
89 // leveldb roll.
90 return !status.ok();
91 }
92
73 void FileSystemOriginDatabase::HandleError( 93 void FileSystemOriginDatabase::HandleError(
74 const tracked_objects::Location& from_here, leveldb::Status status) { 94 const tracked_objects::Location& from_here, leveldb::Status status) {
75 db_.reset(); 95 db_.reset();
76 LOG(ERROR) << "FileSystemOriginDatabase failed at: " 96 LOG(ERROR) << "FileSystemOriginDatabase failed at: "
77 << from_here.ToString() << " with error: " << status.ToString(); 97 << from_here.ToString() << " with error: " << status.ToString();
78 } 98 }
79 99
80 bool FileSystemOriginDatabase::HasOriginPath(const std::string& origin) { 100 bool FileSystemOriginDatabase::HasOriginPath(const std::string& origin) {
81 if (!Init()) 101 if (!Init(true))
82 return false; 102 return false;
83 if (origin.empty()) 103 if (origin.empty())
84 return false; 104 return false;
85 std::string path; 105 std::string path;
86 leveldb::Status status = 106 leveldb::Status status =
87 db_->Get(leveldb::ReadOptions(), OriginToOriginKey(origin), &path); 107 db_->Get(leveldb::ReadOptions(), OriginToOriginKey(origin), &path);
88 if (status.ok()) 108 if (status.ok())
89 return true; 109 return true;
90 if (status.IsNotFound()) 110 if (status.IsNotFound())
91 return false; 111 return false;
92 HandleError(FROM_HERE, status); 112 HandleError(FROM_HERE, status);
93 return false; 113 return false;
94 } 114 }
95 115
96 bool FileSystemOriginDatabase::GetPathForOrigin( 116 bool FileSystemOriginDatabase::GetPathForOrigin(
97 const std::string& origin, FilePath* directory) { 117 const std::string& origin, FilePath* directory) {
98 if (!Init()) 118 if (!Init(true))
99 return false; 119 return false;
100 DCHECK(directory); 120 DCHECK(directory);
101 if (origin.empty()) 121 if (origin.empty())
102 return false; 122 return false;
103 std::string path_string; 123 std::string path_string;
104 std::string origin_key = OriginToOriginKey(origin); 124 std::string origin_key = OriginToOriginKey(origin);
105 leveldb::Status status = 125 leveldb::Status status =
106 db_->Get(leveldb::ReadOptions(), origin_key, &path_string); 126 db_->Get(leveldb::ReadOptions(), origin_key, &path_string);
107 if (status.IsNotFound()) { 127 if (status.IsNotFound()) {
108 int last_path_number; 128 int last_path_number;
(...skipping 16 matching lines...) Expand all
125 #elif defined(OS_WIN) 145 #elif defined(OS_WIN)
126 *directory = FilePath(base::SysUTF8ToWide(path_string)); 146 *directory = FilePath(base::SysUTF8ToWide(path_string));
127 #endif 147 #endif
128 return true; 148 return true;
129 } 149 }
130 HandleError(FROM_HERE, status); 150 HandleError(FROM_HERE, status);
131 return false; 151 return false;
132 } 152 }
133 153
134 bool FileSystemOriginDatabase::RemovePathForOrigin(const std::string& origin) { 154 bool FileSystemOriginDatabase::RemovePathForOrigin(const std::string& origin) {
135 if (!Init()) 155 if (!Init(true))
136 return false; 156 return false;
137 leveldb::Status status = 157 leveldb::Status status =
138 db_->Delete(leveldb::WriteOptions(), OriginToOriginKey(origin)); 158 db_->Delete(leveldb::WriteOptions(), OriginToOriginKey(origin));
139 if (status.ok() || status.IsNotFound()) 159 if (status.ok() || status.IsNotFound())
140 return true; 160 return true;
141 HandleError(FROM_HERE, status); 161 HandleError(FROM_HERE, status);
142 return false; 162 return false;
143 } 163 }
144 164
145 bool FileSystemOriginDatabase::ListAllOrigins( 165 bool FileSystemOriginDatabase::ListAllOrigins(
146 std::vector<OriginRecord>* origins) { 166 std::vector<OriginRecord>* origins) {
147 if (!Init()) 167 if (!Init(true))
148 return false; 168 return false;
149 DCHECK(origins); 169 DCHECK(origins);
150 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions())); 170 scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions()));
151 std::string origin_key_prefix = OriginToOriginKey(""); 171 std::string origin_key_prefix = OriginToOriginKey("");
152 iter->Seek(origin_key_prefix); 172 iter->Seek(origin_key_prefix);
153 origins->clear(); 173 origins->clear();
154 while(iter->Valid() && 174 while(iter->Valid() &&
155 StartsWithASCII(iter->key().ToString(), origin_key_prefix, true)) { 175 StartsWithASCII(iter->key().ToString(), origin_key_prefix, true)) {
156 std::string origin = 176 std::string origin =
157 iter->key().ToString().substr(origin_key_prefix.length()); 177 iter->key().ToString().substr(origin_key_prefix.length());
158 #if defined(OS_POSIX) 178 #if defined(OS_POSIX)
159 FilePath path = FilePath(iter->value().ToString()); 179 FilePath path = FilePath(iter->value().ToString());
160 #elif defined(OS_WIN) 180 #elif defined(OS_WIN)
161 FilePath path = FilePath(base::SysUTF8ToWide(iter->value().ToString())); 181 FilePath path = FilePath(base::SysUTF8ToWide(iter->value().ToString()));
162 #endif 182 #endif
163 origins->push_back(OriginRecord(origin, path)); 183 origins->push_back(OriginRecord(origin, path));
164 iter->Next(); 184 iter->Next();
165 } 185 }
166 return true; 186 return true;
167 } 187 }
168 188
169 void FileSystemOriginDatabase::DropDatabase() { 189 void FileSystemOriginDatabase::DropDatabase() {
170 db_.reset(); 190 db_.reset();
171 } 191 }
172 192
173 bool FileSystemOriginDatabase::GetLastPathNumber(int* number) { 193 bool FileSystemOriginDatabase::GetLastPathNumber(int* number) {
174 if (!Init()) 194 if (!Init(true))
175 return false; 195 return false;
176 DCHECK(number); 196 DCHECK(number);
177 std::string number_string; 197 std::string number_string;
178 leveldb::Status status = 198 leveldb::Status status =
179 db_->Get(leveldb::ReadOptions(), LastPathKey(), &number_string); 199 db_->Get(leveldb::ReadOptions(), LastPathKey(), &number_string);
180 if (status.ok()) 200 if (status.ok())
181 return base::StringToInt(number_string, number); 201 return base::StringToInt(number_string, number);
182 if (!status.IsNotFound()) { 202 if (!status.IsNotFound()) {
183 HandleError(FROM_HERE, status); 203 HandleError(FROM_HERE, status);
184 return false; 204 return false;
(...skipping 11 matching lines...) Expand all
196 db_->Put(leveldb::WriteOptions(), LastPathKey(), std::string("-1")); 216 db_->Put(leveldb::WriteOptions(), LastPathKey(), std::string("-1"));
197 if (!status.ok()) { 217 if (!status.ok()) {
198 HandleError(FROM_HERE, status); 218 HandleError(FROM_HERE, status);
199 return false; 219 return false;
200 } 220 }
201 *number = -1; 221 *number = -1;
202 return true; 222 return true;
203 } 223 }
204 224
205 } // namespace fileapi 225 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698