]>
Commit | Line | Data |
---|---|---|
de8ee011 A |
1 | // |
2 | // lf_hfs_file_mgr_internal.h | |
3 | // livefiles_hfs | |
4 | // | |
5 | // Created by Yakov Ben Zaken on 22/03/2018. | |
6 | // | |
7 | ||
8 | #ifndef lf_hfs_file_mgr_internal_h | |
9 | #define lf_hfs_file_mgr_internal_h | |
10 | ||
11 | #include <MacTypes.h> | |
12 | #include "lf_hfs.h" | |
13 | #include "lf_hfs_defs.h" | |
14 | #include "lf_hfs_format.h" | |
15 | #include "lf_hfs_cnode.h" | |
16 | ||
17 | ||
18 | /* CatalogNodeID is used to track catalog objects */ | |
19 | typedef u_int32_t HFSCatalogNodeID; | |
20 | ||
21 | /* internal error codes*/ | |
22 | #define ERR_BASE -32767 | |
23 | ||
24 | enum { | |
25 | ||
26 | /* FXM errors*/ | |
27 | fxRangeErr = ERR_BASE + 16, /* file position beyond mapped range*/ | |
28 | fxOvFlErr = ERR_BASE + 17, /* extents file overflow*/ | |
29 | ||
30 | /* Unicode errors*/ | |
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*/ | |
34 | ||
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*/ | |
43 | ||
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*/ | |
53 | ||
54 | /* TFS internal errors*/ | |
55 | fsDSIntErr = -127 /* Internal file system error*/ | |
56 | }; | |
57 | ||
58 | ||
59 | /* internal flags*/ | |
60 | ||
61 | enum { | |
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 */ | |
68 | ||
69 | kTFTrunExtBit = 0, /* truncate to the extent containing new PEOF*/ | |
70 | kTFTrunExtMask = 1 | |
71 | }; | |
72 | ||
73 | enum { | |
74 | kUndefinedStrLen = 0, /* Unknown string length */ | |
75 | kNoHint = 0, | |
76 | ||
77 | /* FileIDs variables*/ | |
78 | kNumExtentsToCache = 4 /* just guessing for ExchangeFiles*/ | |
79 | }; | |
80 | ||
81 | ||
82 | /* Universal Extent Key */ | |
83 | ||
84 | typedef union ExtentKey { | |
85 | HFSExtentKey hfs; | |
86 | HFSPlusExtentKey hfsPlus; | |
87 | } ExtentKey; | |
88 | ||
89 | /* Universal extent descriptor */ | |
90 | typedef union ExtentDescriptor { | |
91 | HFSExtentDescriptor hfs; | |
92 | HFSPlusExtentDescriptor hfsPlus; | |
93 | } ExtentDescriptor; | |
94 | ||
95 | /* Universal extent record */ | |
96 | typedef union ExtentRecord { | |
97 | HFSExtentRecord hfs; | |
98 | HFSPlusExtentRecord hfsPlus; | |
99 | } ExtentRecord; | |
100 | ||
101 | ||
102 | enum { | |
103 | CMMaxCName = kHFSMaxFileNameChars | |
104 | }; | |
105 | ||
106 | ||
107 | /* Universal catalog name*/ | |
108 | typedef union CatalogName { | |
109 | Str31 pstr; | |
110 | HFSUniStr255 ustr; | |
111 | } CatalogName; | |
112 | ||
113 | ||
114 | #define GetFileControlBlock(fref) VTOF((fref)) | |
115 | #define GetFileRefNumFromFCB(fcb) FTOV((fcb)) | |
116 | ||
117 | #define ReturnIfError(result) do { if ( (result) != noErr ) return (result); } while(0) | |
118 | #define ExitOnError(result) do { if ( (result) != noErr ) goto ErrorExit; } while(0) | |
119 | ||
120 | ||
121 | ||
122 | /* Catalog Manager Routines (IPI)*/ | |
123 | OSErr ExchangeFileIDs( ExtendedVCB *volume, | |
124 | ConstUTF8Param srcName, | |
125 | ConstUTF8Param destName, | |
126 | HFSCatalogNodeID srcID, | |
127 | HFSCatalogNodeID destID, | |
128 | u_int32_t srcHint, | |
129 | u_int32_t destHint ); | |
130 | ||
131 | OSErr MoveData( ExtendedVCB *vcb, HFSCatalogNodeID srcID, HFSCatalogNodeID destID, int rsrc); | |
132 | ||
133 | /* BTree Manager Routines*/ | |
134 | typedef int32_t (*KeyCompareProcPtr)(void *a, void *b); | |
135 | ||
136 | OSErr ReplaceBTreeRecord( FileReference refNum, | |
137 | const void *key, | |
138 | u_int32_t hint, | |
139 | void *newData, | |
140 | u_int16_t dataSize, | |
141 | u_int32_t *newHint ); | |
142 | ||
143 | ||
144 | /* Prototypes for exported routines in VolumeAllocation.c*/ | |
145 | ||
146 | /* | |
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 | |
150 | * flags. | |
151 | */ | |
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 | |
165 | ||
166 | typedef uint32_t hfs_block_alloc_flags_t; | |
167 | ||
168 | ||
169 | OSErr BlockAllocate( ExtendedVCB *vcb, | |
170 | u_int32_t startingBlock, | |
171 | u_int32_t minBlocks, | |
172 | u_int32_t maxBlocks, | |
173 | hfs_block_alloc_flags_t flags, | |
174 | u_int32_t *startBlock, | |
175 | u_int32_t *actualBlocks ); | |
176 | ||
177 | struct rl_entry; | |
178 | typedef struct hfs_alloc_extra_args { | |
179 | // Used with HFS_ALLOC_TRY_HARD and HFS_ALLOC_FORCECONTIG | |
180 | uint32_t max_blocks; | |
181 | ||
182 | // Used with with HFS_ALLOC_USE_TENTATIVE & HFS_ALLOC_COMMIT | |
183 | struct rl_entry **reservation_in; | |
184 | ||
185 | // Used with HFS_ALLOC_TENTATIVE & HFS_ALLOC_LOCKED | |
186 | struct rl_entry **reservation_out; | |
187 | ||
188 | /* | |
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: | |
194 | * | |
195 | * (block_count + @alignment_offset) % @alignment == 0 | |
196 | * | |
197 | * Alignment is *not* guaranteed. | |
198 | * | |
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. | |
202 | */ | |
203 | int alignment; | |
204 | int alignment_offset; | |
205 | } hfs_alloc_extra_args_t; | |
206 | ||
207 | /* | |
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 | |
213 | * more information. | |
214 | */ | |
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 ); | |
219 | ||
220 | OSErr BlockDeallocate( ExtendedVCB *vcb, | |
221 | u_int32_t firstBlock, | |
222 | u_int32_t numBlocks, | |
223 | hfs_block_alloc_flags_t flags ); | |
224 | ||
225 | OSErr BlockMarkAllocated( ExtendedVCB *vcb, u_int32_t startingBlock, u_int32_t numBlocks ); | |
226 | ||
227 | OSErr BlockMarkFree( ExtendedVCB *vcb, u_int32_t startingBlock, u_int32_t numBlocks ); | |
228 | ||
229 | OSErr BlockMarkFreeUnused( ExtendedVCB *vcb, u_int32_t startingBlock, u_int32_t numBlocks ); | |
230 | ||
231 | u_int32_t MetaZoneFreeBlocks( ExtendedVCB *vcb ); | |
232 | ||
233 | u_int32_t ScanUnmapBlocks( struct hfsmount *hfsmp ); | |
234 | ||
235 | int hfs_init_summary( struct hfsmount *hfsmp ); | |
236 | ||
237 | errno_t hfs_find_free_extents( struct hfsmount *hfsmp, void (*callback)(void *data, off_t), void *callback_arg ); | |
238 | ||
239 | void hfs_free_tentative( hfsmount_t *hfsmp, struct rl_entry **reservation ); | |
240 | ||
241 | void hfs_free_locked( hfsmount_t *hfsmp, struct rl_entry **reservation ); | |
242 | ||
243 | /* Get the current time in UTC (GMT)*/ | |
244 | u_int32_t GetTimeUTC( void ); | |
245 | ||
246 | u_int32_t LocalToUTC( u_int32_t localTime ); | |
247 | ||
248 | u_int32_t UTCToLocal( u_int32_t utcTime ); | |
249 | ||
250 | #endif /* lf_hfs_file_mgr_internal_h */ |