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

Side by Side Diff: base/files/file_posix.cc

Issue 1072133006: Add granular file tracing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@do-initialize
Patch Set: herp Created 5 years, 7 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
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 "base/files/file.h" 5 #include "base/files/file.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <sys/stat.h> 9 #include <sys/stat.h>
10 #include <unistd.h> 10 #include <unistd.h>
11 11
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/metrics/sparse_histogram.h" 14 #include "base/metrics/sparse_histogram.h"
15 #include "base/posix/eintr_wrapper.h" 15 #include "base/posix/eintr_wrapper.h"
16 #include "base/strings/utf_string_conversions.h" 16 #include "base/strings/utf_string_conversions.h"
17 #include "base/threading/thread_restrictions.h" 17 #include "base/threading/thread_restrictions.h"
18 #include "base/trace_event/trace_event.h"
18 19
19 #if defined(OS_ANDROID) 20 #if defined(OS_ANDROID)
20 #include "base/os_compat_android.h" 21 #include "base/os_compat_android.h"
21 #endif 22 #endif
22 23
23 namespace base { 24 namespace base {
24 25
25 // Make sure our Whence mappings match the system headers. 26 // Make sure our Whence mappings match the system headers.
26 COMPILE_ASSERT(File::FROM_BEGIN == SEEK_SET && 27 COMPILE_ASSERT(File::FROM_BEGIN == SEEK_SET &&
27 File::FROM_CURRENT == SEEK_CUR && 28 File::FROM_CURRENT == SEEK_CUR &&
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 168
168 PlatformFile File::TakePlatformFile() { 169 PlatformFile File::TakePlatformFile() {
169 return file_.release(); 170 return file_.release();
170 } 171 }
171 172
172 void File::Close() { 173 void File::Close() {
173 if (!IsValid()) 174 if (!IsValid())
174 return; 175 return;
175 176
176 ThreadRestrictions::AssertIOAllowed(); 177 ThreadRestrictions::AssertIOAllowed();
178
179 TRACE_EVENT_ID1(kTraceGroup, "Close", this, "path",
180 unsafe_path_.AsUTF8Unsafe());
177 file_.reset(); 181 file_.reset();
178 } 182 }
179 183
180 int64 File::Seek(Whence whence, int64 offset) { 184 int64 File::Seek(Whence whence, int64 offset) {
181 ThreadRestrictions::AssertIOAllowed(); 185 ThreadRestrictions::AssertIOAllowed();
182 DCHECK(IsValid()); 186 DCHECK(IsValid());
183 187
188 TRACE_EVENT_ID1(kTraceGroup, "Seek", this, "path",
189 unsafe_path_.AsUTF8Unsafe());
190
184 #if defined(OS_ANDROID) 191 #if defined(OS_ANDROID)
185 COMPILE_ASSERT(sizeof(int64) == sizeof(off64_t), off64_t_64_bit); 192 COMPILE_ASSERT(sizeof(int64) == sizeof(off64_t), off64_t_64_bit);
186 return lseek64(file_.get(), static_cast<off64_t>(offset), 193 return lseek64(file_.get(), static_cast<off64_t>(offset),
187 static_cast<int>(whence)); 194 static_cast<int>(whence));
188 #else 195 #else
189 COMPILE_ASSERT(sizeof(int64) == sizeof(off_t), off_t_64_bit); 196 COMPILE_ASSERT(sizeof(int64) == sizeof(off_t), off_t_64_bit);
190 return lseek(file_.get(), static_cast<off_t>(offset), 197 return lseek(file_.get(), static_cast<off_t>(offset),
191 static_cast<int>(whence)); 198 static_cast<int>(whence));
192 #endif 199 #endif
193 } 200 }
194 201
195 int File::Read(int64 offset, char* data, int size) { 202 int File::Read(int64 offset, char* data, int size) {
196 ThreadRestrictions::AssertIOAllowed(); 203 ThreadRestrictions::AssertIOAllowed();
197 DCHECK(IsValid()); 204 DCHECK(IsValid());
198 if (size < 0) 205 if (size < 0)
199 return -1; 206 return -1;
200 207
208 TRACE_EVENT_ID2(kTraceGroup, "Read", this, "path",
209 unsafe_path_.AsUTF8Unsafe(), "size", size);
210
201 int bytes_read = 0; 211 int bytes_read = 0;
202 int rv; 212 int rv;
203 do { 213 do {
204 rv = HANDLE_EINTR(pread(file_.get(), data + bytes_read, 214 rv = HANDLE_EINTR(pread(file_.get(), data + bytes_read,
205 size - bytes_read, offset + bytes_read)); 215 size - bytes_read, offset + bytes_read));
206 if (rv <= 0) 216 if (rv <= 0)
207 break; 217 break;
208 218
209 bytes_read += rv; 219 bytes_read += rv;
210 } while (bytes_read < size); 220 } while (bytes_read < size);
211 221
212 return bytes_read ? bytes_read : rv; 222 return bytes_read ? bytes_read : rv;
213 } 223 }
214 224
215 int File::ReadAtCurrentPos(char* data, int size) { 225 int File::ReadAtCurrentPos(char* data, int size) {
216 ThreadRestrictions::AssertIOAllowed(); 226 ThreadRestrictions::AssertIOAllowed();
217 DCHECK(IsValid()); 227 DCHECK(IsValid());
218 if (size < 0) 228 if (size < 0)
219 return -1; 229 return -1;
220 230
231 TRACE_EVENT_ID2(kTraceGroup, "ReadAtCurrentPost", this, "path",
232 unsafe_path_.AsUTF8Unsafe(), "size", size);
233
221 int bytes_read = 0; 234 int bytes_read = 0;
222 int rv; 235 int rv;
223 do { 236 do {
224 rv = HANDLE_EINTR(read(file_.get(), data + bytes_read, size - bytes_read)); 237 rv = HANDLE_EINTR(read(file_.get(), data + bytes_read, size - bytes_read));
225 if (rv <= 0) 238 if (rv <= 0)
226 break; 239 break;
227 240
228 bytes_read += rv; 241 bytes_read += rv;
229 } while (bytes_read < size); 242 } while (bytes_read < size);
230 243
231 return bytes_read ? bytes_read : rv; 244 return bytes_read ? bytes_read : rv;
232 } 245 }
233 246
234 int File::ReadNoBestEffort(int64 offset, char* data, int size) { 247 int File::ReadNoBestEffort(int64 offset, char* data, int size) {
235 ThreadRestrictions::AssertIOAllowed(); 248 ThreadRestrictions::AssertIOAllowed();
236 DCHECK(IsValid()); 249 DCHECK(IsValid());
237 250 TRACE_EVENT_ID2(kTraceGroup, "ReadNoBestEffort", this, "path",
251 unsafe_path_.AsUTF8Unsafe(), "size", size);
238 return HANDLE_EINTR(pread(file_.get(), data, size, offset)); 252 return HANDLE_EINTR(pread(file_.get(), data, size, offset));
239 } 253 }
240 254
241 int File::ReadAtCurrentPosNoBestEffort(char* data, int size) { 255 int File::ReadAtCurrentPosNoBestEffort(char* data, int size) {
242 ThreadRestrictions::AssertIOAllowed(); 256 ThreadRestrictions::AssertIOAllowed();
243 DCHECK(IsValid()); 257 DCHECK(IsValid());
244 if (size < 0) 258 if (size < 0)
245 return -1; 259 return -1;
246 260
261 TRACE_EVENT_ID2(kTraceGroup, "ReadAtCurrentPosNoBestEffort", this, "path",
262 unsafe_path_.AsUTF8Unsafe(), "size", size);
247 return HANDLE_EINTR(read(file_.get(), data, size)); 263 return HANDLE_EINTR(read(file_.get(), data, size));
248 } 264 }
249 265
250 int File::Write(int64 offset, const char* data, int size) { 266 int File::Write(int64 offset, const char* data, int size) {
251 ThreadRestrictions::AssertIOAllowed(); 267 ThreadRestrictions::AssertIOAllowed();
252 268
253 if (IsOpenAppend(file_.get())) 269 if (IsOpenAppend(file_.get()))
254 return WriteAtCurrentPos(data, size); 270 return WriteAtCurrentPos(data, size);
255 271
256 DCHECK(IsValid()); 272 DCHECK(IsValid());
257 if (size < 0) 273 if (size < 0)
258 return -1; 274 return -1;
259 275
276 TRACE_EVENT_ID2(kTraceGroup, "Write", this, "path",
277 unsafe_path_.AsUTF8Unsafe(), "size", size);
278
260 int bytes_written = 0; 279 int bytes_written = 0;
261 int rv; 280 int rv;
262 do { 281 do {
263 rv = HANDLE_EINTR(pwrite(file_.get(), data + bytes_written, 282 rv = HANDLE_EINTR(pwrite(file_.get(), data + bytes_written,
264 size - bytes_written, offset + bytes_written)); 283 size - bytes_written, offset + bytes_written));
265 if (rv <= 0) 284 if (rv <= 0)
266 break; 285 break;
267 286
268 bytes_written += rv; 287 bytes_written += rv;
269 } while (bytes_written < size); 288 } while (bytes_written < size);
270 289
271 return bytes_written ? bytes_written : rv; 290 return bytes_written ? bytes_written : rv;
272 } 291 }
273 292
274 int File::WriteAtCurrentPos(const char* data, int size) { 293 int File::WriteAtCurrentPos(const char* data, int size) {
275 ThreadRestrictions::AssertIOAllowed(); 294 ThreadRestrictions::AssertIOAllowed();
276 DCHECK(IsValid()); 295 DCHECK(IsValid());
277 if (size < 0) 296 if (size < 0)
278 return -1; 297 return -1;
279 298
299 TRACE_EVENT_ID2(kTraceGroup, "WriteAtCurrentPos", this, "path",
300 unsafe_path_.AsUTF8Unsafe(), "size", size);
301
280 int bytes_written = 0; 302 int bytes_written = 0;
281 int rv; 303 int rv;
282 do { 304 do {
283 rv = HANDLE_EINTR(write(file_.get(), data + bytes_written, 305 rv = HANDLE_EINTR(write(file_.get(), data + bytes_written,
284 size - bytes_written)); 306 size - bytes_written));
285 if (rv <= 0) 307 if (rv <= 0)
286 break; 308 break;
287 309
288 bytes_written += rv; 310 bytes_written += rv;
289 } while (bytes_written < size); 311 } while (bytes_written < size);
290 312
291 return bytes_written ? bytes_written : rv; 313 return bytes_written ? bytes_written : rv;
292 } 314 }
293 315
294 int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) { 316 int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) {
295 ThreadRestrictions::AssertIOAllowed(); 317 ThreadRestrictions::AssertIOAllowed();
296 DCHECK(IsValid()); 318 DCHECK(IsValid());
297 if (size < 0) 319 if (size < 0)
298 return -1; 320 return -1;
299 321
322 TRACE_EVENT_ID2(kTraceGroup, "WriteAtCurrentPosNoBestEffort", this, "path",
323 unsafe_path_.AsUTF8Unsafe(), "size", size);
300 return HANDLE_EINTR(write(file_.get(), data, size)); 324 return HANDLE_EINTR(write(file_.get(), data, size));
301 } 325 }
302 326
303 int64 File::GetLength() { 327 int64 File::GetLength() {
304 DCHECK(IsValid()); 328 DCHECK(IsValid());
305 329
330 TRACE_EVENT_ID1(kTraceGroup, "GetLength", this, "path",
331 unsafe_path_.AsUTF8Unsafe());
332
306 stat_wrapper_t file_info; 333 stat_wrapper_t file_info;
307 if (CallFstat(file_.get(), &file_info)) 334 if (CallFstat(file_.get(), &file_info))
308 return false; 335 return false;
309 336
310 return file_info.st_size; 337 return file_info.st_size;
311 } 338 }
312 339
313 bool File::SetLength(int64 length) { 340 bool File::SetLength(int64 length) {
314 ThreadRestrictions::AssertIOAllowed(); 341 ThreadRestrictions::AssertIOAllowed();
315 DCHECK(IsValid()); 342 DCHECK(IsValid());
343
344 TRACE_EVENT_ID2(kTraceGroup, "SetLength", this, "path",
345 unsafe_path_.AsUTF8Unsafe(), "length", length);
346
316 return !CallFtruncate(file_.get(), length); 347 return !CallFtruncate(file_.get(), length);
317 } 348 }
318 349
319 bool File::SetTimes(Time last_access_time, Time last_modified_time) { 350 bool File::SetTimes(Time last_access_time, Time last_modified_time) {
320 ThreadRestrictions::AssertIOAllowed(); 351 ThreadRestrictions::AssertIOAllowed();
321 DCHECK(IsValid()); 352 DCHECK(IsValid());
322 353
354 TRACE_EVENT_ID1(kTraceGroup, "SetTimes", this, "path",
355 unsafe_path_.AsUTF8Unsafe());
356
323 timeval times[2]; 357 timeval times[2];
324 times[0] = last_access_time.ToTimeVal(); 358 times[0] = last_access_time.ToTimeVal();
325 times[1] = last_modified_time.ToTimeVal(); 359 times[1] = last_modified_time.ToTimeVal();
326 360
327 return !CallFutimes(file_.get(), times); 361 return !CallFutimes(file_.get(), times);
328 } 362 }
329 363
330 bool File::GetInfo(Info* info) { 364 bool File::GetInfo(Info* info) {
331 DCHECK(IsValid()); 365 DCHECK(IsValid());
332 366
367 TRACE_EVENT_ID1(kTraceGroup, "GetInfo", this, "path",
368 unsafe_path_.AsUTF8Unsafe());
369
333 stat_wrapper_t file_info; 370 stat_wrapper_t file_info;
334 if (CallFstat(file_.get(), &file_info)) 371 if (CallFstat(file_.get(), &file_info))
335 return false; 372 return false;
336 373
337 info->FromStat(file_info); 374 info->FromStat(file_info);
338 return true; 375 return true;
339 } 376 }
340 377
341 File::Error File::Lock() { 378 File::Error File::Lock() {
379 TRACE_EVENT_ID1(kTraceGroup, "Lock", this, "path",
380 unsafe_path_.AsUTF8Unsafe());
342 return CallFctnlFlock(file_.get(), true); 381 return CallFctnlFlock(file_.get(), true);
343 } 382 }
344 383
345 File::Error File::Unlock() { 384 File::Error File::Unlock() {
385 TRACE_EVENT_ID1(kTraceGroup, "Unlock", this, "path",
386 unsafe_path_.AsUTF8Unsafe());
346 return CallFctnlFlock(file_.get(), false); 387 return CallFctnlFlock(file_.get(), false);
347 } 388 }
348 389
349 File File::Duplicate() { 390 File File::Duplicate() {
350 if (!IsValid()) 391 if (!IsValid())
351 return File(); 392 return File();
352 393
394 TRACE_EVENT_ID1(kTraceGroup, "Duplicate", this, "path",
395 unsafe_path_.AsUTF8Unsafe());
396
353 PlatformFile other_fd = dup(GetPlatformFile()); 397 PlatformFile other_fd = dup(GetPlatformFile());
354 if (other_fd == -1) 398 if (other_fd == -1)
355 return File(OSErrorToFileError(errno)); 399 return File(OSErrorToFileError(errno));
356 400
357 File other(other_fd); 401 File other(other_fd);
358 if (async()) 402 if (async())
359 other.async_ = true; 403 other.async_ = true;
360 return other.Pass(); 404 return other.Pass();
361 } 405 }
362 406
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 CHECK_EQ(file_memory_checksum_, computed_checksum) << "corrupted fd memory"; 479 CHECK_EQ(file_memory_checksum_, computed_checksum) << "corrupted fd memory";
436 } 480 }
437 481
438 void File::MemoryCheckingScopedFD::UpdateChecksum() { 482 void File::MemoryCheckingScopedFD::UpdateChecksum() {
439 ComputeMemoryChecksum(&file_memory_checksum_); 483 ComputeMemoryChecksum(&file_memory_checksum_);
440 } 484 }
441 485
442 // NaCl doesn't implement system calls to open files directly. 486 // NaCl doesn't implement system calls to open files directly.
443 #if !defined(OS_NACL) 487 #if !defined(OS_NACL)
444 // TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here? 488 // TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here?
445 void File::DoInitialize(const FilePath& name, uint32 flags) { 489 void File::DoInitialize(uint32 flags) {
446 ThreadRestrictions::AssertIOAllowed(); 490 ThreadRestrictions::AssertIOAllowed();
447 DCHECK(!IsValid()); 491 DCHECK(!IsValid());
448 492
493 TRACE_EVENT_ID1(kTraceGroup, "Initialize", this, "path",
494 unsafe_path_.AsUTF8Unsafe());
495
449 int open_flags = 0; 496 int open_flags = 0;
450 if (flags & FLAG_CREATE) 497 if (flags & FLAG_CREATE)
451 open_flags = O_CREAT | O_EXCL; 498 open_flags = O_CREAT | O_EXCL;
452 499
453 created_ = false; 500 created_ = false;
454 501
455 if (flags & FLAG_CREATE_ALWAYS) { 502 if (flags & FLAG_CREATE_ALWAYS) {
456 DCHECK(!open_flags); 503 DCHECK(!open_flags);
457 DCHECK(flags & FLAG_WRITE); 504 DCHECK(flags & FLAG_WRITE);
458 open_flags = O_CREAT | O_TRUNC; 505 open_flags = O_CREAT | O_TRUNC;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 else if (flags & FLAG_APPEND) 537 else if (flags & FLAG_APPEND)
491 open_flags |= O_APPEND | O_WRONLY; 538 open_flags |= O_APPEND | O_WRONLY;
492 539
493 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_equal_zero); 540 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_equal_zero);
494 541
495 int mode = S_IRUSR | S_IWUSR; 542 int mode = S_IRUSR | S_IWUSR;
496 #if defined(OS_CHROMEOS) 543 #if defined(OS_CHROMEOS)
497 mode |= S_IRGRP | S_IROTH; 544 mode |= S_IRGRP | S_IROTH;
498 #endif 545 #endif
499 546
500 int descriptor = HANDLE_EINTR(open(name.value().c_str(), open_flags, mode)); 547 int descriptor =
548 HANDLE_EINTR(open(unsafe_path_.value().c_str(), open_flags, mode));
501 549
502 if (flags & FLAG_OPEN_ALWAYS) { 550 if (flags & FLAG_OPEN_ALWAYS) {
503 if (descriptor < 0) { 551 if (descriptor < 0) {
504 open_flags |= O_CREAT; 552 open_flags |= O_CREAT;
505 if (flags & FLAG_EXCLUSIVE_READ || flags & FLAG_EXCLUSIVE_WRITE) 553 if (flags & FLAG_EXCLUSIVE_READ || flags & FLAG_EXCLUSIVE_WRITE)
506 open_flags |= O_EXCL; // together with O_CREAT implies O_NOFOLLOW 554 open_flags |= O_EXCL; // together with O_CREAT implies O_NOFOLLOW
507 555
508 descriptor = HANDLE_EINTR(open(name.value().c_str(), open_flags, mode)); 556 descriptor =
557 HANDLE_EINTR(open(unsafe_path_.value().c_str(), open_flags, mode));
509 if (descriptor >= 0) 558 if (descriptor >= 0)
510 created_ = true; 559 created_ = true;
511 } 560 }
512 } 561 }
513 562
514 if (descriptor < 0) { 563 if (descriptor < 0) {
515 error_details_ = File::OSErrorToFileError(errno); 564 error_details_ = File::OSErrorToFileError(errno);
516 return; 565 return;
517 } 566 }
518 567
519 if (flags & (FLAG_CREATE_ALWAYS | FLAG_CREATE)) 568 if (flags & (FLAG_CREATE_ALWAYS | FLAG_CREATE))
520 created_ = true; 569 created_ = true;
521 570
522 if (flags & FLAG_DELETE_ON_CLOSE) 571 if (flags & FLAG_DELETE_ON_CLOSE)
523 unlink(name.value().c_str()); 572 unlink(unsafe_path_.value().c_str());
524 573
525 async_ = ((flags & FLAG_ASYNC) == FLAG_ASYNC); 574 async_ = ((flags & FLAG_ASYNC) == FLAG_ASYNC);
526 error_details_ = FILE_OK; 575 error_details_ = FILE_OK;
527 file_.reset(descriptor); 576 file_.reset(descriptor);
528 } 577 }
529 #endif // !defined(OS_NACL) 578 #endif // !defined(OS_NACL)
530 579
531 bool File::DoFlush() { 580 bool File::DoFlush() {
532 ThreadRestrictions::AssertIOAllowed(); 581 ThreadRestrictions::AssertIOAllowed();
533 DCHECK(IsValid()); 582 DCHECK(IsValid());
583
534 #if defined(OS_NACL) 584 #if defined(OS_NACL)
535 NOTIMPLEMENTED(); // NaCl doesn't implement fsync. 585 NOTIMPLEMENTED(); // NaCl doesn't implement fsync.
536 return true; 586 return true;
537 #elif defined(OS_LINUX) || defined(OS_ANDROID) 587 #else
588 TRACE_EVENT_ID1(kTraceGroup, "Flush", this, "path",
589 unsafe_path_.AsUTF8Unsafe());
590 #if defined(OS_LINUX) || defined(OS_ANDROID)
538 return !HANDLE_EINTR(fdatasync(file_.get())); 591 return !HANDLE_EINTR(fdatasync(file_.get()));
539 #else 592 #else
540 return !HANDLE_EINTR(fsync(file_.get())); 593 return !HANDLE_EINTR(fsync(file_.get()));
541 #endif 594 #endif // defined(OS_LINUX) || defined(OS_ANDROID)
595 #endif // defined(OS_NACL)
542 } 596 }
543 597
544 void File::SetPlatformFile(PlatformFile file) { 598 void File::SetPlatformFile(PlatformFile file) {
545 DCHECK(!file_.is_valid()); 599 DCHECK(!file_.is_valid());
546 file_.reset(file); 600 file_.reset(file);
547 } 601 }
548 602
549 } // namespace base 603 } // namespace base
OLDNEW
« no previous file with comments | « base/files/file.cc ('k') | base/files/file_win.cc » ('j') | base/trace_event/trace_event.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698