+
+ /*
+ * Do not update the free block count. This flags is specified
+ * when a volume is being truncated.
+ */
+ if ((flags & HFS_ALLOC_SKIPFREEBLKS) == 0) {
+ vcb->freeBlocks += numBlocks;
+ }
+
+ vcb->hfs_freed_block_count += numBlocks;
+ if (firstBlock < vcb->sparseAllocation) {
+ vcb->sparseAllocation = firstBlock;
+ }
+
+ if (vcb->nextAllocation == (firstBlock + numBlocks)) {
+ HFS_UPDATE_NEXT_ALLOCATION(vcb, (vcb->nextAllocation - numBlocks));
+ }
+
+ if (free_extent_cache_active(vcb) == 0) {
+ goto skip_cache;
+ }
+
+ tempWord = vcb->vcbFreeExtCnt;
+ // Add this free chunk to the free extent list
+ if (vcb->hfs_flags & HFS_HAS_SPARSE_DEVICE) {
+ // Sorted by start block
+ if (tempWord == kMaxFreeExtents && vcb->vcbFreeExt[kMaxFreeExtents-1].startBlock > firstBlock)
+ --tempWord;
+ if (tempWord < kMaxFreeExtents)
+ {
+ // We're going to add this extent. Bubble any smaller extents down in the list.
+ while (tempWord && vcb->vcbFreeExt[tempWord-1].startBlock > firstBlock)
+ {
+ vcb->vcbFreeExt[tempWord] = vcb->vcbFreeExt[tempWord-1];
+ if (vcb->vcbFreeExt[tempWord].startBlock < vcb->sparseAllocation) {
+ vcb->sparseAllocation = vcb->vcbFreeExt[tempWord].startBlock;
+ }
+ --tempWord;
+ }
+ vcb->vcbFreeExt[tempWord].startBlock = firstBlock;
+ vcb->vcbFreeExt[tempWord].blockCount = numBlocks;
+
+ if (vcb->vcbFreeExtCnt < kMaxFreeExtents) {
+ ++vcb->vcbFreeExtCnt;
+ }
+ }
+ } else {
+ // Sorted by num blocks
+ if (tempWord == kMaxFreeExtents && vcb->vcbFreeExt[kMaxFreeExtents-1].blockCount < numBlocks)
+ --tempWord;
+ if (tempWord < kMaxFreeExtents)
+ {
+ // We're going to add this extent. Bubble any smaller extents down in the list.
+ while (tempWord && vcb->vcbFreeExt[tempWord-1].blockCount < numBlocks)
+ {
+ vcb->vcbFreeExt[tempWord] = vcb->vcbFreeExt[tempWord-1];
+ if (vcb->vcbFreeExt[tempWord].startBlock < vcb->sparseAllocation) {
+ vcb->sparseAllocation = vcb->vcbFreeExt[tempWord].startBlock;
+ }
+ --tempWord;
+ }
+ vcb->vcbFreeExt[tempWord].startBlock = firstBlock;
+ vcb->vcbFreeExt[tempWord].blockCount = numBlocks;
+
+ if (vcb->vcbFreeExtCnt < kMaxFreeExtents) {
+ ++vcb->vcbFreeExtCnt;
+ }
+ }
+ }
+
+skip_cache: