• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/disk_cache/sparse_control.h"
6 
7 #include "base/format_macros.h"
8 #include "base/logging.h"
9 #include "base/message_loop.h"
10 #include "base/string_util.h"
11 #include "base/time.h"
12 #include "net/base/io_buffer.h"
13 #include "net/base/net_errors.h"
14 #include "net/disk_cache/backend_impl.h"
15 #include "net/disk_cache/entry_impl.h"
16 #include "net/disk_cache/file.h"
17 
18 using base::Time;
19 
20 namespace {
21 
22 // Stream of the sparse data index.
23 const int kSparseIndex = 2;
24 
25 // Stream of the sparse data.
26 const int kSparseData = 1;
27 
28 // We can have up to 64k children.
29 const int kMaxMapSize = 8 * 1024;
30 
31 // The maximum number of bytes that a child can store.
32 const int kMaxEntrySize = 0x100000;
33 
34 // The size of each data block (tracked by the child allocation bitmap).
35 const int kBlockSize = 1024;
36 
37 // Returns the name of of a child entry given the base_name and signature of the
38 // parent and the child_id.
39 // If the entry is called entry_name, child entries will be named something
40 // like Range_entry_name:XXX:YYY where XXX is the entry signature and YYY is the
41 // number of the particular child.
GenerateChildName(const std::string & base_name,int64 signature,int64 child_id)42 std::string GenerateChildName(const std::string& base_name, int64 signature,
43                               int64 child_id) {
44   return StringPrintf("Range_%s:%" PRIx64 ":%" PRIx64, base_name.c_str(),
45                       signature, child_id);
46 }
47 
48 // This class deletes the children of a sparse entry.
49 class ChildrenDeleter
50     : public base::RefCounted<ChildrenDeleter>,
51       public disk_cache::FileIOCallback {
52  public:
ChildrenDeleter(disk_cache::BackendImpl * backend,const std::string & name)53   ChildrenDeleter(disk_cache::BackendImpl* backend, const std::string& name)
54       : backend_(backend), name_(name) {}
55 
56   virtual void OnFileIOComplete(int bytes_copied);
57 
58   // Two ways of deleting the children: if we have the children map, use Start()
59   // directly, otherwise pass the data address to ReadData().
60   void Start(char* buffer, int len);
61   void ReadData(disk_cache::Addr address, int len);
62 
63  private:
64   friend class base::RefCounted<ChildrenDeleter>;
~ChildrenDeleter()65   ~ChildrenDeleter() {}
66 
67   void DeleteChildren();
68 
69   disk_cache::BackendImpl* backend_;
70   std::string name_;
71   disk_cache::Bitmap children_map_;
72   int64 signature_;
73   scoped_array<char> buffer_;
74   DISALLOW_EVIL_CONSTRUCTORS(ChildrenDeleter);
75 };
76 
77 // This is the callback of the file operation.
OnFileIOComplete(int bytes_copied)78 void ChildrenDeleter::OnFileIOComplete(int bytes_copied) {
79   char* buffer = buffer_.release();
80   Start(buffer, bytes_copied);
81 }
82 
Start(char * buffer,int len)83 void ChildrenDeleter::Start(char* buffer, int len) {
84   buffer_.reset(buffer);
85   if (len < static_cast<int>(sizeof(disk_cache::SparseData)))
86     return Release();
87 
88   // Just copy the information from |buffer|, delete |buffer| and start deleting
89   // the child entries.
90   disk_cache::SparseData* data =
91       reinterpret_cast<disk_cache::SparseData*>(buffer);
92   signature_ = data->header.signature;
93 
94   int num_bits = (len - sizeof(disk_cache::SparseHeader)) * 8;
95   children_map_.Resize(num_bits, false);
96   children_map_.SetMap(data->bitmap, num_bits / 32);
97   buffer_.reset();
98 
99   DeleteChildren();
100 }
101 
ReadData(disk_cache::Addr address,int len)102 void ChildrenDeleter::ReadData(disk_cache::Addr address, int len) {
103   DCHECK(address.is_block_file());
104   disk_cache::File* file(backend_->File(address));
105   if (!file)
106     return Release();
107 
108   size_t file_offset = address.start_block() * address.BlockSize() +
109                        disk_cache::kBlockHeaderSize;
110 
111   buffer_.reset(new char[len]);
112   bool completed;
113   if (!file->Read(buffer_.get(), len, file_offset, this, &completed))
114     return Release();
115 
116   if (completed)
117     OnFileIOComplete(len);
118 
119   // And wait until OnFileIOComplete gets called.
120 }
121 
DeleteChildren()122 void ChildrenDeleter::DeleteChildren() {
123   int child_id = 0;
124   if (!children_map_.FindNextSetBit(&child_id)) {
125     // We are done. Just delete this object.
126     return Release();
127   }
128   std::string child_name = GenerateChildName(name_, signature_, child_id);
129   backend_->DoomEntry(child_name);
130   children_map_.Set(child_id, false);
131 
132   // Post a task to delete the next child.
133   MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
134       this, &ChildrenDeleter::DeleteChildren));
135 }
136 
137 }  // namespace.
138 
139 namespace disk_cache {
140 
~SparseControl()141 SparseControl::~SparseControl() {
142   if (child_)
143     CloseChild();
144   if (init_)
145     WriteSparseData();
146 }
147 
Init()148 int SparseControl::Init() {
149   DCHECK(!init_);
150 
151   // We should not have sparse data for the exposed entry.
152   if (entry_->GetDataSize(kSparseData))
153     return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
154 
155   // Now see if there is something where we store our data.
156   int rv = net::OK;
157   int data_len = entry_->GetDataSize(kSparseIndex);
158   if (!data_len) {
159     rv = CreateSparseEntry();
160   } else {
161     rv = OpenSparseEntry(data_len);
162   }
163 
164   if (rv == net::OK)
165     init_ = true;
166   return rv;
167 }
168 
StartIO(SparseOperation op,int64 offset,net::IOBuffer * buf,int buf_len,net::CompletionCallback * callback)169 int SparseControl::StartIO(SparseOperation op, int64 offset, net::IOBuffer* buf,
170                            int buf_len, net::CompletionCallback* callback) {
171   DCHECK(init_);
172   // We don't support simultaneous IO for sparse data.
173   if (operation_ != kNoOperation)
174     return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
175 
176   if (offset < 0 || buf_len < 0)
177     return net::ERR_INVALID_ARGUMENT;
178 
179   // We only support up to 64 GB.
180   if (offset + buf_len >= 0x1000000000LL || offset + buf_len < 0)
181     return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
182 
183   DCHECK(!user_buf_);
184   DCHECK(!user_callback_);
185 
186   if (!buf && (op == kReadOperation || op == kWriteOperation))
187     return 0;
188 
189   // Copy the operation parameters.
190   operation_ = op;
191   offset_ = offset;
192   user_buf_ = buf ? new net::DrainableIOBuffer(buf, buf_len) : NULL;
193   buf_len_ = buf_len;
194   user_callback_ = callback;
195 
196   result_ = 0;
197   pending_ = false;
198   finished_ = false;
199   abort_ = false;
200 
201   DoChildrenIO();
202 
203   if (!pending_) {
204     // Everything was done synchronously.
205     operation_ = kNoOperation;
206     user_buf_ = NULL;
207     user_callback_ = NULL;
208     return result_;
209   }
210 
211   return net::ERR_IO_PENDING;
212 }
213 
GetAvailableRange(int64 offset,int len,int64 * start)214 int SparseControl::GetAvailableRange(int64 offset, int len, int64* start) {
215   DCHECK(init_);
216   // We don't support simultaneous IO for sparse data.
217   if (operation_ != kNoOperation)
218     return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
219 
220   DCHECK(start);
221 
222   range_found_ = false;
223   int result = StartIO(kGetRangeOperation, offset, NULL, len, NULL);
224   if (range_found_) {
225     *start = offset_;
226     return result;
227   }
228 
229   // This is a failure. We want to return a valid start value in any case.
230   *start = offset;
231   return result < 0 ? result : 0;  // Don't mask error codes to the caller.
232 }
233 
CancelIO()234 void SparseControl::CancelIO() {
235   if (operation_ == kNoOperation)
236     return;
237   abort_ = true;
238 }
239 
ReadyToUse(net::CompletionCallback * completion_callback)240 int SparseControl::ReadyToUse(net::CompletionCallback* completion_callback) {
241   if (!abort_)
242     return net::OK;
243 
244   // We'll grab another reference to keep this object alive because we just have
245   // one extra reference due to the pending IO operation itself, but we'll
246   // release that one before invoking user_callback_.
247   entry_->AddRef();  // Balanced in DoAbortCallbacks.
248   abort_callbacks_.push_back(completion_callback);
249   return net::ERR_IO_PENDING;
250 }
251 
252 // Static
DeleteChildren(EntryImpl * entry)253 void SparseControl::DeleteChildren(EntryImpl* entry) {
254   DCHECK(entry->GetEntryFlags() & PARENT_ENTRY);
255   int data_len = entry->GetDataSize(kSparseIndex);
256   if (data_len < static_cast<int>(sizeof(SparseData)) ||
257       entry->GetDataSize(kSparseData))
258     return;
259 
260   int map_len = data_len - sizeof(SparseHeader);
261   if (map_len > kMaxMapSize || map_len % 4)
262     return;
263 
264   char* buffer;
265   Addr address;
266   entry->GetData(kSparseIndex, &buffer, &address);
267   if (!buffer && !address.is_initialized())
268     return;
269 
270   ChildrenDeleter* deleter = new ChildrenDeleter(entry->backend_,
271                                                  entry->GetKey());
272   // The object will self destruct when finished.
273   deleter->AddRef();
274 
275   if (buffer) {
276     MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
277         deleter, &ChildrenDeleter::Start, buffer, data_len));
278   } else {
279     MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
280         deleter, &ChildrenDeleter::ReadData, address, data_len));
281   }
282 }
283 
284 // We are going to start using this entry to store sparse data, so we have to
285 // initialize our control info.
CreateSparseEntry()286 int SparseControl::CreateSparseEntry() {
287   if (CHILD_ENTRY & entry_->GetEntryFlags())
288     return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
289 
290   memset(&sparse_header_, 0, sizeof(sparse_header_));
291   sparse_header_.signature = Time::Now().ToInternalValue();
292   sparse_header_.magic = kIndexMagic;
293   sparse_header_.parent_key_len = entry_->GetKey().size();
294   children_map_.Resize(kNumSparseBits, true);
295 
296   // Save the header. The bitmap is saved in the destructor.
297   scoped_refptr<net::IOBuffer> buf =
298       new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_));
299 
300   int rv = entry_->WriteData(kSparseIndex, 0, buf, sizeof(sparse_header_), NULL,
301                              false);
302   if (rv != sizeof(sparse_header_)) {
303     DLOG(ERROR) << "Unable to save sparse_header_";
304     return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
305   }
306 
307   entry_->SetEntryFlags(PARENT_ENTRY);
308   return net::OK;
309 }
310 
311 // We are opening an entry from disk. Make sure that our control data is there.
OpenSparseEntry(int data_len)312 int SparseControl::OpenSparseEntry(int data_len) {
313   if (data_len < static_cast<int>(sizeof(SparseData)))
314     return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
315 
316   if (entry_->GetDataSize(kSparseData))
317     return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
318 
319   if (!(PARENT_ENTRY & entry_->GetEntryFlags()))
320     return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
321 
322   // Dont't go over board with the bitmap. 8 KB gives us offsets up to 64 GB.
323   int map_len = data_len - sizeof(sparse_header_);
324   if (map_len > kMaxMapSize || map_len % 4)
325     return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
326 
327   scoped_refptr<net::IOBuffer> buf =
328       new net::WrappedIOBuffer(reinterpret_cast<char*>(&sparse_header_));
329 
330   // Read header.
331   int rv = entry_->ReadData(kSparseIndex, 0, buf, sizeof(sparse_header_), NULL);
332   if (rv != static_cast<int>(sizeof(sparse_header_)))
333     return net::ERR_CACHE_READ_FAILURE;
334 
335   // The real validation should be performed by the caller. This is just to
336   // double check.
337   if (sparse_header_.magic != kIndexMagic ||
338       sparse_header_.parent_key_len !=
339           static_cast<int>(entry_->GetKey().size()))
340     return net::ERR_CACHE_OPERATION_NOT_SUPPORTED;
341 
342   // Read the actual bitmap.
343   buf = new net::IOBuffer(map_len);
344   rv = entry_->ReadData(kSparseIndex, sizeof(sparse_header_), buf, map_len,
345                         NULL);
346   if (rv != map_len)
347     return net::ERR_CACHE_READ_FAILURE;
348 
349   // Grow the bitmap to the current size and copy the bits.
350   children_map_.Resize(map_len * 8, false);
351   children_map_.SetMap(reinterpret_cast<uint32*>(buf->data()), map_len);
352   return net::OK;
353 }
354 
OpenChild()355 bool SparseControl::OpenChild() {
356   DCHECK_GE(result_, 0);
357 
358   std::string key = GenerateChildKey();
359   if (child_) {
360     // Keep using the same child or open another one?.
361     if (key == child_->GetKey())
362       return true;
363     CloseChild();
364   }
365 
366   // Se if we are tracking this child.
367   bool child_present = ChildPresent();
368   if (!child_present || !entry_->backend_->OpenEntry(key, &child_))
369     return ContinueWithoutChild(key);
370 
371   EntryImpl* child = static_cast<EntryImpl*>(child_);
372   if (!(CHILD_ENTRY & child->GetEntryFlags()) ||
373       child->GetDataSize(kSparseIndex) <
374           static_cast<int>(sizeof(child_data_)))
375     return KillChildAndContinue(key, false);
376 
377   scoped_refptr<net::WrappedIOBuffer> buf =
378       new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_));
379 
380   // Read signature.
381   int rv = child_->ReadData(kSparseIndex, 0, buf, sizeof(child_data_), NULL);
382   if (rv != sizeof(child_data_))
383     return KillChildAndContinue(key, true);  // This is a fatal failure.
384 
385   if (child_data_.header.signature != sparse_header_.signature ||
386       child_data_.header.magic != kIndexMagic)
387     return KillChildAndContinue(key, false);
388 
389   if (child_data_.header.last_block_len < 0 ||
390       child_data_.header.last_block_len > kBlockSize) {
391     // Make sure this values are always within range.
392     child_data_.header.last_block_len = 0;
393     child_data_.header.last_block = -1;
394   }
395 
396   return true;
397 }
398 
CloseChild()399 void SparseControl::CloseChild() {
400   scoped_refptr<net::WrappedIOBuffer> buf =
401       new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_));
402 
403   // Save the allocation bitmap before closing the child entry.
404   int rv = child_->WriteData(kSparseIndex, 0, buf, sizeof(child_data_),
405                              NULL, false);
406   if (rv != sizeof(child_data_))
407     DLOG(ERROR) << "Failed to save child data";
408   child_->Close();
409   child_ = NULL;
410 }
411 
GenerateChildKey()412 std::string SparseControl::GenerateChildKey() {
413   return GenerateChildName(entry_->GetKey(), sparse_header_.signature,
414                            offset_ >> 20);
415 }
416 
417 // We are deleting the child because something went wrong.
KillChildAndContinue(const std::string & key,bool fatal)418 bool SparseControl::KillChildAndContinue(const std::string& key, bool fatal) {
419   SetChildBit(false);
420   child_->Doom();
421   child_->Close();
422   child_ = NULL;
423   if (fatal) {
424     result_ = net::ERR_CACHE_READ_FAILURE;
425     return false;
426   }
427   return ContinueWithoutChild(key);
428 }
429 
430 // We were not able to open this child; see what we can do.
ContinueWithoutChild(const std::string & key)431 bool SparseControl::ContinueWithoutChild(const std::string& key) {
432   if (kReadOperation == operation_)
433     return false;
434   if (kGetRangeOperation == operation_)
435     return true;
436 
437   if (!entry_->backend_->CreateEntry(key, &child_)) {
438     child_ = NULL;
439     result_ = net::ERR_CACHE_READ_FAILURE;
440     return false;
441   }
442   // Write signature.
443   InitChildData();
444   return true;
445 }
446 
ChildPresent()447 bool SparseControl::ChildPresent() {
448   int child_bit = static_cast<int>(offset_ >> 20);
449   if (children_map_.Size() <= child_bit)
450     return false;
451 
452   return children_map_.Get(child_bit);
453 }
454 
SetChildBit(bool value)455 void SparseControl::SetChildBit(bool value) {
456   int child_bit = static_cast<int>(offset_ >> 20);
457 
458   // We may have to increase the bitmap of child entries.
459   if (children_map_.Size() <= child_bit)
460     children_map_.Resize(Bitmap::RequiredArraySize(child_bit + 1) * 32, true);
461 
462   children_map_.Set(child_bit, value);
463 }
464 
WriteSparseData()465 void SparseControl::WriteSparseData() {
466   scoped_refptr<net::IOBuffer> buf = new net::WrappedIOBuffer(
467       reinterpret_cast<const char*>(children_map_.GetMap()));
468 
469   int len = children_map_.ArraySize() * 4;
470   int rv = entry_->WriteData(kSparseIndex, sizeof(sparse_header_), buf, len,
471                              NULL, false);
472   if (rv != len) {
473     DLOG(ERROR) << "Unable to save sparse map";
474   }
475 }
476 
VerifyRange()477 bool SparseControl::VerifyRange() {
478   DCHECK_GE(result_, 0);
479 
480   child_offset_ = static_cast<int>(offset_) & (kMaxEntrySize - 1);
481   child_len_ = std::min(buf_len_, kMaxEntrySize - child_offset_);
482 
483   // We can write to (or get info from) anywhere in this child.
484   if (operation_ != kReadOperation)
485     return true;
486 
487   // Check that there are no holes in this range.
488   int last_bit = (child_offset_ + child_len_ + 1023) >> 10;
489   int start = child_offset_ >> 10;
490   if (child_map_.FindNextBit(&start, last_bit, false)) {
491     // Something is not here.
492     DCHECK_GE(child_data_.header.last_block_len, 0);
493     DCHECK_LT(child_data_.header.last_block_len, kMaxEntrySize);
494     int partial_block_len = PartialBlockLength(start);
495     if (start == child_offset_ >> 10) {
496       // It looks like we don't have anything.
497       if (partial_block_len <= (child_offset_ & (kBlockSize - 1)))
498         return false;
499     }
500 
501     // We have the first part.
502     child_len_ = (start << 10) - child_offset_;
503     if (partial_block_len) {
504       // We may have a few extra bytes.
505       child_len_ = std::min(child_len_ + partial_block_len, buf_len_);
506     }
507     // There is no need to read more after this one.
508     buf_len_ = child_len_;
509   }
510   return true;
511 }
512 
UpdateRange(int result)513 void SparseControl::UpdateRange(int result) {
514   if (result <= 0 || operation_ != kWriteOperation)
515     return;
516 
517   DCHECK_GE(child_data_.header.last_block_len, 0);
518   DCHECK_LT(child_data_.header.last_block_len, kMaxEntrySize);
519 
520   // Write the bitmap.
521   int first_bit = child_offset_ >> 10;
522   int block_offset = child_offset_ & (kBlockSize - 1);
523   if (block_offset && (child_data_.header.last_block != first_bit ||
524                        child_data_.header.last_block_len < block_offset)) {
525     // The first block is not completely filled; ignore it.
526     first_bit++;
527   }
528 
529   int last_bit = (child_offset_ + result) >> 10;
530   block_offset = (child_offset_ + result) & (kBlockSize - 1);
531 
532   // This condition will hit with the following criteria:
533   // 1. The first byte doesn't follow the last write.
534   // 2. The first byte is in the middle of a block.
535   // 3. The first byte and the last byte are in the same block.
536   if (first_bit > last_bit)
537     return;
538 
539   if (block_offset && !child_map_.Get(last_bit)) {
540     // The last block is not completely filled; save it for later.
541     child_data_.header.last_block = last_bit;
542     child_data_.header.last_block_len = block_offset;
543   } else {
544     child_data_.header.last_block = -1;
545   }
546 
547   child_map_.SetRange(first_bit, last_bit, true);
548 }
549 
PartialBlockLength(int block_index) const550 int SparseControl::PartialBlockLength(int block_index) const {
551   if (block_index == child_data_.header.last_block)
552     return child_data_.header.last_block_len;
553 
554   // This may be the last stored index.
555   int entry_len = child_->GetDataSize(kSparseData);
556   if (block_index == entry_len >> 10)
557     return entry_len & (kBlockSize - 1);
558 
559   // This is really empty.
560   return 0;
561 }
562 
InitChildData()563 void SparseControl::InitChildData() {
564   // We know the real type of child_.
565   EntryImpl* child = static_cast<EntryImpl*>(child_);
566   child->SetEntryFlags(CHILD_ENTRY);
567 
568   memset(&child_data_, 0, sizeof(child_data_));
569   child_data_.header = sparse_header_;
570 
571   scoped_refptr<net::WrappedIOBuffer> buf =
572       new net::WrappedIOBuffer(reinterpret_cast<char*>(&child_data_));
573 
574   int rv = child_->WriteData(kSparseIndex, 0, buf, sizeof(child_data_),
575                              NULL, false);
576   if (rv != sizeof(child_data_))
577     DLOG(ERROR) << "Failed to save child data";
578   SetChildBit(true);
579 }
580 
DoChildrenIO()581 void SparseControl::DoChildrenIO() {
582   while (DoChildIO()) continue;
583 
584   if (pending_ && finished_)
585     DoUserCallback();
586 }
587 
DoChildIO()588 bool SparseControl::DoChildIO() {
589   finished_ = true;
590   if (!buf_len_ || result_ < 0)
591     return false;
592 
593   if (!OpenChild())
594     return false;
595 
596   if (!VerifyRange())
597     return false;
598 
599   // We have more work to do. Let's not trigger a callback to the caller.
600   finished_ = false;
601   net::CompletionCallback* callback = user_callback_ ? &child_callback_ : NULL;
602 
603   int rv = 0;
604   switch (operation_) {
605     case kReadOperation:
606       rv = child_->ReadData(kSparseData, child_offset_, user_buf_, child_len_,
607                             callback);
608       break;
609     case kWriteOperation:
610       rv = child_->WriteData(kSparseData, child_offset_, user_buf_, child_len_,
611                              callback, false);
612       break;
613     case kGetRangeOperation:
614       rv = DoGetAvailableRange();
615       break;
616     default:
617       NOTREACHED();
618   }
619 
620   if (rv == net::ERR_IO_PENDING) {
621     if (!pending_) {
622       pending_ = true;
623       // The child will protect himself against closing the entry while IO is in
624       // progress. However, this entry can still be closed, and that would not
625       // be a good thing for us, so we increase the refcount until we're
626       // finished doing sparse stuff.
627       entry_->AddRef();  // Balanced in DoUserCallback.
628     }
629     return false;
630   }
631   if (!rv)
632     return false;
633 
634   DoChildIOCompleted(rv);
635   return true;
636 }
637 
DoGetAvailableRange()638 int SparseControl::DoGetAvailableRange() {
639   if (!child_)
640     return child_len_;  // Move on to the next child.
641 
642   // Check that there are no holes in this range.
643   int last_bit = (child_offset_ + child_len_ + 1023) >> 10;
644   int start = child_offset_ >> 10;
645   int partial_start_bytes = PartialBlockLength(start);
646   int found = start;
647   int bits_found = child_map_.FindBits(&found, last_bit, true);
648 
649   // We don't care if there is a partial block in the middle of the range.
650   int block_offset = child_offset_ & (kBlockSize - 1);
651   if (!bits_found && partial_start_bytes <= block_offset)
652     return child_len_;
653 
654   // We are done. Just break the loop and reset result_ to our real result.
655   range_found_ = true;
656 
657   // found now points to the first 1. Lets see if we have zeros before it.
658   int empty_start = std::max((found << 10) - child_offset_, 0);
659 
660   int bytes_found = bits_found << 10;
661   bytes_found += PartialBlockLength(found + bits_found);
662 
663   if (start == found)
664     bytes_found -= block_offset;
665 
666   // If the user is searching past the end of this child, bits_found is the
667   // right result; otherwise, we have some empty space at the start of this
668   // query that we have to subtract from the range that we searched.
669   result_ = std::min(bytes_found, child_len_ - empty_start);
670 
671   if (!bits_found) {
672     result_ = std::min(partial_start_bytes - block_offset, child_len_);
673     empty_start = 0;
674   }
675 
676   // Only update offset_ when this query found zeros at the start.
677   if (empty_start)
678     offset_ += empty_start;
679 
680   // This will actually break the loop.
681   buf_len_ = 0;
682   return 0;
683 }
684 
DoChildIOCompleted(int result)685 void SparseControl::DoChildIOCompleted(int result) {
686   if (result < 0) {
687     // We fail the whole operation if we encounter an error.
688     result_ = result;
689     return;
690   }
691 
692   UpdateRange(result);
693 
694   result_ += result;
695   offset_ += result;
696   buf_len_ -= result;
697 
698   // We'll be reusing the user provided buffer for the next chunk.
699   if (buf_len_ && user_buf_)
700     user_buf_->DidConsume(result);
701 }
702 
OnChildIOCompleted(int result)703 void SparseControl::OnChildIOCompleted(int result) {
704   DCHECK_NE(net::ERR_IO_PENDING, result);
705   DoChildIOCompleted(result);
706 
707   if (abort_) {
708     // We'll return the current result of the operation, which may be less than
709     // the bytes to read or write, but the user cancelled the operation.
710     abort_ = false;
711     DoUserCallback();
712     return DoAbortCallbacks();
713   }
714 
715   // We are running a callback from the message loop. It's time to restart what
716   // we were doing before.
717   DoChildrenIO();
718 }
719 
DoUserCallback()720 void SparseControl::DoUserCallback() {
721   DCHECK(user_callback_);
722   net::CompletionCallback* c = user_callback_;
723   user_callback_ = NULL;
724   user_buf_ = NULL;
725   pending_ = false;
726   operation_ = kNoOperation;
727   entry_->Release();  // Don't touch object after this line.
728   c->Run(result_);
729 }
730 
DoAbortCallbacks()731 void SparseControl::DoAbortCallbacks() {
732   for (size_t i = 0; i < abort_callbacks_.size(); i++) {
733     // Releasing all references to entry_ may result in the destruction of this
734     // object so we should not be touching it after the last Release().
735     net::CompletionCallback* c = abort_callbacks_[i];
736     if (i == abort_callbacks_.size() - 1)
737       abort_callbacks_.clear();
738 
739     entry_->Release();  // Don't touch object after this line.
740     c->Run(net::OK);
741   }
742 }
743 
744 }  // namespace disk_cache
745