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

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

Issue 7608011: Simplify directory path accounting. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rolled in CR feedback. Created 9 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
« no previous file with comments | « webkit/fileapi/quota_file_util.h ('k') | webkit/fileapi/quota_file_util_unittest.cc » ('j') | 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) 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/quota_file_util.h" 5 #include "webkit/fileapi/quota_file_util.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "webkit/fileapi/file_system_context.h" 9 #include "webkit/fileapi/file_system_context.h"
10 #include "webkit/fileapi/file_system_operation_context.h" 10 #include "webkit/fileapi/file_system_operation_context.h"
11 #include "webkit/fileapi/file_system_path_manager.h" 11 #include "webkit/fileapi/file_system_path_manager.h"
12 #include "webkit/fileapi/file_system_quota_util.h" 12 #include "webkit/fileapi/file_system_quota_util.h"
13 #include "webkit/quota/quota_manager.h" 13 #include "webkit/quota/quota_manager.h"
14 14
15 using quota::QuotaManagerProxy; 15 using quota::QuotaManagerProxy;
16 16
17 namespace fileapi { 17 namespace fileapi {
18 18
19 const int64 QuotaFileUtil::kNoLimit = kint64max; 19 const int64 QuotaFileUtil::kNoLimit = kint64max;
20 20
21 // See the comment in the header file as for these constants. 21 namespace {
22 const int64 QuotaFileUtil::kFilePathCostPerChar = 2;
23 const int64 QuotaFileUtil::kFilePathCostPerFile = 146;
24 22
25 namespace { 23 // Checks if copying in the same filesystem can be performed.
24 // This method is not called for moving within a single filesystem.
25 bool CanCopy(
26 const FilePath& src_file_path,
27 const FilePath& dest_file_path,
28 int64 allowed_bytes_growth,
29 int64* growth) {
30 base::PlatformFileInfo src_file_info;
31 if (!file_util::GetFileInfo(src_file_path, &src_file_info)) {
32 // Falling through to the actual copy/move operation.
33 return true;
34 }
35 base::PlatformFileInfo dest_file_info;
36 if (!file_util::GetFileInfo(dest_file_path, &dest_file_info))
37 dest_file_info.size = 0;
38 if (allowed_bytes_growth != QuotaFileUtil::kNoLimit &&
39 src_file_info.size - dest_file_info.size > allowed_bytes_growth)
40 return false;
41 if (growth != NULL)
42 *growth = src_file_info.size - dest_file_info.size;
43
44 return true;
45 }
26 46
27 // A helper class to hook quota_util() methods before and after modifications. 47 // A helper class to hook quota_util() methods before and after modifications.
28 class ScopedOriginUpdateHelper { 48 class ScopedOriginUpdateHelper {
29 public: 49 public:
30 explicit ScopedOriginUpdateHelper( 50 explicit ScopedOriginUpdateHelper(
31 FileSystemOperationContext* operation_context, 51 FileSystemOperationContext* operation_context,
32 const GURL& origin_url, 52 const GURL& origin_url,
33 FileSystemType type) 53 FileSystemType type)
34 : operation_context_(operation_context), 54 : operation_context_(operation_context),
35 origin_url_(origin_url), 55 origin_url_(origin_url),
36 type_(type) { 56 type_(type) {
37 DCHECK(operation_context_); 57 DCHECK(operation_context_);
38 DCHECK(operation_context_->file_system_context()); 58 DCHECK(operation_context_->file_system_context());
39 DCHECK(type != kFileSystemTypeUnknown); 59 DCHECK(type != kFileSystemTypeUnknown);
40 quota_util_ = 60 quota_util_ =
41 operation_context_->file_system_context()->GetQuotaUtil(type_); 61 operation_context_->file_system_context()->GetQuotaUtil(type_);
42 quota_manager_proxy_ = 62 quota_manager_proxy_ =
43 operation_context_->file_system_context()->quota_manager_proxy(); 63 operation_context_->file_system_context()->quota_manager_proxy();
44 if (quota_util_) 64 if (quota_util_)
45 quota_util_->StartUpdateOriginOnFileThread(origin_url_, type_); 65 quota_util_->StartUpdateOriginOnFileThread(origin_url_, type_);
46 } 66 }
47 67
48 ~ScopedOriginUpdateHelper() { 68 ~ScopedOriginUpdateHelper() {
49 if (quota_util_) 69 if (quota_util_)
50 quota_util_->EndUpdateOriginOnFileThread(origin_url_, type_); 70 quota_util_->EndUpdateOriginOnFileThread(origin_url_, type_);
51 } 71 }
52 72
53 void NotifyUpdate(int64 growth) { 73 void NotifyUpdate(int64 growth) {
54 if (operation_context_->allowed_bytes_growth() != QuotaFileUtil::kNoLimit) 74 operation_context_->set_allowed_bytes_growth(
55 operation_context_->set_allowed_bytes_growth( 75 operation_context_->allowed_bytes_growth() - growth);
56 operation_context_->allowed_bytes_growth() - growth);
57 if (quota_util_) 76 if (quota_util_)
58 quota_util_->UpdateOriginUsageOnFileThread( 77 quota_util_->UpdateOriginUsageOnFileThread(
59 quota_manager_proxy_, origin_url_, type_, growth); 78 quota_manager_proxy_, origin_url_, type_, growth);
60 } 79 }
61 80
62 private: 81 private:
63 FileSystemOperationContext* operation_context_; 82 FileSystemOperationContext* operation_context_;
64 FileSystemQuotaUtil* quota_util_; 83 FileSystemQuotaUtil* quota_util_;
65 QuotaManagerProxy* quota_manager_proxy_; 84 QuotaManagerProxy* quota_manager_proxy_;
66 const GURL& origin_url_; 85 const GURL& origin_url_;
67 FileSystemType type_; 86 FileSystemType type_;
68 DISALLOW_COPY_AND_ASSIGN(ScopedOriginUpdateHelper); 87 DISALLOW_COPY_AND_ASSIGN(ScopedOriginUpdateHelper);
69 }; 88 };
70 89
71 } // namespace (anonymous) 90 } // namespace (anonymous)
72 91
73 QuotaFileUtil::QuotaFileUtil(FileSystemFileUtil* underlying_file_util) 92 QuotaFileUtil::QuotaFileUtil(FileSystemFileUtil* underlying_file_util)
74 : underlying_file_util_(underlying_file_util) { 93 : underlying_file_util_(underlying_file_util) {
75 } 94 }
76 95
77 QuotaFileUtil::~QuotaFileUtil() { 96 QuotaFileUtil::~QuotaFileUtil() {
78 } 97 }
79 98
80 // static 99 // static
81 QuotaFileUtil* QuotaFileUtil::CreateDefault() { 100 QuotaFileUtil* QuotaFileUtil::CreateDefault() {
82 return new QuotaFileUtil(new FileSystemFileUtil()); 101 return new QuotaFileUtil(new FileSystemFileUtil());
83 } 102 }
84 103
85 int64 QuotaFileUtil::ComputeFilePathCost(const FilePath& file_path) const {
86 return kFilePathCostPerFile +
87 file_path.BaseName().value().length() * kFilePathCostPerChar;
88 }
89
90 PlatformFileError QuotaFileUtil::CreateOrOpen(
91 FileSystemOperationContext* fs_context,
92 const FilePath& file_path, int file_flags,
93 PlatformFile* file_handle, bool* created) {
94 DCHECK(fs_context);
95 scoped_ptr<ScopedOriginUpdateHelper> helper;
96
97 int64 allowed_bytes_growth = fs_context->allowed_bytes_growth();
98 int64 growth = 0;
99
100 if (!file_util::PathExists(file_path))
101 growth = ComputeFilePathCost(fs_context->src_virtual_path());
102
103 if (growth > 0) {
104 helper.reset(new ScopedOriginUpdateHelper(
105 fs_context,
106 fs_context->src_origin_url(),
107 fs_context->src_type()));
108
109 if (allowed_bytes_growth != kNoLimit && growth > allowed_bytes_growth)
110 return base::PLATFORM_FILE_ERROR_NO_SPACE;
111 }
112
113 base::PlatformFileError error = underlying_file_util_->CreateOrOpen(
114 fs_context, file_path, file_flags, file_handle, created);
115
116 if (growth > 0) {
117 if (error == base::PLATFORM_FILE_OK)
118 helper->NotifyUpdate(growth);
119 }
120
121 return error;
122 }
123
124 PlatformFileError QuotaFileUtil::EnsureFileExists(
125 FileSystemOperationContext* fs_context,
126 const FilePath& file_path,
127 bool* created) {
128 DCHECK(fs_context);
129 scoped_ptr<ScopedOriginUpdateHelper> helper;
130
131 int64 allowed_bytes_growth = fs_context->allowed_bytes_growth();
132 int64 growth = 0;
133
134 if (!file_util::PathExists(file_path))
135 growth = ComputeFilePathCost(fs_context->src_virtual_path());
136
137 if (growth > 0) {
138 helper.reset(new ScopedOriginUpdateHelper(
139 fs_context,
140 fs_context->src_origin_url(),
141 fs_context->src_type()));
142
143 if (allowed_bytes_growth != kNoLimit && growth > allowed_bytes_growth)
144 return base::PLATFORM_FILE_ERROR_NO_SPACE;
145 }
146
147 base::PlatformFileError error = underlying_file_util_->EnsureFileExists(
148 fs_context, file_path, created);
149
150 if (growth > 0 &&error == base::PLATFORM_FILE_OK)
151 helper->NotifyUpdate(growth);
152
153 return error;
154 }
155
156 PlatformFileError QuotaFileUtil::CreateDirectory(
157 FileSystemOperationContext* fs_context,
158 const FilePath& file_path,
159 bool exclusive,
160 bool recursive) {
161 DCHECK(fs_context);
162 scoped_ptr<ScopedOriginUpdateHelper> helper;
163
164 int64 allowed_bytes_growth = fs_context->allowed_bytes_growth();
165 int64 growth = 0;
166
167 if (!exclusive || !file_util::PathExists(file_path)) {
168 if (recursive) {
169 FilePath last_path;
170 for (FilePath path = fs_context->src_virtual_path();
171 path.value() != last_path.value() &&
172 !fs_context->src_file_system_file_util()->PathExists(
173 fs_context, fs_context->src_virtual_path());
174 path = path.DirName()) {
175 growth += ComputeFilePathCost(fs_context->src_virtual_path());
176 last_path = path;
177 }
178 } else {
179 growth += ComputeFilePathCost(fs_context->src_virtual_path());
180 }
181 }
182
183 if (growth > 0) {
184 helper.reset(new ScopedOriginUpdateHelper(
185 fs_context,
186 fs_context->src_origin_url(),
187 fs_context->src_type()));
188
189 if (allowed_bytes_growth != kNoLimit && growth > allowed_bytes_growth)
190 return base::PLATFORM_FILE_ERROR_NO_SPACE;
191 }
192
193 base::PlatformFileError error = base::PLATFORM_FILE_OK;
194 error = underlying_file_util_->CreateDirectory(
195 fs_context, file_path, exclusive, recursive);
196
197 if (growth > 0 && error == base::PLATFORM_FILE_OK)
198 helper->NotifyUpdate(growth);
199
200 return error;
201 }
202
203 base::PlatformFileError QuotaFileUtil::CopyOrMoveFile( 104 base::PlatformFileError QuotaFileUtil::CopyOrMoveFile(
204 FileSystemOperationContext* fs_context, 105 FileSystemOperationContext* fs_context,
205 const FilePath& src_file_path, 106 const FilePath& src_file_path,
206 const FilePath& dest_file_path, 107 const FilePath& dest_file_path,
207 bool copy) { 108 bool copy) {
208 DCHECK(fs_context); 109 DCHECK(fs_context);
209 110
210 // TODO(kinuko): For cross-filesystem move case we need 2 helpers, one for 111 // TODO(kinuko): For cross-filesystem move case we need 2 helpers, one for
211 // src and one for dest. 112 // src and one for dest.
212 ScopedOriginUpdateHelper helper( 113 ScopedOriginUpdateHelper helper(
213 fs_context, 114 fs_context,
214 fs_context->dest_origin_url(), 115 fs_context->dest_origin_url(),
215 fs_context->dest_type()); 116 fs_context->dest_type());
216 117
217 int64 growth = 0; 118 int64 growth = 0;
218 119
219 // It assumes copy/move operations are always in the same fs currently. 120 // It assumes copy/move operations are always in the same fs currently.
220 // TODO(dmikurube): Do quota check if moving between different fs. 121 // TODO(dmikurube): Do quota check if moving between different fs.
221 if (copy) { 122 if (copy) {
222 int64 allowed_bytes_growth = fs_context->allowed_bytes_growth(); 123 int64 allowed_bytes_growth = fs_context->allowed_bytes_growth();
223 // The third argument (growth) is not used for now. 124 // The third argument (growth) is not used for now.
224 if (!CanCopyFile(fs_context, src_file_path, dest_file_path, 125 if (!CanCopy(src_file_path, dest_file_path, allowed_bytes_growth, &growth))
225 allowed_bytes_growth, &growth))
226 return base::PLATFORM_FILE_ERROR_NO_SPACE; 126 return base::PLATFORM_FILE_ERROR_NO_SPACE;
227 } else { // move 127 } else {
228 int64 allowed_bytes_growth = fs_context->allowed_bytes_growth();
229 base::PlatformFileInfo dest_file_info; 128 base::PlatformFileInfo dest_file_info;
230 int64 src_file_path_cost =
231 ComputeFilePathCost(fs_context->src_virtual_path());
232 int64 dest_file_path_cost =
233 ComputeFilePathCost(fs_context->dest_virtual_path());
234 if (!file_util::GetFileInfo(dest_file_path, &dest_file_info)) 129 if (!file_util::GetFileInfo(dest_file_path, &dest_file_info))
235 dest_file_info.size = 0; 130 dest_file_info.size = 0;
236 growth = -dest_file_info.size - src_file_path_cost + dest_file_path_cost; 131 growth = -dest_file_info.size;
237 if (allowed_bytes_growth != kNoLimit && growth > allowed_bytes_growth)
238 return base::PLATFORM_FILE_ERROR_NO_SPACE;
239 } 132 }
240 133
241 base::PlatformFileError error = underlying_file_util_->CopyOrMoveFile( 134 base::PlatformFileError error = underlying_file_util_->CopyOrMoveFile(
242 fs_context, src_file_path, dest_file_path, copy); 135 fs_context, src_file_path, dest_file_path, copy);
243 136
244 if (error == base::PLATFORM_FILE_OK) { 137 if (error == base::PLATFORM_FILE_OK) {
245 // TODO(kinuko): For cross-filesystem move case, call this with -growth 138 // TODO(kinuko): For cross-filesystem move case, call this with -growth
246 // for source and growth for dest. 139 // for source and growth for dest.
247 helper.NotifyUpdate(growth); 140 helper.NotifyUpdate(growth);
248 } 141 }
249 142
250 return error; 143 return error;
251 } 144 }
252 145
253 base::PlatformFileError QuotaFileUtil::DeleteFile( 146 base::PlatformFileError QuotaFileUtil::DeleteFile(
254 FileSystemOperationContext* fs_context, 147 FileSystemOperationContext* fs_context,
255 const FilePath& file_path) { 148 const FilePath& file_path) {
256 DCHECK(fs_context); 149 DCHECK(fs_context);
257 ScopedOriginUpdateHelper helper( 150 ScopedOriginUpdateHelper helper(
258 fs_context, 151 fs_context,
259 fs_context->src_origin_url(), 152 fs_context->src_origin_url(),
260 fs_context->src_type()); 153 fs_context->src_type());
261 154
262 int64 growth = 0; 155 int64 growth = 0;
263 base::PlatformFileInfo file_info; 156 base::PlatformFileInfo file_info;
264 if (file_util::GetFileInfo(file_path, &file_info)) { 157 if (!file_util::GetFileInfo(file_path, &file_info))
265 growth -= file_info.size + 158 file_info.size = 0;
266 ComputeFilePathCost(fs_context->src_virtual_path()); 159 growth = -file_info.size;
267 }
268 160
269 base::PlatformFileError error = underlying_file_util_->DeleteFile( 161 base::PlatformFileError error = underlying_file_util_->DeleteFile(
270 fs_context, file_path); 162 fs_context, file_path);
271 163
272 if (error == base::PLATFORM_FILE_OK) 164 if (error == base::PLATFORM_FILE_OK)
273 helper.NotifyUpdate(growth); 165 helper.NotifyUpdate(growth);
274 166
275 return error; 167 return error;
276 } 168 }
277 169
278 base::PlatformFileError QuotaFileUtil::DeleteSingleDirectory(
279 FileSystemOperationContext* fs_context,
280 const FilePath& file_path) {
281 DCHECK(fs_context);
282 ScopedOriginUpdateHelper helper(
283 fs_context,
284 fs_context->src_origin_url(),
285 fs_context->src_type());
286
287 int64 growth = 0;
288 if (file_util::DirectoryExists(file_path))
289 growth -= ComputeFilePathCost(fs_context->src_virtual_path());
290
291 base::PlatformFileError error = underlying_file_util_->DeleteSingleDirectory(
292 fs_context, file_path);
293
294 if (error == base::PLATFORM_FILE_OK)
295 helper.NotifyUpdate(growth);
296
297 return error;
298 }
299
300 base::PlatformFileError QuotaFileUtil::Truncate( 170 base::PlatformFileError QuotaFileUtil::Truncate(
301 FileSystemOperationContext* fs_context, 171 FileSystemOperationContext* fs_context,
302 const FilePath& path, 172 const FilePath& path,
303 int64 length) { 173 int64 length) {
304 int64 allowed_bytes_growth = fs_context->allowed_bytes_growth(); 174 int64 allowed_bytes_growth = fs_context->allowed_bytes_growth();
305 ScopedOriginUpdateHelper helper( 175 ScopedOriginUpdateHelper helper(
306 fs_context, 176 fs_context,
307 fs_context->src_origin_url(), 177 fs_context->src_origin_url(),
308 fs_context->src_type()); 178 fs_context->src_type());
309 179
310 int64 growth = 0; 180 int64 growth = 0;
311 base::PlatformFileInfo file_info; 181 base::PlatformFileInfo file_info;
312 if (!file_util::GetFileInfo(path, &file_info)) 182 if (!file_util::GetFileInfo(path, &file_info))
313 return base::PLATFORM_FILE_ERROR_FAILED; 183 return base::PLATFORM_FILE_ERROR_FAILED;
314 184
315 growth = length - file_info.size; 185 growth = length - file_info.size;
316 if (allowed_bytes_growth != kNoLimit && growth > allowed_bytes_growth) 186 if (allowed_bytes_growth != kNoLimit && growth > allowed_bytes_growth)
317 return base::PLATFORM_FILE_ERROR_NO_SPACE; 187 return base::PLATFORM_FILE_ERROR_NO_SPACE;
318 188
319 base::PlatformFileError error = underlying_file_util_->Truncate( 189 base::PlatformFileError error = underlying_file_util_->Truncate(
320 fs_context, path, length); 190 fs_context, path, length);
321 191
322 if (error == base::PLATFORM_FILE_OK) 192 if (error == base::PLATFORM_FILE_OK)
323 helper.NotifyUpdate(growth); 193 helper.NotifyUpdate(growth);
324 194
325 return error; 195 return error;
326 } 196 }
327 197
328 // Checks if copying in the same filesystem can be performed.
329 // This method is not called for moving within a single filesystem.
330 bool QuotaFileUtil::CanCopyFile(
331 FileSystemOperationContext* fs_context,
332 const FilePath& src_file_path,
333 const FilePath& dest_file_path,
334 int64 allowed_bytes_growth,
335 int64* growth) const {
336 DCHECK(growth);
337 base::PlatformFileInfo src_file_info;
338 if (!file_util::GetFileInfo(src_file_path, &src_file_info)) {
339 // Falling through to the actual copy/move operation.
340 return true;
341 }
342 base::PlatformFileInfo dest_file_info;
343 int dest_file_path_cost = 0;
344 if (!file_util::GetFileInfo(dest_file_path, &dest_file_info)) {
345 dest_file_info.size = 0;
346 dest_file_path_cost = ComputeFilePathCost(fs_context->dest_virtual_path());
347 }
348 *growth = src_file_info.size - dest_file_info.size + dest_file_path_cost;
349 if (allowed_bytes_growth != QuotaFileUtil::kNoLimit &&
350 *growth > allowed_bytes_growth)
351 return false;
352
353 return true;
354 }
355
356 } // namespace fileapi 198 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/quota_file_util.h ('k') | webkit/fileapi/quota_file_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698