| OLD | NEW |
| 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 "net/disk_cache/sparse_control.h" | 5 #include "net/disk_cache/sparse_control.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/format_macros.h" | 8 #include "base/format_macros.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 if (operation_ != kNoOperation) | 248 if (operation_ != kNoOperation) |
| 249 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 249 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 250 | 250 |
| 251 if (offset < 0 || buf_len < 0) | 251 if (offset < 0 || buf_len < 0) |
| 252 return net::ERR_INVALID_ARGUMENT; | 252 return net::ERR_INVALID_ARGUMENT; |
| 253 | 253 |
| 254 // We only support up to 64 GB. | 254 // We only support up to 64 GB. |
| 255 if (offset + buf_len >= 0x1000000000LL || offset + buf_len < 0) | 255 if (offset + buf_len >= 0x1000000000LL || offset + buf_len < 0) |
| 256 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 256 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 257 | 257 |
| 258 DCHECK(!user_buf_); | 258 DCHECK(!user_buf_.get()); |
| 259 DCHECK(user_callback_.is_null()); | 259 DCHECK(user_callback_.is_null()); |
| 260 | 260 |
| 261 if (!buf && (op == kReadOperation || op == kWriteOperation)) | 261 if (!buf && (op == kReadOperation || op == kWriteOperation)) |
| 262 return 0; | 262 return 0; |
| 263 | 263 |
| 264 // Copy the operation parameters. | 264 // Copy the operation parameters. |
| 265 operation_ = op; | 265 operation_ = op; |
| 266 offset_ = offset; | 266 offset_ = offset; |
| 267 user_buf_ = buf ? new net::DrainableIOBuffer(buf, buf_len) : NULL; | 267 user_buf_ = buf ? new net::DrainableIOBuffer(buf, buf_len) : NULL; |
| 268 buf_len_ = buf_len; | 268 buf_len_ = buf_len; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 memset(&sparse_header_, 0, sizeof(sparse_header_)); | 376 memset(&sparse_header_, 0, sizeof(sparse_header_)); |
| 377 sparse_header_.signature = Time::Now().ToInternalValue(); | 377 sparse_header_.signature = Time::Now().ToInternalValue(); |
| 378 sparse_header_.magic = kIndexMagic; | 378 sparse_header_.magic = kIndexMagic; |
| 379 sparse_header_.parent_key_len = entry_->GetKey().size(); | 379 sparse_header_.parent_key_len = entry_->GetKey().size(); |
| 380 children_map_.Resize(kNumSparseBits, true); | 380 children_map_.Resize(kNumSparseBits, true); |
| 381 | 381 |
| 382 // Save the header. The bitmap is saved in the destructor. | 382 // Save the header. The bitmap is saved in the destructor. |
| 383 scoped_refptr<net::IOBuffer> buf( | 383 scoped_refptr<net::IOBuffer> buf( |
| 384 new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_))); | 384 new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_))); |
| 385 | 385 |
| 386 int rv = entry_->WriteData( | 386 int rv = entry_->WriteData(kSparseIndex, |
| 387 kSparseIndex, 0, buf, sizeof(sparse_header_), CompletionCallback(), | 387 0, |
| 388 false); | 388 buf.get(), |
| 389 sizeof(sparse_header_), |
| 390 CompletionCallback(), |
| 391 false); |
| 389 if (rv != sizeof(sparse_header_)) { | 392 if (rv != sizeof(sparse_header_)) { |
| 390 DLOG(ERROR) << "Unable to save sparse_header_"; | 393 DLOG(ERROR) << "Unable to save sparse_header_"; |
| 391 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 394 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 392 } | 395 } |
| 393 | 396 |
| 394 entry_->SetEntryFlags(PARENT_ENTRY); | 397 entry_->SetEntryFlags(PARENT_ENTRY); |
| 395 return net::OK; | 398 return net::OK; |
| 396 } | 399 } |
| 397 | 400 |
| 398 // We are opening an entry from disk. Make sure that our control data is there. | 401 // We are opening an entry from disk. Make sure that our control data is there. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 409 // Dont't go over board with the bitmap. 8 KB gives us offsets up to 64 GB. | 412 // Dont't go over board with the bitmap. 8 KB gives us offsets up to 64 GB. |
| 410 int map_len = data_len - sizeof(sparse_header_); | 413 int map_len = data_len - sizeof(sparse_header_); |
| 411 if (map_len > kMaxMapSize || map_len % 4) | 414 if (map_len > kMaxMapSize || map_len % 4) |
| 412 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 415 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 413 | 416 |
| 414 scoped_refptr<net::IOBuffer> buf( | 417 scoped_refptr<net::IOBuffer> buf( |
| 415 new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_))); | 418 new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_))); |
| 416 | 419 |
| 417 // Read header. | 420 // Read header. |
| 418 int rv = entry_->ReadData( | 421 int rv = entry_->ReadData( |
| 419 kSparseIndex, 0, buf, sizeof(sparse_header_), CompletionCallback()); | 422 kSparseIndex, 0, buf.get(), sizeof(sparse_header_), CompletionCallback()); |
| 420 if (rv != static_cast<int>(sizeof(sparse_header_))) | 423 if (rv != static_cast<int>(sizeof(sparse_header_))) |
| 421 return net::ERR_CACHE_READ_FAILURE; | 424 return net::ERR_CACHE_READ_FAILURE; |
| 422 | 425 |
| 423 // The real validation should be performed by the caller. This is just to | 426 // The real validation should be performed by the caller. This is just to |
| 424 // double check. | 427 // double check. |
| 425 if (sparse_header_.magic != kIndexMagic || | 428 if (sparse_header_.magic != kIndexMagic || |
| 426 sparse_header_.parent_key_len != | 429 sparse_header_.parent_key_len != |
| 427 static_cast<int>(entry_->GetKey().size())) | 430 static_cast<int>(entry_->GetKey().size())) |
| 428 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; | 431 return net::ERR_CACHE_OPERATION_NOT_SUPPORTED; |
| 429 | 432 |
| 430 // Read the actual bitmap. | 433 // Read the actual bitmap. |
| 431 buf = new net::IOBuffer(map_len); | 434 buf = new net::IOBuffer(map_len); |
| 432 rv = entry_->ReadData(kSparseIndex, sizeof(sparse_header_), buf, map_len, | 435 rv = entry_->ReadData(kSparseIndex, |
| 436 sizeof(sparse_header_), |
| 437 buf.get(), |
| 438 map_len, |
| 433 CompletionCallback()); | 439 CompletionCallback()); |
| 434 if (rv != map_len) | 440 if (rv != map_len) |
| 435 return net::ERR_CACHE_READ_FAILURE; | 441 return net::ERR_CACHE_READ_FAILURE; |
| 436 | 442 |
| 437 // Grow the bitmap to the current size and copy the bits. | 443 // Grow the bitmap to the current size and copy the bits. |
| 438 children_map_.Resize(map_len * 8, false); | 444 children_map_.Resize(map_len * 8, false); |
| 439 children_map_.SetMap(reinterpret_cast<uint32*>(buf->data()), map_len); | 445 children_map_.SetMap(reinterpret_cast<uint32*>(buf->data()), map_len); |
| 440 return net::OK; | 446 return net::OK; |
| 441 } | 447 } |
| 442 | 448 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 465 EntryImpl* child = static_cast<EntryImpl*>(child_); | 471 EntryImpl* child = static_cast<EntryImpl*>(child_); |
| 466 if (!(CHILD_ENTRY & child->GetEntryFlags()) || | 472 if (!(CHILD_ENTRY & child->GetEntryFlags()) || |
| 467 child->GetDataSize(kSparseIndex) < | 473 child->GetDataSize(kSparseIndex) < |
| 468 static_cast<int>(sizeof(child_data_))) | 474 static_cast<int>(sizeof(child_data_))) |
| 469 return KillChildAndContinue(key, false); | 475 return KillChildAndContinue(key, false); |
| 470 | 476 |
| 471 scoped_refptr<net::WrappedIOBuffer> buf( | 477 scoped_refptr<net::WrappedIOBuffer> buf( |
| 472 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_))); | 478 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_))); |
| 473 | 479 |
| 474 // Read signature. | 480 // Read signature. |
| 475 int rv = child_->ReadData(kSparseIndex, 0, buf, sizeof(child_data_), | 481 int rv = child_->ReadData( |
| 476 CompletionCallback()); | 482 kSparseIndex, 0, buf.get(), sizeof(child_data_), CompletionCallback()); |
| 477 if (rv != sizeof(child_data_)) | 483 if (rv != sizeof(child_data_)) |
| 478 return KillChildAndContinue(key, true); // This is a fatal failure. | 484 return KillChildAndContinue(key, true); // This is a fatal failure. |
| 479 | 485 |
| 480 if (child_data_.header.signature != sparse_header_.signature || | 486 if (child_data_.header.signature != sparse_header_.signature || |
| 481 child_data_.header.magic != kIndexMagic) | 487 child_data_.header.magic != kIndexMagic) |
| 482 return KillChildAndContinue(key, false); | 488 return KillChildAndContinue(key, false); |
| 483 | 489 |
| 484 if (child_data_.header.last_block_len < 0 || | 490 if (child_data_.header.last_block_len < 0 || |
| 485 child_data_.header.last_block_len > kBlockSize) { | 491 child_data_.header.last_block_len > kBlockSize) { |
| 486 // Make sure these values are always within range. | 492 // Make sure these values are always within range. |
| 487 child_data_.header.last_block_len = 0; | 493 child_data_.header.last_block_len = 0; |
| 488 child_data_.header.last_block = -1; | 494 child_data_.header.last_block = -1; |
| 489 } | 495 } |
| 490 | 496 |
| 491 return true; | 497 return true; |
| 492 } | 498 } |
| 493 | 499 |
| 494 void SparseControl::CloseChild() { | 500 void SparseControl::CloseChild() { |
| 495 scoped_refptr<net::WrappedIOBuffer> buf( | 501 scoped_refptr<net::WrappedIOBuffer> buf( |
| 496 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_))); | 502 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_))); |
| 497 | 503 |
| 498 // Save the allocation bitmap before closing the child entry. | 504 // Save the allocation bitmap before closing the child entry. |
| 499 int rv = child_->WriteData(kSparseIndex, 0, buf, sizeof(child_data_), | 505 int rv = child_->WriteData(kSparseIndex, |
| 506 0, |
| 507 buf.get(), |
| 508 sizeof(child_data_), |
| 500 CompletionCallback(), | 509 CompletionCallback(), |
| 501 false); | 510 false); |
| 502 if (rv != sizeof(child_data_)) | 511 if (rv != sizeof(child_data_)) |
| 503 DLOG(ERROR) << "Failed to save child data"; | 512 DLOG(ERROR) << "Failed to save child data"; |
| 504 child_->Release(); | 513 child_->Release(); |
| 505 child_ = NULL; | 514 child_ = NULL; |
| 506 } | 515 } |
| 507 | 516 |
| 508 std::string SparseControl::GenerateChildKey() { | 517 std::string SparseControl::GenerateChildKey() { |
| 509 return GenerateChildName(entry_->GetKey(), sparse_header_.signature, | 518 return GenerateChildName(entry_->GetKey(), sparse_header_.signature, |
| 510 offset_ >> 20); | 519 offset_ >> 20); |
| 511 } | 520 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 children_map_.Resize(Bitmap::RequiredArraySize(child_bit + 1) * 32, true); | 569 children_map_.Resize(Bitmap::RequiredArraySize(child_bit + 1) * 32, true); |
| 561 | 570 |
| 562 children_map_.Set(child_bit, value); | 571 children_map_.Set(child_bit, value); |
| 563 } | 572 } |
| 564 | 573 |
| 565 void SparseControl::WriteSparseData() { | 574 void SparseControl::WriteSparseData() { |
| 566 scoped_refptr<net::IOBuffer> buf(new net::WrappedIOBuffer( | 575 scoped_refptr<net::IOBuffer> buf(new net::WrappedIOBuffer( |
| 567 reinterpret_cast<const char*>(children_map_.GetMap()))); | 576 reinterpret_cast<const char*>(children_map_.GetMap()))); |
| 568 | 577 |
| 569 int len = children_map_.ArraySize() * 4; | 578 int len = children_map_.ArraySize() * 4; |
| 570 int rv = entry_->WriteData(kSparseIndex, sizeof(sparse_header_), buf, len, | 579 int rv = entry_->WriteData(kSparseIndex, |
| 571 CompletionCallback(), false); | 580 sizeof(sparse_header_), |
| 581 buf.get(), |
| 582 len, |
| 583 CompletionCallback(), |
| 584 false); |
| 572 if (rv != len) { | 585 if (rv != len) { |
| 573 DLOG(ERROR) << "Unable to save sparse map"; | 586 DLOG(ERROR) << "Unable to save sparse map"; |
| 574 } | 587 } |
| 575 } | 588 } |
| 576 | 589 |
| 577 bool SparseControl::VerifyRange() { | 590 bool SparseControl::VerifyRange() { |
| 578 DCHECK_GE(result_, 0); | 591 DCHECK_GE(result_, 0); |
| 579 | 592 |
| 580 child_offset_ = static_cast<int>(offset_) & (kMaxEntrySize - 1); | 593 child_offset_ = static_cast<int>(offset_) & (kMaxEntrySize - 1); |
| 581 child_len_ = std::min(buf_len_, kMaxEntrySize - child_offset_); | 594 child_len_ = std::min(buf_len_, kMaxEntrySize - child_offset_); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 // We know the real type of child_. | 677 // We know the real type of child_. |
| 665 EntryImpl* child = static_cast<EntryImpl*>(child_); | 678 EntryImpl* child = static_cast<EntryImpl*>(child_); |
| 666 child->SetEntryFlags(CHILD_ENTRY); | 679 child->SetEntryFlags(CHILD_ENTRY); |
| 667 | 680 |
| 668 memset(&child_data_, 0, sizeof(child_data_)); | 681 memset(&child_data_, 0, sizeof(child_data_)); |
| 669 child_data_.header = sparse_header_; | 682 child_data_.header = sparse_header_; |
| 670 | 683 |
| 671 scoped_refptr<net::WrappedIOBuffer> buf( | 684 scoped_refptr<net::WrappedIOBuffer> buf( |
| 672 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_))); | 685 new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_))); |
| 673 | 686 |
| 674 int rv = child_->WriteData(kSparseIndex, 0, buf, sizeof(child_data_), | 687 int rv = child_->WriteData(kSparseIndex, |
| 675 CompletionCallback(), false); | 688 0, |
| 689 buf.get(), |
| 690 sizeof(child_data_), |
| 691 CompletionCallback(), |
| 692 false); |
| 676 if (rv != sizeof(child_data_)) | 693 if (rv != sizeof(child_data_)) |
| 677 DLOG(ERROR) << "Failed to save child data"; | 694 DLOG(ERROR) << "Failed to save child data"; |
| 678 SetChildBit(true); | 695 SetChildBit(true); |
| 679 } | 696 } |
| 680 | 697 |
| 681 void SparseControl::DoChildrenIO() { | 698 void SparseControl::DoChildrenIO() { |
| 682 while (DoChildIO()) continue; | 699 while (DoChildIO()) continue; |
| 683 | 700 |
| 684 // Range operations are finished synchronously, often without setting | 701 // Range operations are finished synchronously, often without setting |
| 685 // |finished_| to true. | 702 // |finished_| to true. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 | 737 |
| 721 int rv = 0; | 738 int rv = 0; |
| 722 switch (operation_) { | 739 switch (operation_) { |
| 723 case kReadOperation: | 740 case kReadOperation: |
| 724 if (entry_->net_log().IsLoggingAllEvents()) { | 741 if (entry_->net_log().IsLoggingAllEvents()) { |
| 725 entry_->net_log().BeginEvent( | 742 entry_->net_log().BeginEvent( |
| 726 net::NetLog::TYPE_SPARSE_READ_CHILD_DATA, | 743 net::NetLog::TYPE_SPARSE_READ_CHILD_DATA, |
| 727 CreateNetLogSparseReadWriteCallback(child_->net_log().source(), | 744 CreateNetLogSparseReadWriteCallback(child_->net_log().source(), |
| 728 child_len_)); | 745 child_len_)); |
| 729 } | 746 } |
| 730 rv = child_->ReadDataImpl(kSparseData, child_offset_, user_buf_, | 747 rv = child_->ReadDataImpl( |
| 731 child_len_, callback); | 748 kSparseData, child_offset_, user_buf_.get(), child_len_, callback); |
| 732 break; | 749 break; |
| 733 case kWriteOperation: | 750 case kWriteOperation: |
| 734 if (entry_->net_log().IsLoggingAllEvents()) { | 751 if (entry_->net_log().IsLoggingAllEvents()) { |
| 735 entry_->net_log().BeginEvent( | 752 entry_->net_log().BeginEvent( |
| 736 net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA, | 753 net::NetLog::TYPE_SPARSE_WRITE_CHILD_DATA, |
| 737 CreateNetLogSparseReadWriteCallback(child_->net_log().source(), | 754 CreateNetLogSparseReadWriteCallback(child_->net_log().source(), |
| 738 child_len_)); | 755 child_len_)); |
| 739 } | 756 } |
| 740 rv = child_->WriteDataImpl(kSparseData, child_offset_, user_buf_, | 757 rv = child_->WriteDataImpl(kSparseData, |
| 741 child_len_, callback, false); | 758 child_offset_, |
| 759 user_buf_.get(), |
| 760 child_len_, |
| 761 callback, |
| 762 false); |
| 742 break; | 763 break; |
| 743 case kGetRangeOperation: | 764 case kGetRangeOperation: |
| 744 rv = DoGetAvailableRange(); | 765 rv = DoGetAvailableRange(); |
| 745 break; | 766 break; |
| 746 default: | 767 default: |
| 747 NOTREACHED(); | 768 NOTREACHED(); |
| 748 } | 769 } |
| 749 | 770 |
| 750 if (rv == net::ERR_IO_PENDING) { | 771 if (rv == net::ERR_IO_PENDING) { |
| 751 if (!pending_) { | 772 if (!pending_) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 return; | 841 return; |
| 821 } | 842 } |
| 822 | 843 |
| 823 UpdateRange(result); | 844 UpdateRange(result); |
| 824 | 845 |
| 825 result_ += result; | 846 result_ += result; |
| 826 offset_ += result; | 847 offset_ += result; |
| 827 buf_len_ -= result; | 848 buf_len_ -= result; |
| 828 | 849 |
| 829 // We'll be reusing the user provided buffer for the next chunk. | 850 // We'll be reusing the user provided buffer for the next chunk. |
| 830 if (buf_len_ && user_buf_) | 851 if (buf_len_ && user_buf_.get()) |
| 831 user_buf_->DidConsume(result); | 852 user_buf_->DidConsume(result); |
| 832 } | 853 } |
| 833 | 854 |
| 834 void SparseControl::OnChildIOCompleted(int result) { | 855 void SparseControl::OnChildIOCompleted(int result) { |
| 835 DCHECK_NE(net::ERR_IO_PENDING, result); | 856 DCHECK_NE(net::ERR_IO_PENDING, result); |
| 836 DoChildIOCompleted(result); | 857 DoChildIOCompleted(result); |
| 837 | 858 |
| 838 if (abort_) { | 859 if (abort_) { |
| 839 // We'll return the current result of the operation, which may be less than | 860 // We'll return the current result of the operation, which may be less than |
| 840 // the bytes to read or write, but the user cancelled the operation. | 861 // the bytes to read or write, but the user cancelled the operation. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 877 CompletionCallback cb = abort_callbacks_[i]; | 898 CompletionCallback cb = abort_callbacks_[i]; |
| 878 if (i == abort_callbacks_.size() - 1) | 899 if (i == abort_callbacks_.size() - 1) |
| 879 abort_callbacks_.clear(); | 900 abort_callbacks_.clear(); |
| 880 | 901 |
| 881 entry_->Release(); // Don't touch object after this line. | 902 entry_->Release(); // Don't touch object after this line. |
| 882 cb.Run(net::OK); | 903 cb.Run(net::OK); |
| 883 } | 904 } |
| 884 } | 905 } |
| 885 | 906 |
| 886 } // namespace disk_cache | 907 } // namespace disk_cache |
| OLD | NEW |