2 // lf_hfs_file_mgr_internal.h
5 // Created by Yakov Ben Zaken on 22/03/2018.
8 #ifndef lf_hfs_file_mgr_internal_h
9 #define lf_hfs_file_mgr_internal_h
13 #include "lf_hfs_defs.h"
14 #include "lf_hfs_format.h"
15 #include "lf_hfs_cnode.h"
18 /* CatalogNodeID is used to track catalog objects */
19 typedef u_int32_t HFSCatalogNodeID
;
21 /* internal error codes*/
22 #define ERR_BASE -32767
27 fxRangeErr
= ERR_BASE
+ 16, /* file position beyond mapped range*/
28 fxOvFlErr
= ERR_BASE
+ 17, /* extents file overflow*/
31 uniTooLongErr
= ERR_BASE
+ 24, /* Unicode string too long to convert to Str31*/
32 uniBufferTooSmallErr
= ERR_BASE
+ 25, /* Unicode output buffer too small*/
33 uniNotMappableErr
= ERR_BASE
+ 26, /* Unicode string can't be mapped to given script*/
35 /* BTree Manager errors*/
36 btNotFound
= ERR_BASE
+ 32, /* record not found*/
37 btExists
= ERR_BASE
+ 33, /* record already exists*/
38 btNoSpaceAvail
= ERR_BASE
+ 34, /* no available space*/
39 btNoFit
= ERR_BASE
+ 35, /* record doesn't fit in node */
40 btBadNode
= ERR_BASE
+ 36, /* bad node detected*/
41 btBadHdr
= ERR_BASE
+ 37, /* bad BTree header record detected*/
42 dsBadRotate
= ERR_BASE
+ 64, /* bad BTree rotate*/
44 /* Catalog Manager errors*/
45 cmNotFound
= ERR_BASE
+ 48, /* CNode not found*/
46 cmExists
= ERR_BASE
+ 49, /* CNode already exists*/
47 cmNotEmpty
= ERR_BASE
+ 50, /* directory CNode not empty (valence = 0)*/
48 cmRootCN
= ERR_BASE
+ 51, /* invalid reference to root CNode*/
49 cmBadNews
= ERR_BASE
+ 52, /* detected bad catalog structure*/
50 cmFThdDirErr
= ERR_BASE
+ 53, /* thread belongs to a directory not a file*/
51 cmFThdGone
= ERR_BASE
+ 54, /* file thread doesn't exist*/
52 cmParentNotFound
= ERR_BASE
+ 55, /* CNode for parent ID does not exist*/
54 /* TFS internal errors*/
55 fsDSIntErr
= -127 /* Internal file system error*/
62 kEFAllMask
= 0x01, /* allocate all requested bytes or none */
63 kEFContigMask
= 0x02, /* force contiguous allocation */
64 kEFReserveMask
= 0x04, /* keep block reserve */
65 kEFDeferMask
= 0x08, /* defer file block allocations */
66 kEFNoClumpMask
= 0x10, /* don't round up to clump size */
67 kEFMetadataMask
= 0x20, /* metadata allocation */
69 kTFTrunExtBit
= 0, /* truncate to the extent containing new PEOF*/
74 kUndefinedStrLen
= 0, /* Unknown string length */
77 /* FileIDs variables*/
78 kNumExtentsToCache
= 4 /* just guessing for ExchangeFiles*/
82 /* Universal Extent Key */
84 typedef union ExtentKey
{
86 HFSPlusExtentKey hfsPlus
;
89 /* Universal extent descriptor */
90 typedef union ExtentDescriptor
{
91 HFSExtentDescriptor hfs
;
92 HFSPlusExtentDescriptor hfsPlus
;
95 /* Universal extent record */
96 typedef union ExtentRecord
{
98 HFSPlusExtentRecord hfsPlus
;
103 CMMaxCName
= kHFSMaxFileNameChars
107 /* Universal catalog name*/
108 typedef union CatalogName
{
114 #define GetFileControlBlock(fref) VTOF((fref))
115 #define GetFileRefNumFromFCB(fcb) FTOV((fcb))
117 #define ReturnIfError(result) do { if ( (result) != noErr ) return (result); } while(0)
118 #define ExitOnError(result) do { if ( (result) != noErr ) goto ErrorExit; } while(0)
122 /* Catalog Manager Routines (IPI)*/
123 OSErr
ExchangeFileIDs( ExtendedVCB
*volume
,
124 ConstUTF8Param srcName
,
125 ConstUTF8Param destName
,
126 HFSCatalogNodeID srcID
,
127 HFSCatalogNodeID destID
,
129 u_int32_t destHint
);
131 OSErr
MoveData( ExtendedVCB
*vcb
, HFSCatalogNodeID srcID
, HFSCatalogNodeID destID
, int rsrc
);
133 /* BTree Manager Routines*/
134 typedef int32_t (*KeyCompareProcPtr
)(void *a
, void *b
);
136 OSErr
ReplaceBTreeRecord( FileReference refNum
,
141 u_int32_t
*newHint
);
144 /* Prototypes for exported routines in VolumeAllocation.c*/
147 * Flags for BlockAllocate(), BlockDeallocate() and hfs_block_alloc.
148 * Some of these are for internal use only. See the comment at the
149 * top of hfs_alloc_int for more details on the semantics of these
152 #define HFS_ALLOC_FORCECONTIG 0x001 //force contiguous block allocation; minblocks must be allocated
153 #define HFS_ALLOC_METAZONE 0x002 //can use metazone blocks
154 #define HFS_ALLOC_SKIPFREEBLKS 0x004 //skip checking/updating freeblocks during alloc/dealloc
155 #define HFS_ALLOC_FLUSHTXN 0x008 //pick best fit for allocation, even if a jnl flush is req'd
156 #define HFS_ALLOC_TENTATIVE 0x010 //reserved allocation that can be claimed back
157 #define HFS_ALLOC_LOCKED 0x020 //reserved allocation that can't be claimed back
158 #define HFS_ALLOC_IGNORE_TENTATIVE 0x040 //Steal tentative blocks if necessary
159 #define HFS_ALLOC_IGNORE_RESERVED 0x080 //Ignore tentative/committed blocks
160 #define HFS_ALLOC_USE_TENTATIVE 0x100 //Use the supplied tentative range (if possible)
161 #define HFS_ALLOC_COMMIT 0x200 //Commit the supplied extent to disk
162 #define HFS_ALLOC_TRY_HARD 0x400 //Search hard to try and get maxBlocks; implies HFS_ALLOC_FLUSHTXN
163 #define HFS_ALLOC_ROLL_BACK 0x800 //Reallocate blocks that were just deallocated
164 //#define HFS_ALLOC_FAST_DEV 0x1000 //Prefer fast device for allocation
166 typedef uint32_t hfs_block_alloc_flags_t
;
169 OSErr
BlockAllocate( ExtendedVCB
*vcb
,
170 u_int32_t startingBlock
,
173 hfs_block_alloc_flags_t flags
,
174 u_int32_t
*startBlock
,
175 u_int32_t
*actualBlocks
);
178 typedef struct hfs_alloc_extra_args
{
179 // Used with HFS_ALLOC_TRY_HARD and HFS_ALLOC_FORCECONTIG
182 // Used with with HFS_ALLOC_USE_TENTATIVE & HFS_ALLOC_COMMIT
183 struct rl_entry
**reservation_in
;
185 // Used with HFS_ALLOC_TENTATIVE & HFS_ALLOC_LOCKED
186 struct rl_entry
**reservation_out
;
189 * If the maximum cannot be returned, the allocation will be
190 * trimmed to the specified alignment after taking
191 * @alignment_offset into account. @alignment and
192 * @alignment_offset are both in terms of blocks, *not* bytes.
193 * The result will be such that:
195 * (block_count + @alignment_offset) % @alignment == 0
197 * Alignment is *not* guaranteed.
199 * One example where alignment might be useful is in the case
200 * where the page size is greater than the allocation block size
201 * and I/O is being performed in multiples of the page size.
204 int alignment_offset
;
205 } hfs_alloc_extra_args_t
;
208 * Same as BlockAllocate but slightly different API.
209 * @extent.startBlock is a hint for where to start searching and
210 * @extent.blockCount is the minimum number of blocks acceptable.
211 * Additional arguments can be passed in @extra_args and use will
212 * depend on @flags. See comment at top of hfs_block_alloc_int for
215 errno_t
hfs_block_alloc( hfsmount_t
*hfsmp
,
216 HFSPlusExtentDescriptor
*extent
,
217 hfs_block_alloc_flags_t flags
,
218 hfs_alloc_extra_args_t
*extra_args
);
220 OSErr
BlockDeallocate( ExtendedVCB
*vcb
,
221 u_int32_t firstBlock
,
223 hfs_block_alloc_flags_t flags
);
225 OSErr
BlockMarkAllocated( ExtendedVCB
*vcb
, u_int32_t startingBlock
, u_int32_t numBlocks
);
227 OSErr
BlockMarkFree( ExtendedVCB
*vcb
, u_int32_t startingBlock
, u_int32_t numBlocks
);
229 OSErr
BlockMarkFreeUnused( ExtendedVCB
*vcb
, u_int32_t startingBlock
, u_int32_t numBlocks
);
231 u_int32_t
MetaZoneFreeBlocks( ExtendedVCB
*vcb
);
233 u_int32_t
ScanUnmapBlocks( struct hfsmount
*hfsmp
);
235 int hfs_init_summary( struct hfsmount
*hfsmp
);
237 errno_t
hfs_find_free_extents( struct hfsmount
*hfsmp
, void (*callback
)(void *data
, off_t
), void *callback_arg
);
239 void hfs_free_tentative( hfsmount_t
*hfsmp
, struct rl_entry
**reservation
);
241 void hfs_free_locked( hfsmount_t
*hfsmp
, struct rl_entry
**reservation
);
243 /* Get the current time in UTC (GMT)*/
244 u_int32_t
GetTimeUTC( void );
246 u_int32_t
LocalToUTC( u_int32_t localTime
);
248 u_int32_t
UTCToLocal( u_int32_t utcTime
);
250 #endif /* lf_hfs_file_mgr_internal_h */