2 * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 File: VolumeAllocation.c
31 Contains: Routines for accessing and modifying the volume bitmap.
35 Copyright: © 1996-2001 by Apple Computer, Inc., all rights reserved.
42 Allocate space on a volume. Can allocate space contiguously.
43 If not contiguous, then allocation may be less than what was
44 asked for. Returns the starting block number, and number of
45 blocks. (Will only do a single extent???)
47 Deallocate a contiguous run of allocation blocks.
49 invalidate_free_extent_cache Invalidate free extent cache for a given volume.
53 Mark a contiguous range of blocks as free. The corresponding
54 bits in the volume bitmap will be cleared.
56 Mark a contiguous range of blocks as allocated. The cor-
57 responding bits in the volume bitmap are set. Also tests to see
58 if any of the blocks were previously unallocated.
60 Find a contiguous range of blocks of a given size. The caller
61 specifies where to begin the search (by block number). The
62 block number of the first block in the range is returned.
64 Find and allocate a contiguous range of blocks up to a given size. The
65 first range of contiguous free blocks found are allocated, even if there
66 are fewer blocks than requested (and even if a contiguous range of blocks
67 of the given size exists elsewhere).
69 Find and allocate a contiguous range of blocks of a given size. If
70 a contiguous range of free blocks of the given size isn't found, then
71 the allocation fails (i.e. it is "all or nothing").
74 Try to allocate space from known free space in the volume's
78 Given an allocation block number, read the bitmap block that
79 contains that allocation block into a caller-supplied buffer.
82 Release a bitmap block back into the buffer cache.
85 #include "../../hfs_macos_defs.h"
87 #include <sys/types.h>
89 #include <sys/systm.h>
90 #include <sys/sysctl.h>
92 #include <kern/kalloc.h>
94 #include "../../hfs.h"
95 #include "../../hfs_dbg.h"
96 #include "../../hfs_format.h"
97 #include "../../hfs_endian.h"
99 #include "../headers/FileMgrInternal.h"
101 #ifndef CONFIG_HFS_TRIM
102 #define CONFIG_HFS_TRIM 0
111 kBitsWithinWordMask
= kBitsPerWord
-1
114 #define kLowBitInWordMask 0x00000001ul
115 #define kHighBitInWordMask 0x80000000ul
116 #define kAllBitsSetInWord 0xFFFFFFFFul
119 static OSErr
ReadBitmapBlock(
123 uintptr_t *blockRef
);
125 static OSErr
ReleaseBitmapBlock(
130 static OSErr
BlockAllocateAny(
132 u_int32_t startingBlock
,
133 u_int32_t endingBlock
,
136 u_int32_t
*actualStartBlock
,
137 u_int32_t
*actualNumBlocks
);
139 static OSErr
BlockAllocateContig(
141 u_int32_t startingBlock
,
145 u_int32_t
*actualStartBlock
,
146 u_int32_t
*actualNumBlocks
);
148 static OSErr
BlockFindContiguous(
150 u_int32_t startingBlock
,
151 u_int32_t endingBlock
,
155 u_int32_t
*actualStartBlock
,
156 u_int32_t
*actualNumBlocks
);
158 static OSErr
BlockAllocateKnown(
161 u_int32_t
*actualStartBlock
,
162 u_int32_t
*actualNumBlocks
);
164 static int free_extent_cache_active(
169 ;________________________________________________________________________________
171 ; Routine: hfs_unmap_free_extent
173 ; Function: Make note of a range of allocation blocks that should be
174 ; unmapped (trimmed). That is, the given range of blocks no
175 ; longer have useful content, and the device can unmap the
176 ; previous contents. For example, a solid state disk may reuse
177 ; the underlying storage for other blocks.
179 ; This routine is only supported for journaled volumes. The extent
180 ; being freed is passed to the journal code, and the extent will
181 ; be unmapped after the current transaction is written to disk.
184 ; hfsmp - The volume containing the allocation blocks.
185 ; startingBlock - The first allocation block of the extent being freed.
186 ; numBlocks - The number of allocation blocks of the extent being freed.
187 ;________________________________________________________________________________
189 static void hfs_unmap_free_extent(struct hfsmount
*hfsmp
, u_int32_t startingBlock
, u_int32_t numBlocks
)
191 if (CONFIG_HFS_TRIM
) {
196 if ((hfsmp
->hfs_flags
& HFS_UNMAP
) && (hfsmp
->jnl
!= NULL
)) {
197 offset
= (u_int64_t
) startingBlock
* hfsmp
->blockSize
+ (u_int64_t
) hfsmp
->hfsPlusIOPosOffset
;
198 length
= (u_int64_t
) numBlocks
* hfsmp
->blockSize
;
200 err
= journal_trim_add_extent(hfsmp
->jnl
, offset
, length
);
202 printf("hfs_unmap_free_extent: error %d from journal_trim_add_extent", err
);
203 hfsmp
->hfs_flags
&= ~HFS_UNMAP
;
211 ;________________________________________________________________________________
213 ; Routine: hfs_unmap_alloc_extent
215 ; Function: Make note of a range of allocation blocks, some of
216 ; which may have previously been passed to hfs_unmap_free_extent,
217 ; is now in use on the volume. The given blocks will be removed
218 ; from any pending DKIOCUNMAP.
221 ; hfsmp - The volume containing the allocation blocks.
222 ; startingBlock - The first allocation block of the extent being allocated.
223 ; numBlocks - The number of allocation blocks being allocated.
224 ;________________________________________________________________________________
226 static void hfs_unmap_alloc_extent(struct hfsmount
*hfsmp
, u_int32_t startingBlock
, u_int32_t numBlocks
)
228 if (CONFIG_HFS_TRIM
) {
233 if ((hfsmp
->hfs_flags
& HFS_UNMAP
) && (hfsmp
->jnl
!= NULL
)) {
234 offset
= (u_int64_t
) startingBlock
* hfsmp
->blockSize
+ (u_int64_t
) hfsmp
->hfsPlusIOPosOffset
;
235 length
= (u_int64_t
) numBlocks
* hfsmp
->blockSize
;
237 err
= journal_trim_remove_extent(hfsmp
->jnl
, offset
, length
);
239 printf("hfs_unmap_alloc_extent: error %d from journal_trim_remove_extent", err
);
240 hfsmp
->hfs_flags
&= ~HFS_UNMAP
;
248 ;________________________________________________________________________________
252 ; Function: Allocate space on a volume. If contiguous allocation is requested,
253 ; at least the requested number of bytes will be allocated or an
254 ; error will be returned. If contiguous allocation is not forced,
255 ; the space will be allocated at the first free fragment following
256 ; the requested starting allocation block. If there is not enough
257 ; room there, a block of less than the requested size will be
260 ; If the requested starting block is 0 (for new file allocations),
261 ; the volume's allocation block pointer will be used as a starting
265 ; vcb - Pointer to ExtendedVCB for the volume to allocate space on
266 ; fcb - Pointer to FCB for the file for which storage is being allocated
267 ; startingBlock - Preferred starting allocation block, 0 = no preference
268 ; forceContiguous - Force contiguous flag - if bit 0 set (NE), allocation is contiguous
269 ; or an error is returned
271 ; minBlocks - Number of blocks requested. If the allocation is non-contiguous,
272 ; less than this may actually be allocated
273 ; maxBlocks - The maximum number of blocks to allocate. If there is additional free
274 ; space after bytesRequested, then up to maxBlocks bytes should really
275 ; be allocated. (Used by ExtendFileC to round up allocations to a multiple
276 ; of the file's clump size.)
279 ; (result) - Error code, zero for successful allocation
280 ; *startBlock - Actual starting allocation block
281 ; *actualBlocks - Actual number of allocation blocks allocated
284 ; The volume bitmap is read and updated; the volume bitmap cache may be changed.
285 ;________________________________________________________________________________
288 sanity_check_free_ext(__unused ExtendedVCB
*vcb
, __unused
int check_allocated
)
293 for(i
=0; i
< vcb
->vcbFreeExtCnt
; i
++) {
294 u_int32_t start
, nblocks
;
296 start
= vcb
->vcbFreeExt
[i
].startBlock
;
297 nblocks
= vcb
->vcbFreeExt
[i
].blockCount
;
301 panic("hfs: %p: slot %d in the free extent array had a zero count (%d)\n", vcb
, i
, start
);
304 if (check_allocated
&& hfs_isallocated(vcb
, start
, nblocks
)) {
305 panic("hfs: %p: slot %d in the free extent array is bad (%d / %d)\n",
306 vcb
, i
, start
, nblocks
);
309 for(j
=i
+1; j
< vcb
->vcbFreeExtCnt
; j
++) {
310 if (start
== vcb
->vcbFreeExt
[j
].startBlock
) {
311 panic("hfs: %p: slot %d/%d are dups?! (%d / %d ; %d / %d)\n",
312 vcb
, i
, j
, start
, nblocks
, vcb
->vcbFreeExt
[i
].startBlock
,
313 vcb
->vcbFreeExt
[i
].blockCount
);
322 OSErr
BlockAllocate (
323 ExtendedVCB
*vcb
, /* which volume to allocate space on */
324 u_int32_t startingBlock
, /* preferred starting block, or 0 for no preference */
325 u_int32_t minBlocks
, /* desired number of blocks to allocate */
326 u_int32_t maxBlocks
, /* maximum number of blocks to allocate */
327 u_int32_t flags
, /* option flags */
328 u_int32_t
*actualStartBlock
, /* actual first block of allocation */
329 u_int32_t
*actualNumBlocks
) /* number of blocks actually allocated; if forceContiguous */
330 /* was zero, then this may represent fewer than minBlocks */
332 u_int32_t freeBlocks
;
334 Boolean updateAllocPtr
= false; // true if nextAllocation needs to be updated
336 Boolean forceContiguous
;
338 if (flags
& HFS_ALLOC_FORCECONTIG
) {
339 forceContiguous
= true;
341 forceContiguous
= false;
344 if (flags
& HFS_ALLOC_METAZONE
) {
351 // Initialize outputs in case we get an error
353 *actualStartBlock
= 0;
354 *actualNumBlocks
= 0;
355 freeBlocks
= hfs_freeblks(VCBTOHFS(vcb
), 0);
357 /* Skip free block check if blocks are being allocated for relocating
358 * data during truncating a volume.
360 * During hfs_truncatefs(), the volume free block count is updated
361 * before relocating data to reflect the total number of free blocks
362 * that will exist on the volume after resize is successful. This
363 * means that we have reserved allocation blocks required for relocating
364 * the data and hence there is no need to check the free blocks.
365 * It will also prevent resize failure when the number of blocks in
366 * an extent being relocated is more than the free blocks that will
367 * exist after the volume is resized.
369 if ((flags
& HFS_ALLOC_SKIPFREEBLKS
) == 0) {
370 // If the disk is already full, don't bother.
371 if (freeBlocks
== 0) {
375 if (forceContiguous
&& freeBlocks
< minBlocks
) {
381 * Clip if necessary so we don't over-subscribe the free blocks.
383 if (minBlocks
> freeBlocks
) {
384 minBlocks
= freeBlocks
;
386 if (maxBlocks
> freeBlocks
) {
387 maxBlocks
= freeBlocks
;
392 // If caller didn't specify a starting block number, then use the volume's
393 // next block to allocate from.
395 if (startingBlock
== 0) {
396 HFS_MOUNT_LOCK(vcb
, TRUE
);
397 if (vcb
->hfs_flags
& HFS_HAS_SPARSE_DEVICE
) {
398 startingBlock
= vcb
->sparseAllocation
;
400 startingBlock
= vcb
->nextAllocation
;
402 HFS_MOUNT_UNLOCK(vcb
, TRUE
);
403 updateAllocPtr
= true;
405 if (startingBlock
>= vcb
->allocLimit
) {
406 startingBlock
= 0; /* overflow so start at beginning */
410 // If the request must be contiguous, then find a sequence of free blocks
411 // that is long enough. Otherwise, find the first free block.
413 if (forceContiguous
) {
414 err
= BlockAllocateContig(vcb
, startingBlock
, minBlocks
, maxBlocks
,
415 useMetaZone
, actualStartBlock
, actualNumBlocks
);
417 * If we allocated from a new position then
418 * also update the roving allocator.
420 if ((err
== noErr
) &&
421 (*actualStartBlock
> startingBlock
) &&
422 ((*actualStartBlock
< VCBTOHFS(vcb
)->hfs_metazone_start
) ||
423 (*actualStartBlock
> VCBTOHFS(vcb
)->hfs_metazone_end
))) {
425 updateAllocPtr
= true;
429 * Scan the bitmap once, gather the N largest free extents, then
430 * allocate from these largest extents. Repeat as needed until
431 * we get all the space we needed. We could probably build up
432 * that list when the higher level caller tried (and failed) a
433 * contiguous allocation first.
435 err
= BlockAllocateKnown(vcb
, maxBlocks
, actualStartBlock
, actualNumBlocks
);
436 if (err
== dskFulErr
)
437 err
= BlockAllocateAny(vcb
, startingBlock
, vcb
->allocLimit
,
438 maxBlocks
, useMetaZone
, actualStartBlock
,
440 if (err
== dskFulErr
)
441 err
= BlockAllocateAny(vcb
, 1, startingBlock
, maxBlocks
,
442 useMetaZone
, actualStartBlock
,
447 // if we actually allocated something then go update the
448 // various bits of state that we maintain regardless of
449 // whether there was an error (i.e. partial allocations
450 // still need to update things like the free block count).
452 if (*actualNumBlocks
!= 0) {
456 // If we used the volume's roving allocation pointer, then we need to update it.
457 // Adding in the length of the current allocation might reduce the next allocate
458 // call by avoiding a re-scan of the already allocated space. However, the clump
459 // just allocated can quite conceivably end up being truncated or released when
460 // the file is closed or its EOF changed. Leaving the allocation pointer at the
461 // start of the last allocation will avoid unnecessary fragmentation in this case.
463 HFS_MOUNT_LOCK(vcb
, TRUE
);
465 if (vcb
->vcbFreeExtCnt
== 0 && vcb
->hfs_freed_block_count
== 0) {
466 vcb
->sparseAllocation
= *actualStartBlock
;
468 if (*actualNumBlocks
< vcb
->hfs_freed_block_count
) {
469 vcb
->hfs_freed_block_count
-= *actualNumBlocks
;
471 vcb
->hfs_freed_block_count
= 0;
474 if (updateAllocPtr
&&
475 ((*actualStartBlock
< VCBTOHFS(vcb
)->hfs_metazone_start
) ||
476 (*actualStartBlock
> VCBTOHFS(vcb
)->hfs_metazone_end
))) {
477 HFS_UPDATE_NEXT_ALLOCATION(vcb
, *actualStartBlock
);
480 for(i
=0; i
< (int)vcb
->vcbFreeExtCnt
; i
++) {
481 u_int32_t start
, end
;
483 start
= vcb
->vcbFreeExt
[i
].startBlock
;
484 end
= start
+ vcb
->vcbFreeExt
[i
].blockCount
;
486 if ( (*actualStartBlock
>= start
&& *actualStartBlock
< end
)
487 || ((*actualStartBlock
+ *actualNumBlocks
) > start
&& *actualStartBlock
< start
)) {
489 for(j
=i
; j
< (int)vcb
->vcbFreeExtCnt
-1; j
++) {
490 vcb
->vcbFreeExt
[j
] = vcb
->vcbFreeExt
[j
+1];
493 vcb
->vcbFreeExtCnt
--;
494 i
--; // so we'll check the guy we just copied down...
496 // keep looping because we may have invalidated more
497 // than one entry in the array
502 * Update the number of free blocks on the volume
504 * Skip updating the free blocks count if the block are
505 * being allocated to relocate data as part of hfs_truncatefs()
507 if ((flags
& HFS_ALLOC_SKIPFREEBLKS
) == 0) {
508 vcb
->freeBlocks
-= *actualNumBlocks
;
511 HFS_MOUNT_UNLOCK(vcb
, TRUE
);
513 sanity_check_free_ext(vcb
, 1);
515 hfs_generate_volume_notifications(VCBTOHFS(vcb
));
523 ;________________________________________________________________________________
525 ; Routine: BlkDealloc
527 ; Function: Update the bitmap to deallocate a run of disk allocation blocks
530 ; vcb - Pointer to ExtendedVCB for the volume to free space on
531 ; firstBlock - First allocation block to be freed
532 ; numBlocks - Number of allocation blocks to free up (must be > 0!)
535 ; (result) - Result code
538 ; The volume bitmap is read and updated; the volume bitmap cache may be changed.
539 ;________________________________________________________________________________
543 OSErr
BlockDeallocate (
544 ExtendedVCB
*vcb
, // Which volume to deallocate space on
545 u_int32_t firstBlock
, // First block in range to deallocate
546 u_int32_t numBlocks
, // Number of contiguous blocks to deallocate
553 // If no blocks to deallocate, then exit early
555 if (numBlocks
== 0) {
561 // Call internal routine to free the sequence of blocks
563 err
= BlockMarkFree(vcb
, firstBlock
, numBlocks
);
568 // Update the volume's free block count, and mark the VCB as dirty.
570 HFS_MOUNT_LOCK(vcb
, TRUE
);
573 * Do not update the free block count. This flags is specified
574 * when a volume is being truncated.
576 if ((flags
& HFS_ALLOC_SKIPFREEBLKS
) == 0) {
577 vcb
->freeBlocks
+= numBlocks
;
580 vcb
->hfs_freed_block_count
+= numBlocks
;
581 if (firstBlock
< vcb
->sparseAllocation
) {
582 vcb
->sparseAllocation
= firstBlock
;
585 if (vcb
->nextAllocation
== (firstBlock
+ numBlocks
)) {
586 HFS_UPDATE_NEXT_ALLOCATION(vcb
, (vcb
->nextAllocation
- numBlocks
));
589 if (free_extent_cache_active(vcb
) == 0) {
593 tempWord
= vcb
->vcbFreeExtCnt
;
594 // Add this free chunk to the free extent list
595 if (vcb
->hfs_flags
& HFS_HAS_SPARSE_DEVICE
) {
596 // Sorted by start block
597 if (tempWord
== kMaxFreeExtents
&& vcb
->vcbFreeExt
[kMaxFreeExtents
-1].startBlock
> firstBlock
)
599 if (tempWord
< kMaxFreeExtents
)
601 // We're going to add this extent. Bubble any smaller extents down in the list.
602 while (tempWord
&& vcb
->vcbFreeExt
[tempWord
-1].startBlock
> firstBlock
)
604 vcb
->vcbFreeExt
[tempWord
] = vcb
->vcbFreeExt
[tempWord
-1];
605 if (vcb
->vcbFreeExt
[tempWord
].startBlock
< vcb
->sparseAllocation
) {
606 vcb
->sparseAllocation
= vcb
->vcbFreeExt
[tempWord
].startBlock
;
610 vcb
->vcbFreeExt
[tempWord
].startBlock
= firstBlock
;
611 vcb
->vcbFreeExt
[tempWord
].blockCount
= numBlocks
;
613 if (vcb
->vcbFreeExtCnt
< kMaxFreeExtents
) {
614 ++vcb
->vcbFreeExtCnt
;
618 // Sorted by num blocks
619 if (tempWord
== kMaxFreeExtents
&& vcb
->vcbFreeExt
[kMaxFreeExtents
-1].blockCount
< numBlocks
)
621 if (tempWord
< kMaxFreeExtents
)
623 // We're going to add this extent. Bubble any smaller extents down in the list.
624 while (tempWord
&& vcb
->vcbFreeExt
[tempWord
-1].blockCount
< numBlocks
)
626 vcb
->vcbFreeExt
[tempWord
] = vcb
->vcbFreeExt
[tempWord
-1];
627 if (vcb
->vcbFreeExt
[tempWord
].startBlock
< vcb
->sparseAllocation
) {
628 vcb
->sparseAllocation
= vcb
->vcbFreeExt
[tempWord
].startBlock
;
632 vcb
->vcbFreeExt
[tempWord
].startBlock
= firstBlock
;
633 vcb
->vcbFreeExt
[tempWord
].blockCount
= numBlocks
;
635 if (vcb
->vcbFreeExtCnt
< kMaxFreeExtents
) {
636 ++vcb
->vcbFreeExtCnt
;
643 HFS_MOUNT_UNLOCK(vcb
, TRUE
);
645 sanity_check_free_ext(vcb
, 1);
647 hfs_generate_volume_notifications(VCBTOHFS(vcb
));
654 u_int8_t freebitcount
[16] = {
655 4, 3, 3, 2, 3, 2, 2, 1, /* 0 1 2 3 4 5 6 7 */
656 3, 2, 2, 1, 2, 1, 1, 0, /* 8 9 A B C D E F */
661 MetaZoneFreeBlocks(ExtendedVCB
*vcb
)
663 u_int32_t freeblocks
;
664 u_int32_t
*currCache
;
674 bytesleft
= freeblocks
= 0;
676 bit
= VCBTOHFS(vcb
)->hfs_metazone_start
;
680 lastbit
= VCBTOHFS(vcb
)->hfs_metazone_end
;
681 bytesperblock
= vcb
->vcbVBMIOSize
;
684 * Count all the bits from bit to lastbit.
686 while (bit
< lastbit
) {
688 * Get next bitmap block.
690 if (bytesleft
== 0) {
692 (void) ReleaseBitmapBlock(vcb
, blockRef
, false);
695 if (ReadBitmapBlock(vcb
, bit
, &currCache
, &blockRef
) != 0) {
698 buffer
= (u_int8_t
*)currCache
;
699 bytesleft
= bytesperblock
;
702 freeblocks
+= freebitcount
[byte
& 0x0F];
703 freeblocks
+= freebitcount
[(byte
>> 4) & 0x0F];
708 (void) ReleaseBitmapBlock(vcb
, blockRef
, false);
715 * Obtain the next allocation block (bit) that's
716 * outside the metadata allocation zone.
718 static u_int32_t
NextBitmapBlock(
722 struct hfsmount
*hfsmp
= VCBTOHFS(vcb
);
724 if ((hfsmp
->hfs_flags
& HFS_METADATA_ZONE
) == 0)
727 * Skip over metadata allocation zone.
729 if ((bit
>= hfsmp
->hfs_metazone_start
) &&
730 (bit
<= hfsmp
->hfs_metazone_end
)) {
731 bit
= hfsmp
->hfs_metazone_end
+ 1;
738 ;_______________________________________________________________________
740 ; Routine: ReadBitmapBlock
742 ; Function: Read in a bitmap block corresponding to a given allocation
743 ; block (bit). Return a pointer to the bitmap block.
746 ; vcb -- Pointer to ExtendedVCB
747 ; bit -- Allocation block whose bitmap block is desired
750 ; buffer -- Pointer to bitmap block corresonding to "block"
752 ;_______________________________________________________________________
754 static OSErr
ReadBitmapBlock(
761 struct buf
*bp
= NULL
;
762 struct vnode
*vp
= NULL
;
767 * volume bitmap blocks are protected by the allocation file lock
769 REQUIRE_FILE_LOCK(vcb
->hfs_allocation_vp
, false);
771 blockSize
= (u_int32_t
)vcb
->vcbVBMIOSize
;
772 block
= (daddr64_t
)(bit
/ (blockSize
* kBitsPerByte
));
774 if (vcb
->vcbSigWord
== kHFSPlusSigWord
) {
775 vp
= vcb
->hfs_allocation_vp
; /* use allocation file vnode */
778 vp
= VCBTOHFS(vcb
)->hfs_devvp
; /* use device I/O vnode */
779 block
+= vcb
->vcbVBMSt
; /* map to physical block */
782 err
= (int)buf_meta_bread(vp
, block
, blockSize
, NOCRED
, &bp
);
790 *blockRef
= (uintptr_t)bp
;
791 *buffer
= (u_int32_t
*)buf_dataptr(bp
);
800 ;_______________________________________________________________________
802 ; Routine: ReleaseBitmapBlock
804 ; Function: Relase a bitmap block.
810 ;_______________________________________________________________________
812 static OSErr
ReleaseBitmapBlock(
817 struct buf
*bp
= (struct buf
*)blockRef
;
821 panic("hfs: ReleaseBitmapBlock: missing bp");
828 struct hfsmount
*hfsmp
= VCBTOHFS(vcb
);
831 journal_modify_block_end(hfsmp
->jnl
, bp
, NULL
, NULL
);
845 _______________________________________________________________________
847 Routine: BlockAllocateContig
849 Function: Allocate a contiguous group of allocation blocks. The
850 allocation is all-or-nothing. The caller guarantees that
851 there are enough free blocks (though they may not be
852 contiguous, in which case this call will fail).
855 vcb Pointer to volume where space is to be allocated
856 startingBlock Preferred first block for allocation
857 minBlocks Minimum number of contiguous blocks to allocate
858 maxBlocks Maximum number of contiguous blocks to allocate
862 actualStartBlock First block of range allocated, or 0 if error
863 actualNumBlocks Number of blocks allocated, or 0 if error
864 _______________________________________________________________________
866 static OSErr
BlockAllocateContig(
868 u_int32_t startingBlock
,
872 u_int32_t
*actualStartBlock
,
873 u_int32_t
*actualNumBlocks
)
878 // Find a contiguous group of blocks at least minBlocks long.
879 // Determine the number of contiguous blocks available (up
884 * NOTE: If the only contiguous free extent of at least minBlocks
885 * crosses startingBlock (i.e. starts before, ends after), then we
886 * won't find it. Earlier versions *did* find this case by letting
887 * the second search look past startingBlock by minBlocks. But
888 * with the free extent cache, this can lead to duplicate entries
889 * in the cache, causing the same blocks to be allocated twice.
891 err
= BlockFindContiguous(vcb
, startingBlock
, vcb
->allocLimit
, minBlocks
,
892 maxBlocks
, useMetaZone
, actualStartBlock
, actualNumBlocks
);
893 if (err
== dskFulErr
&& startingBlock
!= 0) {
895 * Constrain the endingBlock so we don't bother looking for ranges
896 * that would overlap those found in the previous call.
898 err
= BlockFindContiguous(vcb
, 1, startingBlock
, minBlocks
, maxBlocks
,
899 useMetaZone
, actualStartBlock
, actualNumBlocks
);
902 // Now mark those blocks allocated.
905 err
= BlockMarkAllocated(vcb
, *actualStartBlock
, *actualNumBlocks
);
911 _______________________________________________________________________
913 Routine: BlockAllocateAny
915 Function: Allocate one or more allocation blocks. If there are fewer
916 free blocks than requested, all free blocks will be
917 allocated. The caller guarantees that there is at least
921 vcb Pointer to volume where space is to be allocated
922 startingBlock Preferred first block for allocation
923 endingBlock Last block to check + 1
924 maxBlocks Maximum number of contiguous blocks to allocate
928 actualStartBlock First block of range allocated, or 0 if error
929 actualNumBlocks Number of blocks allocated, or 0 if error
930 _______________________________________________________________________
932 static OSErr
BlockAllocateAny(
934 u_int32_t startingBlock
,
935 register u_int32_t endingBlock
,
938 u_int32_t
*actualStartBlock
,
939 u_int32_t
*actualNumBlocks
)
942 register u_int32_t block
; // current block number
943 register u_int32_t currentWord
; // Pointer to current word within bitmap block
944 register u_int32_t bitMask
; // Word with given bits already set (ready to OR in)
945 register u_int32_t wordsLeft
; // Number of words left in this bitmap block
946 u_int32_t
*buffer
= NULL
;
947 u_int32_t
*currCache
= NULL
;
949 u_int32_t bitsPerBlock
;
950 u_int32_t wordsPerBlock
;
951 Boolean dirty
= false;
952 struct hfsmount
*hfsmp
= VCBTOHFS(vcb
);
955 * When we're skipping the metadata zone and the start/end
956 * range overlaps with the metadata zone then adjust the
957 * start to be outside of the metadata zone. If the range
958 * is entirely inside the metadata zone then we can deny the
959 * request (dskFulErr).
961 if (!useMetaZone
&& (vcb
->hfs_flags
& HFS_METADATA_ZONE
)) {
962 if (startingBlock
<= vcb
->hfs_metazone_end
) {
963 if (endingBlock
> (vcb
->hfs_metazone_end
+ 2))
964 startingBlock
= vcb
->hfs_metazone_end
+ 1;
972 // Since this routine doesn't wrap around
973 if (maxBlocks
> (endingBlock
- startingBlock
)) {
974 maxBlocks
= endingBlock
- startingBlock
;
978 // Pre-read the first bitmap block
980 err
= ReadBitmapBlock(vcb
, startingBlock
, &currCache
, &blockRef
);
981 if (err
!= noErr
) goto Exit
;
985 // Set up the current position within the block
988 u_int32_t wordIndexInBlock
;
990 bitsPerBlock
= vcb
->vcbVBMIOSize
* kBitsPerByte
;
991 wordsPerBlock
= vcb
->vcbVBMIOSize
/ kBytesPerWord
;
993 wordIndexInBlock
= (startingBlock
& (bitsPerBlock
-1)) / kBitsPerWord
;
994 buffer
+= wordIndexInBlock
;
995 wordsLeft
= wordsPerBlock
- wordIndexInBlock
;
996 currentWord
= SWAP_BE32 (*buffer
);
997 bitMask
= kHighBitInWordMask
>> (startingBlock
& kBitsWithinWordMask
);
1001 // Find the first unallocated block
1003 block
=startingBlock
;
1004 while (block
< endingBlock
) {
1005 if ((currentWord
& bitMask
) == 0)
1013 bitMask
= kHighBitInWordMask
;
1016 if (--wordsLeft
== 0) {
1018 buffer
= currCache
= NULL
;
1019 err
= ReleaseBitmapBlock(vcb
, blockRef
, false);
1020 if (err
!= noErr
) goto Exit
;
1023 * Skip over metadata blocks.
1026 block
= NextBitmapBlock(vcb
, block
);
1028 if (block
>= endingBlock
) {
1033 err
= ReadBitmapBlock(vcb
, block
, &currCache
, &blockRef
);
1034 if (err
!= noErr
) goto Exit
;
1037 wordsLeft
= wordsPerBlock
;
1039 currentWord
= SWAP_BE32 (*buffer
);
1043 // Did we get to the end of the bitmap before finding a free block?
1044 // If so, then couldn't allocate anything.
1045 if (block
>= endingBlock
) {
1050 // Return the first block in the allocated range
1051 *actualStartBlock
= block
;
1054 // If we could get the desired number of blocks before hitting endingBlock,
1055 // then adjust endingBlock so we won't keep looking. Ideally, the comparison
1056 // would be (block + maxBlocks) < endingBlock, but that could overflow. The
1057 // comparison below yields identical results, but without overflow.
1058 if (block
< (endingBlock
-maxBlocks
)) {
1059 endingBlock
= block
+ maxBlocks
; // if we get this far, we've found enough
1064 journal_modify_block_start(hfsmp
->jnl
, (struct buf
*)blockRef
);
1068 // Allocate all of the consecutive blocks
1070 while ((currentWord
& bitMask
) == 0) {
1071 // Allocate this block
1072 currentWord
|= bitMask
;
1074 // Move to the next block. If no more, then exit.
1076 if (block
== endingBlock
)
1082 *buffer
= SWAP_BE32 (currentWord
); // update value in bitmap
1085 bitMask
= kHighBitInWordMask
;
1088 if (--wordsLeft
== 0) {
1090 buffer
= currCache
= NULL
;
1091 err
= ReleaseBitmapBlock(vcb
, blockRef
, true);
1092 if (err
!= noErr
) goto Exit
;
1095 * Skip over metadata blocks.
1098 u_int32_t nextBlock
;
1100 nextBlock
= NextBitmapBlock(vcb
, block
);
1101 if (nextBlock
!= block
) {
1102 goto Exit
; /* allocation gap, so stop */
1106 err
= ReadBitmapBlock(vcb
, block
, &currCache
, &blockRef
);
1107 if (err
!= noErr
) goto Exit
;
1112 journal_modify_block_start(hfsmp
->jnl
, (struct buf
*)blockRef
);
1115 wordsLeft
= wordsPerBlock
;
1118 currentWord
= SWAP_BE32 (*buffer
);
1121 *buffer
= SWAP_BE32 (currentWord
); // update the last change
1125 *actualNumBlocks
= block
- *actualStartBlock
;
1128 if ((*actualStartBlock
+ *actualNumBlocks
) > vcb
->allocLimit
) {
1129 panic("hfs: BlockAllocateAny: allocation overflow on \"%s\"", vcb
->vcbVN
);
1132 /* Remove these blocks from the TRIM list if applicable */
1133 if (CONFIG_HFS_TRIM
) {
1134 hfs_unmap_alloc_extent(vcb
, *actualStartBlock
, *actualNumBlocks
);
1138 *actualStartBlock
= 0;
1139 *actualNumBlocks
= 0;
1143 (void) ReleaseBitmapBlock(vcb
, blockRef
, dirty
);
1150 _______________________________________________________________________
1152 Routine: BlockAllocateKnown
1154 Function: Try to allocate space from known free space in the free
1158 vcb Pointer to volume where space is to be allocated
1159 maxBlocks Maximum number of contiguous blocks to allocate
1162 actualStartBlock First block of range allocated, or 0 if error
1163 actualNumBlocks Number of blocks allocated, or 0 if error
1166 dskFulErr Free extent cache is empty
1167 _______________________________________________________________________
1170 static OSErr
BlockAllocateKnown(
1172 u_int32_t maxBlocks
,
1173 u_int32_t
*actualStartBlock
,
1174 u_int32_t
*actualNumBlocks
)
1178 u_int32_t foundBlocks
;
1179 u_int32_t newStartBlock
, newBlockCount
;
1181 HFS_MOUNT_LOCK(vcb
, TRUE
);
1182 if (free_extent_cache_active(vcb
) == 0 ||
1183 vcb
->vcbFreeExtCnt
== 0 ||
1184 vcb
->vcbFreeExt
[0].blockCount
== 0) {
1185 HFS_MOUNT_UNLOCK(vcb
, TRUE
);
1188 HFS_MOUNT_UNLOCK(vcb
, TRUE
);
1190 // Just grab up to maxBlocks of the first (largest) free exent.
1191 *actualStartBlock
= vcb
->vcbFreeExt
[0].startBlock
;
1192 foundBlocks
= vcb
->vcbFreeExt
[0].blockCount
;
1193 if (foundBlocks
> maxBlocks
)
1194 foundBlocks
= maxBlocks
;
1195 *actualNumBlocks
= foundBlocks
;
1197 if (vcb
->hfs_flags
& HFS_HAS_SPARSE_DEVICE
) {
1198 // since sparse volumes keep the free extent list sorted by starting
1199 // block number, the list won't get re-ordered, it may only shrink
1201 vcb
->vcbFreeExt
[0].startBlock
+= foundBlocks
;
1202 vcb
->vcbFreeExt
[0].blockCount
-= foundBlocks
;
1203 if (vcb
->vcbFreeExt
[0].blockCount
== 0) {
1204 for(i
=1; i
< vcb
->vcbFreeExtCnt
; i
++) {
1205 vcb
->vcbFreeExt
[i
-1] = vcb
->vcbFreeExt
[i
];
1207 vcb
->vcbFreeExtCnt
--;
1213 // Adjust the start and length of that extent.
1214 newStartBlock
= vcb
->vcbFreeExt
[0].startBlock
+ foundBlocks
;
1215 newBlockCount
= vcb
->vcbFreeExt
[0].blockCount
- foundBlocks
;
1218 // The first extent might not be the largest anymore. Bubble up any
1219 // (now larger) extents to the top of the list.
1220 for (i
=1; i
<vcb
->vcbFreeExtCnt
; ++i
)
1222 if (vcb
->vcbFreeExt
[i
].blockCount
> newBlockCount
)
1224 vcb
->vcbFreeExt
[i
-1].startBlock
= vcb
->vcbFreeExt
[i
].startBlock
;
1225 vcb
->vcbFreeExt
[i
-1].blockCount
= vcb
->vcbFreeExt
[i
].blockCount
;
1233 // If this is now the smallest known free extent, then it might be smaller than
1234 // other extents we didn't keep track of. So, just forget about this extent.
1235 // After the previous loop, (i-1) is the index of the extent we just allocated from.
1236 if (newBlockCount
== 0)
1238 // then just reduce the number of free extents since this guy got deleted
1239 --vcb
->vcbFreeExtCnt
;
1243 // It's not the smallest, so store it in its proper place
1244 vcb
->vcbFreeExt
[i
-1].startBlock
= newStartBlock
;
1245 vcb
->vcbFreeExt
[i
-1].blockCount
= newBlockCount
;
1250 if ((*actualStartBlock
+ *actualNumBlocks
) > vcb
->allocLimit
)
1252 printf ("hfs: BlockAllocateKnown() found allocation overflow on \"%s\"", vcb
->vcbVN
);
1253 hfs_mark_volume_inconsistent(vcb
);
1254 *actualStartBlock
= 0;
1255 *actualNumBlocks
= 0;
1261 // Now mark the found extent in the bitmap
1263 err
= BlockMarkAllocated(vcb
, *actualStartBlock
, *actualNumBlocks
);
1266 sanity_check_free_ext(vcb
, 1);
1274 _______________________________________________________________________
1276 Routine: BlockMarkAllocated
1278 Function: Mark a contiguous group of blocks as allocated (set in the
1279 bitmap). It assumes those bits are currently marked
1280 deallocated (clear in the bitmap).
1283 vcb Pointer to volume where space is to be allocated
1284 startingBlock First block number to mark as allocated
1285 numBlocks Number of blocks to mark as allocated
1286 _______________________________________________________________________
1289 OSErr
BlockMarkAllocated(
1291 u_int32_t startingBlock
,
1292 register u_int32_t numBlocks
)
1295 register u_int32_t
*currentWord
; // Pointer to current word within bitmap block
1296 register u_int32_t wordsLeft
; // Number of words left in this bitmap block
1297 register u_int32_t bitMask
; // Word with given bits already set (ready to OR in)
1298 u_int32_t firstBit
; // Bit index within word of first bit to allocate
1299 u_int32_t numBits
; // Number of bits in word to allocate
1300 u_int32_t
*buffer
= NULL
;
1302 u_int32_t bitsPerBlock
;
1303 u_int32_t wordsPerBlock
;
1305 struct hfsmount
*hfsmp
= VCBTOHFS(vcb
);
1307 if (CONFIG_HFS_TRIM
) {
1308 hfs_unmap_alloc_extent(vcb
, startingBlock
, numBlocks
);
1312 // Pre-read the bitmap block containing the first word of allocation
1315 err
= ReadBitmapBlock(vcb
, startingBlock
, &buffer
, &blockRef
);
1316 if (err
!= noErr
) goto Exit
;
1318 // Initialize currentWord, and wordsLeft.
1321 u_int32_t wordIndexInBlock
;
1323 bitsPerBlock
= vcb
->vcbVBMIOSize
* kBitsPerByte
;
1324 wordsPerBlock
= vcb
->vcbVBMIOSize
/ kBytesPerWord
;
1326 wordIndexInBlock
= (startingBlock
& (bitsPerBlock
-1)) / kBitsPerWord
;
1327 currentWord
= buffer
+ wordIndexInBlock
;
1328 wordsLeft
= wordsPerBlock
- wordIndexInBlock
;
1333 journal_modify_block_start(hfsmp
->jnl
, (struct buf
*)blockRef
);
1337 // If the first block to allocate doesn't start on a word
1338 // boundary in the bitmap, then treat that first word
1342 firstBit
= startingBlock
% kBitsPerWord
;
1343 if (firstBit
!= 0) {
1344 bitMask
= kAllBitsSetInWord
>> firstBit
; // turn off all bits before firstBit
1345 numBits
= kBitsPerWord
- firstBit
; // number of remaining bits in this word
1346 if (numBits
> numBlocks
) {
1347 numBits
= numBlocks
; // entire allocation is inside this one word
1348 bitMask
&= ~(kAllBitsSetInWord
>> (firstBit
+ numBits
)); // turn off bits after last
1351 if ((*currentWord
& SWAP_BE32 (bitMask
)) != 0) {
1352 panic("hfs: BlockMarkAllocated: blocks already allocated!");
1355 *currentWord
|= SWAP_BE32 (bitMask
); // set the bits in the bitmap
1356 numBlocks
-= numBits
; // adjust number of blocks left to allocate
1358 ++currentWord
; // move to next word
1359 --wordsLeft
; // one less word left in this block
1363 // Allocate whole words (32 blocks) at a time.
1366 bitMask
= kAllBitsSetInWord
; // put this in a register for 68K
1367 while (numBlocks
>= kBitsPerWord
) {
1368 if (wordsLeft
== 0) {
1369 // Read in the next bitmap block
1370 startingBlock
+= bitsPerBlock
; // generate a block number in the next bitmap block
1373 err
= ReleaseBitmapBlock(vcb
, blockRef
, true);
1374 if (err
!= noErr
) goto Exit
;
1376 err
= ReadBitmapBlock(vcb
, startingBlock
, &buffer
, &blockRef
);
1377 if (err
!= noErr
) goto Exit
;
1381 journal_modify_block_start(hfsmp
->jnl
, (struct buf
*)blockRef
);
1384 // Readjust currentWord and wordsLeft
1385 currentWord
= buffer
;
1386 wordsLeft
= wordsPerBlock
;
1389 if (*currentWord
!= 0) {
1390 panic("hfs: BlockMarkAllocated: blocks already allocated!");
1393 *currentWord
= SWAP_BE32 (bitMask
);
1394 numBlocks
-= kBitsPerWord
;
1396 ++currentWord
; // move to next word
1397 --wordsLeft
; // one less word left in this block
1401 // Allocate any remaining blocks.
1404 if (numBlocks
!= 0) {
1405 bitMask
= ~(kAllBitsSetInWord
>> numBlocks
); // set first numBlocks bits
1406 if (wordsLeft
== 0) {
1407 // Read in the next bitmap block
1408 startingBlock
+= bitsPerBlock
; // generate a block number in the next bitmap block
1411 err
= ReleaseBitmapBlock(vcb
, blockRef
, true);
1412 if (err
!= noErr
) goto Exit
;
1414 err
= ReadBitmapBlock(vcb
, startingBlock
, &buffer
, &blockRef
);
1415 if (err
!= noErr
) goto Exit
;
1419 journal_modify_block_start(hfsmp
->jnl
, (struct buf
*)blockRef
);
1422 // Readjust currentWord and wordsLeft
1423 currentWord
= buffer
;
1424 wordsLeft
= wordsPerBlock
;
1427 if ((*currentWord
& SWAP_BE32 (bitMask
)) != 0) {
1428 panic("hfs: BlockMarkAllocated: blocks already allocated!");
1431 *currentWord
|= SWAP_BE32 (bitMask
); // set the bits in the bitmap
1433 // No need to update currentWord or wordsLeft
1439 (void)ReleaseBitmapBlock(vcb
, blockRef
, true);
1446 _______________________________________________________________________
1448 Routine: BlockMarkFree
1450 Function: Mark a contiguous group of blocks as free (clear in the
1451 bitmap). It assumes those bits are currently marked
1452 allocated (set in the bitmap).
1455 vcb Pointer to volume where space is to be freed
1456 startingBlock First block number to mark as freed
1457 numBlocks Number of blocks to mark as freed
1458 _______________________________________________________________________
1461 OSErr
BlockMarkFree(
1463 u_int32_t startingBlock_in
,
1464 register u_int32_t numBlocks_in
)
1467 u_int32_t startingBlock
= startingBlock_in
;
1468 u_int32_t numBlocks
= numBlocks_in
;
1469 register u_int32_t
*currentWord
; // Pointer to current word within bitmap block
1470 register u_int32_t wordsLeft
; // Number of words left in this bitmap block
1471 register u_int32_t bitMask
; // Word with given bits already set (ready to OR in)
1472 u_int32_t firstBit
; // Bit index within word of first bit to allocate
1473 u_int32_t numBits
; // Number of bits in word to allocate
1474 u_int32_t
*buffer
= NULL
;
1476 u_int32_t bitsPerBlock
;
1477 u_int32_t wordsPerBlock
;
1479 struct hfsmount
*hfsmp
= VCBTOHFS(vcb
);
1482 * NOTE: We use vcb->totalBlocks instead of vcb->allocLimit because we
1483 * need to be able to free blocks being relocated during hfs_truncatefs.
1485 if (startingBlock
+ numBlocks
> vcb
->totalBlocks
) {
1486 printf ("hfs: BlockMarkFree() trying to free non-existent blocks starting at %u (numBlock=%u) on volume %s\n", startingBlock
, numBlocks
, vcb
->vcbVN
);
1487 hfs_mark_volume_inconsistent(vcb
);
1493 // Pre-read the bitmap block containing the first word of allocation
1496 err
= ReadBitmapBlock(vcb
, startingBlock
, &buffer
, &blockRef
);
1497 if (err
!= noErr
) goto Exit
;
1500 journal_modify_block_start(hfsmp
->jnl
, (struct buf
*)blockRef
);
1504 // Initialize currentWord, and wordsLeft.
1507 u_int32_t wordIndexInBlock
;
1509 bitsPerBlock
= vcb
->vcbVBMIOSize
* kBitsPerByte
;
1510 wordsPerBlock
= vcb
->vcbVBMIOSize
/ kBytesPerWord
;
1512 wordIndexInBlock
= (startingBlock
& (bitsPerBlock
-1)) / kBitsPerWord
;
1513 currentWord
= buffer
+ wordIndexInBlock
;
1514 wordsLeft
= wordsPerBlock
- wordIndexInBlock
;
1518 // If the first block to free doesn't start on a word
1519 // boundary in the bitmap, then treat that first word
1523 firstBit
= startingBlock
% kBitsPerWord
;
1524 if (firstBit
!= 0) {
1525 bitMask
= kAllBitsSetInWord
>> firstBit
; // turn off all bits before firstBit
1526 numBits
= kBitsPerWord
- firstBit
; // number of remaining bits in this word
1527 if (numBits
> numBlocks
) {
1528 numBits
= numBlocks
; // entire allocation is inside this one word
1529 bitMask
&= ~(kAllBitsSetInWord
>> (firstBit
+ numBits
)); // turn off bits after last
1531 if ((*currentWord
& SWAP_BE32 (bitMask
)) != SWAP_BE32 (bitMask
)) {
1534 *currentWord
&= SWAP_BE32 (~bitMask
); // clear the bits in the bitmap
1535 numBlocks
-= numBits
; // adjust number of blocks left to free
1537 ++currentWord
; // move to next word
1538 --wordsLeft
; // one less word left in this block
1542 // Free whole words (32 blocks) at a time.
1545 while (numBlocks
>= kBitsPerWord
) {
1546 if (wordsLeft
== 0) {
1547 // Read in the next bitmap block
1548 startingBlock
+= bitsPerBlock
; // generate a block number in the next bitmap block
1551 err
= ReleaseBitmapBlock(vcb
, blockRef
, true);
1552 if (err
!= noErr
) goto Exit
;
1554 err
= ReadBitmapBlock(vcb
, startingBlock
, &buffer
, &blockRef
);
1555 if (err
!= noErr
) goto Exit
;
1559 journal_modify_block_start(hfsmp
->jnl
, (struct buf
*)blockRef
);
1562 // Readjust currentWord and wordsLeft
1563 currentWord
= buffer
;
1564 wordsLeft
= wordsPerBlock
;
1566 if (*currentWord
!= SWAP_BE32 (kAllBitsSetInWord
)) {
1569 *currentWord
= 0; // clear the entire word
1570 numBlocks
-= kBitsPerWord
;
1572 ++currentWord
; // move to next word
1573 --wordsLeft
; // one less word left in this block
1577 // Free any remaining blocks.
1580 if (numBlocks
!= 0) {
1581 bitMask
= ~(kAllBitsSetInWord
>> numBlocks
); // set first numBlocks bits
1582 if (wordsLeft
== 0) {
1583 // Read in the next bitmap block
1584 startingBlock
+= bitsPerBlock
; // generate a block number in the next bitmap block
1587 err
= ReleaseBitmapBlock(vcb
, blockRef
, true);
1588 if (err
!= noErr
) goto Exit
;
1590 err
= ReadBitmapBlock(vcb
, startingBlock
, &buffer
, &blockRef
);
1591 if (err
!= noErr
) goto Exit
;
1595 journal_modify_block_start(hfsmp
->jnl
, (struct buf
*)blockRef
);
1598 // Readjust currentWord and wordsLeft
1599 currentWord
= buffer
;
1600 wordsLeft
= wordsPerBlock
;
1602 if ((*currentWord
& SWAP_BE32 (bitMask
)) != SWAP_BE32 (bitMask
)) {
1605 *currentWord
&= SWAP_BE32 (~bitMask
); // clear the bits in the bitmap
1607 // No need to update currentWord or wordsLeft
1613 (void)ReleaseBitmapBlock(vcb
, blockRef
, true);
1615 if (CONFIG_HFS_TRIM
&& err
== noErr
) {
1616 hfs_unmap_free_extent(vcb
, startingBlock_in
, numBlocks_in
);
1624 panic("hfs: BlockMarkFree: blocks not allocated!");
1626 printf ("hfs: BlockMarkFree() trying to free unallocated blocks on volume %s\n", vcb
->vcbVN
);
1627 hfs_mark_volume_inconsistent(vcb
);
1635 _______________________________________________________________________
1637 Routine: BlockFindContiguous
1639 Function: Find a contiguous range of blocks that are free (bits
1640 clear in the bitmap). If a contiguous range of the
1641 minimum size can't be found, an error will be returned.
1644 vcb Pointer to volume where space is to be allocated
1645 startingBlock Preferred first block of range
1646 endingBlock Last possible block in range + 1
1647 minBlocks Minimum number of blocks needed. Must be > 0.
1648 maxBlocks Maximum (ideal) number of blocks desired
1649 useMetaZone OK to dip into metadata allocation zone
1652 actualStartBlock First block of range found, or 0 if error
1653 actualNumBlocks Number of blocks found, or 0 if error
1656 noErr Found at least minBlocks contiguous
1657 dskFulErr No contiguous space found, or all less than minBlocks
1658 _______________________________________________________________________
1661 static OSErr
BlockFindContiguous(
1663 u_int32_t startingBlock
,
1664 u_int32_t endingBlock
,
1665 u_int32_t minBlocks
,
1666 u_int32_t maxBlocks
,
1667 Boolean useMetaZone
,
1668 u_int32_t
*actualStartBlock
,
1669 u_int32_t
*actualNumBlocks
)
1672 register u_int32_t currentBlock
; // Block we're currently looking at.
1673 u_int32_t firstBlock
; // First free block in current extent.
1674 u_int32_t stopBlock
; // If we get to this block, stop searching for first free block.
1675 u_int32_t foundBlocks
; // Number of contiguous free blocks in current extent.
1676 u_int32_t
*buffer
= NULL
;
1677 register u_int32_t
*currentWord
;
1678 register u_int32_t bitMask
;
1679 register u_int32_t wordsLeft
;
1680 register u_int32_t tempWord
;
1682 u_int32_t wordsPerBlock
;
1683 u_int32_t j
, updated_free_extents
= 0, really_add
;
1686 * When we're skipping the metadata zone and the start/end
1687 * range overlaps with the metadata zone then adjust the
1688 * start to be outside of the metadata zone. If the range
1689 * is entirely inside the metadata zone then we can deny the
1690 * request (dskFulErr).
1692 if (!useMetaZone
&& (vcb
->hfs_flags
& HFS_METADATA_ZONE
)) {
1693 if (startingBlock
<= vcb
->hfs_metazone_end
) {
1694 if (endingBlock
> (vcb
->hfs_metazone_end
+ 2))
1695 startingBlock
= vcb
->hfs_metazone_end
+ 1;
1701 if ((endingBlock
- startingBlock
) < minBlocks
)
1703 // The set of blocks we're checking is smaller than the minimum number
1704 // of blocks, so we couldn't possibly find a good range.
1708 stopBlock
= endingBlock
- minBlocks
+ 1;
1709 currentBlock
= startingBlock
;
1713 * Skip over metadata blocks.
1716 currentBlock
= NextBitmapBlock(vcb
, currentBlock
);
1719 // Pre-read the first bitmap block.
1721 err
= ReadBitmapBlock(vcb
, currentBlock
, &buffer
, &blockRef
);
1722 if ( err
!= noErr
) goto ErrorExit
;
1725 // Figure out where currentBlock is within the buffer.
1727 wordsPerBlock
= vcb
->vcbVBMIOSize
/ kBytesPerWord
;
1729 wordsLeft
= (currentBlock
/ kBitsPerWord
) & (wordsPerBlock
-1); // Current index into buffer
1730 currentWord
= buffer
+ wordsLeft
;
1731 wordsLeft
= wordsPerBlock
- wordsLeft
;
1737 //============================================================
1738 // Look for a free block, skipping over allocated blocks.
1739 //============================================================
1742 // Check an initial partial word (if any)
1744 bitMask
= currentBlock
& kBitsWithinWordMask
;
1747 tempWord
= SWAP_BE32(*currentWord
); // Fetch the current word only once
1748 bitMask
= kHighBitInWordMask
>> bitMask
;
1749 while (tempWord
& bitMask
)
1755 // Did we find an unused bit (bitMask != 0), or run out of bits (bitMask == 0)?
1759 // Didn't find any unused bits, so we're done with this word.
1765 // Check whole words
1767 while (currentBlock
< stopBlock
)
1769 // See if it's time to read another block.
1773 err
= ReleaseBitmapBlock(vcb
, blockRef
, false);
1774 if (err
!= noErr
) goto ErrorExit
;
1777 * Skip over metadata blocks.
1780 currentBlock
= NextBitmapBlock(vcb
, currentBlock
);
1781 if (currentBlock
>= stopBlock
) {
1786 err
= ReadBitmapBlock(vcb
, currentBlock
, &buffer
, &blockRef
);
1787 if ( err
!= noErr
) goto ErrorExit
;
1789 currentWord
= buffer
;
1790 wordsLeft
= wordsPerBlock
;
1793 // See if any of the bits are clear
1794 if ((tempWord
= SWAP_BE32(*currentWord
)) + 1) // non-zero if any bits were clear
1796 // Figure out which bit is clear
1797 bitMask
= kHighBitInWordMask
;
1798 while (tempWord
& bitMask
)
1804 break; // Found the free bit; break out to FoundUnused.
1807 // Keep looking at the next word
1808 currentBlock
+= kBitsPerWord
;
1814 // Make sure the unused bit is early enough to use
1815 if (currentBlock
>= stopBlock
)
1820 // Remember the start of the extent
1821 firstBlock
= currentBlock
;
1823 //============================================================
1824 // Count the number of contiguous free blocks.
1825 //============================================================
1828 // Check an initial partial word (if any)
1830 bitMask
= currentBlock
& kBitsWithinWordMask
;
1833 tempWord
= SWAP_BE32(*currentWord
); // Fetch the current word only once
1834 bitMask
= kHighBitInWordMask
>> bitMask
;
1835 while (bitMask
&& !(tempWord
& bitMask
))
1841 // Did we find a used bit (bitMask != 0), or run out of bits (bitMask == 0)?
1845 // Didn't find any used bits, so we're done with this word.
1851 // Check whole words
1853 while (currentBlock
< endingBlock
)
1855 // See if it's time to read another block.
1859 err
= ReleaseBitmapBlock(vcb
, blockRef
, false);
1860 if (err
!= noErr
) goto ErrorExit
;
1863 * Skip over metadata blocks.
1866 u_int32_t nextBlock
;
1868 nextBlock
= NextBitmapBlock(vcb
, currentBlock
);
1869 if (nextBlock
!= currentBlock
) {
1870 goto LoopExit
; /* allocation gap, so stop */
1874 err
= ReadBitmapBlock(vcb
, currentBlock
, &buffer
, &blockRef
);
1875 if ( err
!= noErr
) goto ErrorExit
;
1877 currentWord
= buffer
;
1878 wordsLeft
= wordsPerBlock
;
1881 // See if any of the bits are set
1882 if ((tempWord
= SWAP_BE32(*currentWord
)) != 0)
1884 // Figure out which bit is set
1885 bitMask
= kHighBitInWordMask
;
1886 while (!(tempWord
& bitMask
))
1892 break; // Found the used bit; break out to FoundUsed.
1895 // Keep looking at the next word
1896 currentBlock
+= kBitsPerWord
;
1900 // If we found at least maxBlocks, we can quit early.
1901 if ((currentBlock
- firstBlock
) >= maxBlocks
)
1906 // Make sure we didn't run out of bitmap looking for a used block.
1907 // If so, pin to the end of the bitmap.
1908 if (currentBlock
> endingBlock
)
1909 currentBlock
= endingBlock
;
1911 // Figure out how many contiguous free blocks there were.
1912 // Pin the answer to maxBlocks.
1913 foundBlocks
= currentBlock
- firstBlock
;
1914 if (foundBlocks
> maxBlocks
)
1915 foundBlocks
= maxBlocks
;
1916 if (foundBlocks
>= minBlocks
)
1917 break; // Found what we needed!
1919 HFS_MOUNT_LOCK(vcb
, TRUE
);
1920 if (free_extent_cache_active(vcb
) == 0) {
1921 HFS_MOUNT_UNLOCK(vcb
, TRUE
);
1924 HFS_MOUNT_UNLOCK(vcb
, TRUE
);
1926 // This free chunk wasn't big enough. Try inserting it into the free extent cache in case
1927 // the allocation wasn't forced contiguous.
1929 for(j
=0; j
< vcb
->vcbFreeExtCnt
; j
++) {
1930 u_int32_t start
, end
;
1932 start
= vcb
->vcbFreeExt
[j
].startBlock
;
1933 end
= start
+ vcb
->vcbFreeExt
[j
].blockCount
;
1935 if ( (firstBlock
>= start
&& firstBlock
< end
)
1936 || ((firstBlock
+ foundBlocks
) > start
&& firstBlock
< start
)) {
1938 // there's overlap with an existing entry so do not add this
1944 if (j
>= vcb
->vcbFreeExtCnt
) {
1948 tempWord
= vcb
->vcbFreeExtCnt
;
1949 if (really_add
&& (vcb
->hfs_flags
& HFS_HAS_SPARSE_DEVICE
)) {
1950 // Sorted by starting block
1951 if (tempWord
== kMaxFreeExtents
&& vcb
->vcbFreeExt
[kMaxFreeExtents
-1].startBlock
> firstBlock
)
1953 if (tempWord
< kMaxFreeExtents
)
1955 // We're going to add this extent. Bubble any smaller extents down in the list.
1956 while (tempWord
&& vcb
->vcbFreeExt
[tempWord
-1].startBlock
> firstBlock
)
1958 vcb
->vcbFreeExt
[tempWord
] = vcb
->vcbFreeExt
[tempWord
-1];
1961 vcb
->vcbFreeExt
[tempWord
].startBlock
= firstBlock
;
1962 vcb
->vcbFreeExt
[tempWord
].blockCount
= foundBlocks
;
1964 if (vcb
->vcbFreeExtCnt
< kMaxFreeExtents
) {
1965 ++vcb
->vcbFreeExtCnt
;
1967 updated_free_extents
= 1;
1969 } else if (really_add
) {
1970 // Sorted by blockCount
1971 if (tempWord
== kMaxFreeExtents
&& vcb
->vcbFreeExt
[kMaxFreeExtents
-1].blockCount
< foundBlocks
)
1973 if (tempWord
< kMaxFreeExtents
)
1975 // We're going to add this extent. Bubble any smaller extents down in the list.
1976 while (tempWord
&& vcb
->vcbFreeExt
[tempWord
-1].blockCount
< foundBlocks
)
1978 vcb
->vcbFreeExt
[tempWord
] = vcb
->vcbFreeExt
[tempWord
-1];
1981 vcb
->vcbFreeExt
[tempWord
].startBlock
= firstBlock
;
1982 vcb
->vcbFreeExt
[tempWord
].blockCount
= foundBlocks
;
1984 if (vcb
->vcbFreeExtCnt
< kMaxFreeExtents
) {
1985 ++vcb
->vcbFreeExtCnt
;
1987 updated_free_extents
= 1;
1991 sanity_check_free_ext(vcb
, 0);
1993 } while (currentBlock
< stopBlock
);
1996 // Return the outputs.
1997 if (foundBlocks
< minBlocks
)
2002 *actualStartBlock
= 0;
2003 *actualNumBlocks
= 0;
2008 *actualStartBlock
= firstBlock
;
2009 *actualNumBlocks
= foundBlocks
;
2011 * Sanity check for overflow
2013 if ((firstBlock
+ foundBlocks
) > vcb
->allocLimit
) {
2014 panic("hfs: blk allocation overflow on \"%s\" sb:0x%08x eb:0x%08x cb:0x%08x fb:0x%08x stop:0x%08x min:0x%08x found:0x%08x",
2015 vcb
->vcbVN
, startingBlock
, endingBlock
, currentBlock
,
2016 firstBlock
, stopBlock
, minBlocks
, foundBlocks
);
2020 if (updated_free_extents
&& (vcb
->hfs_flags
& HFS_HAS_SPARSE_DEVICE
)) {
2022 u_int32_t min_start
= vcb
->totalBlocks
;
2024 // set the nextAllocation pointer to the smallest free block number
2025 // we've seen so on the next mount we won't rescan unnecessarily
2026 for(i
=0; i
< (int)vcb
->vcbFreeExtCnt
; i
++) {
2027 if (vcb
->vcbFreeExt
[i
].startBlock
< min_start
) {
2028 min_start
= vcb
->vcbFreeExt
[i
].startBlock
;
2031 if (min_start
!= vcb
->totalBlocks
) {
2032 if (min_start
< vcb
->nextAllocation
) {
2033 vcb
->nextAllocation
= min_start
;
2035 if (min_start
< vcb
->sparseAllocation
) {
2036 vcb
->sparseAllocation
= min_start
;
2042 (void) ReleaseBitmapBlock(vcb
, blockRef
, false);
2044 sanity_check_free_ext(vcb
, 1);
2050 * Test to see if any blocks in a range are allocated.
2052 * The journal or allocation file lock must be held.
2056 hfs_isallocated(struct hfsmount
*hfsmp
, u_int32_t startingBlock
, u_int32_t numBlocks
)
2058 u_int32_t
*currentWord
; // Pointer to current word within bitmap block
2059 u_int32_t wordsLeft
; // Number of words left in this bitmap block
2060 u_int32_t bitMask
; // Word with given bits already set (ready to test)
2061 u_int32_t firstBit
; // Bit index within word of first bit to allocate
2062 u_int32_t numBits
; // Number of bits in word to allocate
2063 u_int32_t
*buffer
= NULL
;
2065 u_int32_t bitsPerBlock
;
2066 u_int32_t wordsPerBlock
;
2071 * Pre-read the bitmap block containing the first word of allocation
2073 error
= ReadBitmapBlock(hfsmp
, startingBlock
, &buffer
, &blockRef
);
2078 * Initialize currentWord, and wordsLeft.
2081 u_int32_t wordIndexInBlock
;
2083 bitsPerBlock
= hfsmp
->vcbVBMIOSize
* kBitsPerByte
;
2084 wordsPerBlock
= hfsmp
->vcbVBMIOSize
/ kBytesPerWord
;
2086 wordIndexInBlock
= (startingBlock
& (bitsPerBlock
-1)) / kBitsPerWord
;
2087 currentWord
= buffer
+ wordIndexInBlock
;
2088 wordsLeft
= wordsPerBlock
- wordIndexInBlock
;
2092 * First test any non word aligned bits.
2094 firstBit
= startingBlock
% kBitsPerWord
;
2095 if (firstBit
!= 0) {
2096 bitMask
= kAllBitsSetInWord
>> firstBit
;
2097 numBits
= kBitsPerWord
- firstBit
;
2098 if (numBits
> numBlocks
) {
2099 numBits
= numBlocks
;
2100 bitMask
&= ~(kAllBitsSetInWord
>> (firstBit
+ numBits
));
2102 if ((*currentWord
& SWAP_BE32 (bitMask
)) != 0) {
2106 numBlocks
-= numBits
;
2112 * Test whole words (32 blocks) at a time.
2114 while (numBlocks
>= kBitsPerWord
) {
2115 if (wordsLeft
== 0) {
2116 /* Read in the next bitmap block. */
2117 startingBlock
+= bitsPerBlock
;
2120 error
= ReleaseBitmapBlock(hfsmp
, blockRef
, false);
2121 if (error
) goto Exit
;
2123 error
= ReadBitmapBlock(hfsmp
, startingBlock
, &buffer
, &blockRef
);
2124 if (error
) goto Exit
;
2126 /* Readjust currentWord and wordsLeft. */
2127 currentWord
= buffer
;
2128 wordsLeft
= wordsPerBlock
;
2130 if (*currentWord
!= 0) {
2134 numBlocks
-= kBitsPerWord
;
2140 * Test any remaining blocks.
2142 if (numBlocks
!= 0) {
2143 bitMask
= ~(kAllBitsSetInWord
>> numBlocks
);
2144 if (wordsLeft
== 0) {
2145 /* Read in the next bitmap block */
2146 startingBlock
+= bitsPerBlock
;
2149 error
= ReleaseBitmapBlock(hfsmp
, blockRef
, false);
2150 if (error
) goto Exit
;
2152 error
= ReadBitmapBlock(hfsmp
, startingBlock
, &buffer
, &blockRef
);
2153 if (error
) goto Exit
;
2155 currentWord
= buffer
;
2156 wordsLeft
= wordsPerBlock
;
2158 if ((*currentWord
& SWAP_BE32 (bitMask
)) != 0) {
2165 (void)ReleaseBitmapBlock(hfsmp
, blockRef
, false);
2170 /* Invalidate free extent cache for a given volume.
2171 * This cache is invalidated and disabled when a volume is being resized
2172 * (via hfs_trucatefs() or hfs_extendefs()).
2176 void invalidate_free_extent_cache(ExtendedVCB
*vcb
)
2180 HFS_MOUNT_LOCK(vcb
, TRUE
);
2181 for (i
= 0; i
< vcb
->vcbFreeExtCnt
; i
++) {
2182 vcb
->vcbFreeExt
[i
].startBlock
= 0;
2183 vcb
->vcbFreeExt
[i
].blockCount
= 0;
2185 vcb
->vcbFreeExtCnt
= 0;
2186 HFS_MOUNT_UNLOCK(vcb
, TRUE
);
2191 /* Check whether free extent cache is active or not.
2192 * This cache is invalidated and disabled when a volume is being resized
2193 * (via hfs_trucatefs() or hfs_extendefs()).
2195 * This function assumes that the caller is holding the lock on
2198 * Returns: 0 if the cache is not active,
2199 * 1 if the cache is active.
2201 static int free_extent_cache_active(ExtendedVCB
*vcb
)
2205 if (vcb
->hfs_flags
& HFS_RESIZE_IN_PROGRESS
) {