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

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

Powered by Google App Engine
This is Rietveld 408576698