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

Side by Side Diff: content/browser/indexed_db/leveldb/leveldb_database.cc

Issue 16409006: Don't delete leveldb directory if disk was full. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: move to else if block Created 7 years, 6 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
« no previous file with comments | « content/browser/indexed_db/leveldb/leveldb_database.h ('k') | 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) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "content/browser/indexed_db/leveldb/leveldb_database.h" 5 #include "content/browser/indexed_db/leveldb/leveldb_database.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 102
103 bool LevelDBDatabase::Destroy(const base::FilePath& file_name) { 103 bool LevelDBDatabase::Destroy(const base::FilePath& file_name) {
104 leveldb::Options options; 104 leveldb::Options options;
105 options.env = leveldb::IDBEnv(); 105 options.env = leveldb::IDBEnv();
106 // ChromiumEnv assumes UTF8, converts back to FilePath before using. 106 // ChromiumEnv assumes UTF8, converts back to FilePath before using.
107 const leveldb::Status s = 107 const leveldb::Status s =
108 leveldb::DestroyDB(file_name.AsUTF8Unsafe(), options); 108 leveldb::DestroyDB(file_name.AsUTF8Unsafe(), options);
109 return s.ok(); 109 return s.ok();
110 } 110 }
111 111
112 static void HistogramFreeSpace(const char* type, 112 static int CheckFreeSpace(const char* type, const base::FilePath& file_name) {
113 const base::FilePath& file_name) { 113 // TODO(dgrogan): Change string16 -> std::string.
114 string16 name = ASCIIToUTF16("WebCore.IndexedDB.LevelDB.Open") + 114 string16 name = ASCIIToUTF16("WebCore.IndexedDB.LevelDB.Open") +
115 ASCIIToUTF16(type) + ASCIIToUTF16("FreeDiskSpace"); 115 ASCIIToUTF16(type) + ASCIIToUTF16("FreeDiskSpace");
116 int64 free_disk_space_in_k_bytes = 116 int64 free_disk_space_in_k_bytes =
117 base::SysInfo::AmountOfFreeDiskSpace(file_name) / 1024; 117 base::SysInfo::AmountOfFreeDiskSpace(file_name) / 1024;
118 if (free_disk_space_in_k_bytes < 0) { 118 if (free_disk_space_in_k_bytes < 0) {
119 base::Histogram::FactoryGet( 119 base::Histogram::FactoryGet(
120 "WebCore.IndexedDB.LevelDB.FreeDiskSpaceFailure", 120 "WebCore.IndexedDB.LevelDB.FreeDiskSpaceFailure",
121 1, 121 1,
122 2 /*boundary*/, 122 2 /*boundary*/,
123 2 /*boundary*/ + 1, 123 2 /*boundary*/ + 1,
124 base::HistogramBase::kUmaTargetedHistogramFlag)->Add(1 /*sample*/); 124 base::HistogramBase::kUmaTargetedHistogramFlag)->Add(1 /*sample*/);
125 return; 125 return -1;
126 } 126 }
127 int clamped_disk_space_k_bytes = 127 int clamped_disk_space_k_bytes =
128 free_disk_space_in_k_bytes > INT_MAX ? INT_MAX 128 free_disk_space_in_k_bytes > INT_MAX ? INT_MAX
129 : free_disk_space_in_k_bytes; 129 : free_disk_space_in_k_bytes;
130 const uint64 histogram_max = static_cast<uint64>(1e9); 130 const uint64 histogram_max = static_cast<uint64>(1e9);
131 COMPILE_ASSERT(histogram_max <= INT_MAX, histogram_max_too_big); 131 COMPILE_ASSERT(histogram_max <= INT_MAX, histogram_max_too_big);
132 base::Histogram::FactoryGet(UTF16ToUTF8(name), 132 base::Histogram::FactoryGet(UTF16ToUTF8(name),
133 1, 133 1,
134 histogram_max, 134 histogram_max,
135 11 /*buckets*/, 135 11 /*buckets*/,
136 base::HistogramBase::kUmaTargetedHistogramFlag) 136 base::HistogramBase::kUmaTargetedHistogramFlag)
137 ->Add(clamped_disk_space_k_bytes); 137 ->Add(clamped_disk_space_k_bytes);
138 return clamped_disk_space_k_bytes;
138 } 139 }
139 140
140 static void HistogramLevelDBError(const char* histogram_name, 141 static void HistogramLevelDBError(const char* histogram_name,
141 const leveldb::Status& s) { 142 const leveldb::Status& s) {
142 DCHECK(!s.ok()); 143 DCHECK(!s.ok());
143 enum { 144 enum {
144 LEVEL_DB_NOT_FOUND, 145 LEVEL_DB_NOT_FOUND,
145 LEVEL_DB_CORRUPTION, 146 LEVEL_DB_CORRUPTION,
146 LEVEL_DB_IO_ERROR, 147 LEVEL_DB_IO_ERROR,
147 LEVEL_DB_OTHER, 148 LEVEL_DB_OTHER,
148 LEVEL_DB_MAX_ERROR 149 LEVEL_DB_MAX_ERROR
149 }; 150 };
150 int leveldb_error = LEVEL_DB_OTHER; 151 int leveldb_error = LEVEL_DB_OTHER;
151 if (s.IsNotFound()) 152 if (s.IsNotFound())
152 leveldb_error = LEVEL_DB_NOT_FOUND; 153 leveldb_error = LEVEL_DB_NOT_FOUND;
153 else if (s.IsCorruption()) 154 else if (s.IsCorruption())
154 leveldb_error = LEVEL_DB_CORRUPTION; 155 leveldb_error = LEVEL_DB_CORRUPTION;
155 else if (s.IsIOError()) 156 else if (s.IsIOError())
156 leveldb_error = LEVEL_DB_IO_ERROR; 157 leveldb_error = LEVEL_DB_IO_ERROR;
157 base::Histogram::FactoryGet(histogram_name, 158 base::Histogram::FactoryGet(histogram_name,
158 1, 159 1,
159 LEVEL_DB_MAX_ERROR, 160 LEVEL_DB_MAX_ERROR,
160 LEVEL_DB_MAX_ERROR + 1, 161 LEVEL_DB_MAX_ERROR + 1,
161 base::HistogramBase::kUmaTargetedHistogramFlag) 162 base::HistogramBase::kUmaTargetedHistogramFlag)
162 ->Add(leveldb_error); 163 ->Add(leveldb_error);
163 } 164 }
164 165
165 scoped_ptr<LevelDBDatabase> LevelDBDatabase::Open( 166 scoped_ptr<LevelDBDatabase> LevelDBDatabase::Open(
166 const base::FilePath& file_name, 167 const base::FilePath& file_name,
167 const LevelDBComparator* comparator) { 168 const LevelDBComparator* comparator,
169 bool* is_disk_full) {
168 scoped_ptr<ComparatorAdapter> comparator_adapter( 170 scoped_ptr<ComparatorAdapter> comparator_adapter(
169 new ComparatorAdapter(comparator)); 171 new ComparatorAdapter(comparator));
170 172
171 leveldb::DB* db; 173 leveldb::DB* db;
172 const leveldb::Status s = 174 const leveldb::Status s =
173 OpenDB(comparator_adapter.get(), leveldb::IDBEnv(), file_name, &db); 175 OpenDB(comparator_adapter.get(), leveldb::IDBEnv(), file_name, &db);
174 176
175 if (!s.ok()) { 177 if (!s.ok()) {
176 HistogramLevelDBError("WebCore.IndexedDB.LevelDBOpenErrors", s); 178 HistogramLevelDBError("WebCore.IndexedDB.LevelDBOpenErrors", s);
177 HistogramFreeSpace("Failure", file_name); 179 int free_space_k_bytes = CheckFreeSpace("Failure", file_name);
180 // Disks with <100k of free space almost never succeed in opening a
181 // leveldb database.
182 if (is_disk_full)
183 *is_disk_full = free_space_k_bytes >= 0 && free_space_k_bytes < 100;
178 184
179 LOG(ERROR) << "Failed to open LevelDB database from " 185 LOG(ERROR) << "Failed to open LevelDB database from "
180 << file_name.AsUTF8Unsafe() << "," << s.ToString(); 186 << file_name.AsUTF8Unsafe() << "," << s.ToString();
181 return scoped_ptr<LevelDBDatabase>(); 187 return scoped_ptr<LevelDBDatabase>();
182 } 188 }
183 189
184 HistogramFreeSpace("Success", file_name); 190 CheckFreeSpace("Success", file_name);
185 191
186 scoped_ptr<LevelDBDatabase> result(new LevelDBDatabase); 192 scoped_ptr<LevelDBDatabase> result(new LevelDBDatabase);
187 result->db_ = make_scoped_ptr(db); 193 result->db_ = make_scoped_ptr(db);
188 result->comparator_adapter_ = comparator_adapter.Pass(); 194 result->comparator_adapter_ = comparator_adapter.Pass();
189 result->comparator_ = comparator; 195 result->comparator_ = comparator;
190 196
191 return result.Pass(); 197 return result.Pass();
192 } 198 }
193 199
194 scoped_ptr<LevelDBDatabase> LevelDBDatabase::OpenInMemory( 200 scoped_ptr<LevelDBDatabase> LevelDBDatabase::OpenInMemory(
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 if (!i) // TODO(jsbell): Double check if we actually need to check this. 356 if (!i) // TODO(jsbell): Double check if we actually need to check this.
351 return scoped_ptr<LevelDBIterator>(); 357 return scoped_ptr<LevelDBIterator>();
352 return scoped_ptr<LevelDBIterator>(new IteratorImpl(i.Pass())); 358 return scoped_ptr<LevelDBIterator>(new IteratorImpl(i.Pass()));
353 } 359 }
354 360
355 const LevelDBComparator* LevelDBDatabase::Comparator() const { 361 const LevelDBComparator* LevelDBDatabase::Comparator() const {
356 return comparator_; 362 return comparator_;
357 } 363 }
358 364
359 } // namespace content 365 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/leveldb/leveldb_database.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698