]>
Commit | Line | Data |
---|---|---|
1c79356b | 1 | /* |
3e170ce0 | 2 | * Copyright (c) 2000-2014 Apple Inc. All rights reserved. |
5d5c5d0d | 3 | * |
2d21ac55 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
1c79356b | 5 | * |
2d21ac55 A |
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. | |
8f6c56a5 | 14 | * |
2d21ac55 A |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
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 | |
8f6c56a5 A |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2d21ac55 A |
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. | |
8f6c56a5 | 25 | * |
2d21ac55 | 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
1c79356b A |
27 | */ |
28 | /* | |
29 | File: FilesInternal.h | |
30 | ||
31 | Contains: IPI for File Manager (HFS Plus) | |
32 | ||
33 | Version: HFS Plus 1.0 | |
34 | ||
6d2010ae | 35 | Copyright: � 1996-2001 by Apple Computer, Inc., all rights reserved. |
1c79356b A |
36 | |
37 | */ | |
38 | #ifndef __FILEMGRINTERNAL__ | |
39 | #define __FILEMGRINTERNAL__ | |
40 | ||
9bccf70c A |
41 | #include <sys/appleapiopts.h> |
42 | ||
43 | #ifdef KERNEL | |
44 | #ifdef __APPLE_API_PRIVATE | |
45 | ||
1c79356b A |
46 | #include <sys/param.h> |
47 | #include <sys/vnode.h> | |
48 | ||
04b8595b A |
49 | #if !HFS_ALLOC_TEST |
50 | ||
1c79356b A |
51 | #include "../../hfs.h" |
52 | #include "../../hfs_macos_defs.h" | |
53 | #include "../../hfs_format.h" | |
9bccf70c | 54 | #include "../../hfs_cnode.h" |
1c79356b | 55 | |
04b8595b | 56 | #endif |
1c79356b | 57 | |
1c79356b A |
58 | #ifdef __cplusplus |
59 | extern "C" { | |
60 | #endif | |
61 | ||
1c79356b | 62 | /* CatalogNodeID is used to track catalog objects */ |
2d21ac55 | 63 | typedef u_int32_t HFSCatalogNodeID; |
1c79356b A |
64 | |
65 | /* internal error codes*/ | |
66 | ||
67 | #if TARGET_API_MACOS_X | |
68 | #define ERR_BASE -32767 | |
69 | #else | |
70 | #define ERR_BASE 0 | |
71 | #endif | |
72 | ||
73 | enum { | |
74 | /* FXM errors*/ | |
75 | fxRangeErr = ERR_BASE + 16, /* file position beyond mapped range*/ | |
76 | fxOvFlErr = ERR_BASE + 17, /* extents file overflow*/ | |
77 | /* Unicode errors*/ | |
78 | uniTooLongErr = ERR_BASE + 24, /* Unicode string too long to convert to Str31*/ | |
79 | uniBufferTooSmallErr = ERR_BASE + 25, /* Unicode output buffer too small*/ | |
80 | uniNotMappableErr = ERR_BASE + 26, /* Unicode string can't be mapped to given script*/ | |
81 | /* BTree Manager errors*/ | |
82 | btNotFound = ERR_BASE + 32, /* record not found*/ | |
83 | btExists = ERR_BASE + 33, /* record already exists*/ | |
84 | btNoSpaceAvail = ERR_BASE + 34, /* no available space*/ | |
85 | btNoFit = ERR_BASE + 35, /* record doesn't fit in node */ | |
86 | btBadNode = ERR_BASE + 36, /* bad node detected*/ | |
87 | btBadHdr = ERR_BASE + 37, /* bad BTree header record detected*/ | |
88 | dsBadRotate = ERR_BASE + 64, /* bad BTree rotate*/ | |
89 | /* Catalog Manager errors*/ | |
90 | cmNotFound = ERR_BASE + 48, /* CNode not found*/ | |
91 | cmExists = ERR_BASE + 49, /* CNode already exists*/ | |
92 | cmNotEmpty = ERR_BASE + 50, /* directory CNode not empty (valence = 0)*/ | |
93 | cmRootCN = ERR_BASE + 51, /* invalid reference to root CNode*/ | |
94 | cmBadNews = ERR_BASE + 52, /* detected bad catalog structure*/ | |
95 | cmFThdDirErr = ERR_BASE + 53, /* thread belongs to a directory not a file*/ | |
96 | cmFThdGone = ERR_BASE + 54, /* file thread doesn't exist*/ | |
97 | cmParentNotFound = ERR_BASE + 55, /* CNode for parent ID does not exist*/ | |
98 | /* TFS internal errors*/ | |
99 | fsDSIntErr = -127 /* Internal file system error*/ | |
100 | }; | |
101 | ||
102 | ||
103 | /* internal flags*/ | |
104 | ||
1c79356b | 105 | enum { |
9bccf70c A |
106 | kEFAllMask = 0x01, /* allocate all requested bytes or none */ |
107 | kEFContigMask = 0x02, /* force contiguous allocation */ | |
108 | kEFReserveMask = 0x04, /* keep block reserve */ | |
109 | kEFDeferMask = 0x08, /* defer file block allocations */ | |
110 | kEFNoClumpMask = 0x10, /* don't round up to clump size */ | |
55e303ae | 111 | kEFMetadataMask = 0x20, /* metadata allocation */ |
9bccf70c | 112 | |
1c79356b A |
113 | kTFTrunExtBit = 0, /* truncate to the extent containing new PEOF*/ |
114 | kTFTrunExtMask = 1 | |
115 | }; | |
116 | ||
117 | enum { | |
0b4e3aa0 A |
118 | kUndefinedStrLen = 0, /* Unknown string length */ |
119 | kNoHint = 0, | |
1c79356b | 120 | |
1c79356b A |
121 | /* FileIDs variables*/ |
122 | kNumExtentsToCache = 4 /* just guessing for ExchangeFiles*/ | |
123 | }; | |
124 | ||
125 | ||
1c79356b A |
126 | /* Universal Extent Key */ |
127 | ||
128 | union ExtentKey { | |
129 | HFSExtentKey hfs; | |
130 | HFSPlusExtentKey hfsPlus; | |
131 | }; | |
132 | typedef union ExtentKey ExtentKey; | |
133 | /* Universal extent descriptor */ | |
134 | ||
135 | union ExtentDescriptor { | |
136 | HFSExtentDescriptor hfs; | |
137 | HFSPlusExtentDescriptor hfsPlus; | |
138 | }; | |
139 | typedef union ExtentDescriptor ExtentDescriptor; | |
140 | /* Universal extent record */ | |
141 | ||
142 | union ExtentRecord { | |
143 | HFSExtentRecord hfs; | |
144 | HFSPlusExtentRecord hfsPlus; | |
145 | }; | |
146 | typedef union ExtentRecord ExtentRecord; | |
1c79356b A |
147 | |
148 | ||
149 | enum { | |
150 | CMMaxCName = kHFSMaxFileNameChars | |
151 | }; | |
152 | ||
153 | ||
1c79356b | 154 | |
1c79356b A |
155 | /* Universal catalog name*/ |
156 | ||
157 | union CatalogName { | |
158 | Str31 pstr; | |
159 | HFSUniStr255 ustr; | |
160 | }; | |
161 | typedef union CatalogName CatalogName; | |
162 | ||
1c79356b A |
163 | |
164 | /* | |
165 | * MacOS accessor routines | |
166 | */ | |
9bccf70c A |
167 | #define GetFileControlBlock(fref) VTOF((fref)) |
168 | #define GetFileRefNumFromFCB(fcb) FTOV((fcb)) | |
1c79356b | 169 | |
1c79356b A |
170 | /* Test for error and return if error occurred*/ |
171 | EXTERN_API_C( void ) | |
172 | ReturnIfError (OSErr result); | |
173 | ||
2d21ac55 | 174 | #define ReturnIfError(result) do { if ( (result) != noErr ) return (result); } while(0) |
1c79356b | 175 | |
1c79356b A |
176 | /* Exit function on error*/ |
177 | EXTERN_API_C( void ) | |
178 | ExitOnError (OSErr result); | |
179 | ||
2d21ac55 | 180 | #define ExitOnError( result ) do { if ( ( result ) != noErr ) goto ErrorExit; } while(0) |
1c79356b | 181 | |
1c79356b A |
182 | |
183 | ||
184 | /* Catalog Manager Routines (IPI)*/ | |
185 | ||
1c79356b A |
186 | EXTERN_API_C( OSErr ) |
187 | ExchangeFileIDs (ExtendedVCB * volume, | |
188 | ConstUTF8Param srcName, | |
189 | ConstUTF8Param destName, | |
190 | HFSCatalogNodeID srcID, | |
191 | HFSCatalogNodeID destID, | |
2d21ac55 A |
192 | u_int32_t srcHint, |
193 | u_int32_t destHint ); | |
1c79356b | 194 | |
6d2010ae A |
195 | EXTERN_API_C( OSErr ) |
196 | MoveData( ExtendedVCB *vcb, HFSCatalogNodeID srcID, HFSCatalogNodeID destID, int rsrc); | |
1c79356b A |
197 | |
198 | /* BTree Manager Routines*/ | |
199 | ||
2d21ac55 | 200 | typedef CALLBACK_API_C( int32_t , KeyCompareProcPtr )(void *a, void *b); |
1c79356b A |
201 | |
202 | ||
1c79356b A |
203 | EXTERN_API_C( OSErr ) |
204 | ReplaceBTreeRecord (FileReference refNum, | |
205 | const void * key, | |
2d21ac55 | 206 | u_int32_t hint, |
1c79356b | 207 | void * newData, |
2d21ac55 A |
208 | u_int16_t dataSize, |
209 | u_int32_t * newHint); | |
1c79356b | 210 | |
1c79356b | 211 | |
1c79356b | 212 | /* Prototypes for exported routines in VolumeAllocation.c*/ |
0b4c1975 A |
213 | |
214 | /* | |
3e170ce0 A |
215 | * Flags for BlockAllocate(), BlockDeallocate() and hfs_block_alloc. |
216 | * Some of these are for internal use only. See the comment at the | |
217 | * top of hfs_alloc_int for more details on the semantics of these | |
218 | * flags. | |
0b4c1975 | 219 | */ |
3e170ce0 A |
220 | #define HFS_ALLOC_FORCECONTIG 0x001 //force contiguous block allocation; minblocks must be allocated |
221 | #define HFS_ALLOC_METAZONE 0x002 //can use metazone blocks | |
222 | #define HFS_ALLOC_SKIPFREEBLKS 0x004 //skip checking/updating freeblocks during alloc/dealloc | |
223 | #define HFS_ALLOC_FLUSHTXN 0x008 //pick best fit for allocation, even if a jnl flush is req'd | |
224 | #define HFS_ALLOC_TENTATIVE 0x010 //reserved allocation that can be claimed back | |
225 | #define HFS_ALLOC_LOCKED 0x020 //reserved allocation that can't be claimed back | |
226 | #define HFS_ALLOC_IGNORE_TENTATIVE 0x040 //Steal tentative blocks if necessary | |
227 | #define HFS_ALLOC_IGNORE_RESERVED 0x080 //Ignore tentative/committed blocks | |
228 | #define HFS_ALLOC_USE_TENTATIVE 0x100 //Use the supplied tentative range (if possible) | |
229 | #define HFS_ALLOC_COMMIT 0x200 //Commit the supplied extent to disk | |
230 | #define HFS_ALLOC_TRY_HARD 0x400 //Search hard to try and get maxBlocks; implies HFS_ALLOC_FLUSHTXN | |
231 | #define HFS_ALLOC_ROLL_BACK 0x800 //Reallocate blocks that were just deallocated | |
232 | #define HFS_ALLOC_FAST_DEV 0x1000 //Prefer fast device for allocation | |
233 | ||
234 | typedef uint32_t hfs_block_alloc_flags_t; | |
235 | ||
236 | struct rl_entry; | |
1c79356b | 237 | EXTERN_API_C( OSErr ) |
3e170ce0 A |
238 | BlockAllocate (ExtendedVCB * vcb, |
239 | u_int32_t startingBlock, | |
240 | u_int32_t minBlocks, | |
241 | u_int32_t maxBlocks, | |
242 | hfs_block_alloc_flags_t flags, | |
243 | u_int32_t * startBlock, | |
244 | u_int32_t * actualBlocks); | |
245 | ||
246 | typedef struct hfs_alloc_extra_args { | |
247 | // Used with HFS_ALLOC_TRY_HARD and HFS_ALLOC_FORCECONTIG | |
248 | uint32_t max_blocks; | |
249 | ||
250 | // Used with with HFS_ALLOC_USE_TENTATIVE & HFS_ALLOC_COMMIT | |
251 | struct rl_entry **reservation_in; | |
252 | ||
253 | // Used with HFS_ALLOC_TENTATIVE & HFS_ALLOC_LOCKED | |
254 | struct rl_entry **reservation_out; | |
255 | ||
256 | /* | |
257 | * If the maximum cannot be returned, the allocation will be | |
258 | * trimmed to the specified alignment after taking | |
259 | * @alignment_offset into account. @alignment and | |
260 | * @alignment_offset are both in terms of blocks, *not* bytes. | |
261 | * The result will be such that: | |
262 | * | |
263 | * (block_count + @alignment_offset) % @alignment == 0 | |
264 | * | |
265 | * Alignment is *not* guaranteed. | |
266 | * | |
267 | * One example where alignment might be useful is in the case | |
268 | * where the page size is greater than the allocation block size | |
269 | * and I/O is being performed in multiples of the page size. | |
270 | */ | |
271 | int alignment; | |
272 | int alignment_offset; | |
273 | } hfs_alloc_extra_args_t; | |
274 | ||
275 | /* | |
276 | * Same as BlockAllocate but slightly different API. | |
277 | * @extent.startBlock is a hint for where to start searching and | |
278 | * @extent.blockCount is the minimum number of blocks acceptable. | |
279 | * Additional arguments can be passed in @extra_args and use will | |
280 | * depend on @flags. See comment at top of hfs_block_alloc_int for | |
281 | * more information. | |
282 | */ | |
283 | errno_t hfs_block_alloc(hfsmount_t *hfsmp, | |
284 | HFSPlusExtentDescriptor *extent, | |
285 | hfs_block_alloc_flags_t flags, | |
286 | hfs_alloc_extra_args_t *extra_args); | |
1c79356b A |
287 | |
288 | EXTERN_API_C( OSErr ) | |
3e170ce0 A |
289 | BlockDeallocate (ExtendedVCB * vcb, |
290 | u_int32_t firstBlock, | |
291 | u_int32_t numBlocks, | |
292 | hfs_block_alloc_flags_t flags); | |
1c79356b | 293 | |
d1ecb069 | 294 | EXTERN_API_C ( void ) |
6d2010ae | 295 | ResetVCBFreeExtCache(struct hfsmount *hfsmp); |
d1ecb069 | 296 | |
55e303ae | 297 | EXTERN_API_C( OSErr ) |
2d21ac55 | 298 | BlockMarkAllocated(ExtendedVCB *vcb, u_int32_t startingBlock, u_int32_t numBlocks); |
55e303ae A |
299 | |
300 | EXTERN_API_C( OSErr ) | |
2d21ac55 | 301 | BlockMarkFree( ExtendedVCB *vcb, u_int32_t startingBlock, u_int32_t numBlocks); |
55e303ae | 302 | |
6d2010ae A |
303 | EXTERN_API_C( OSErr ) |
304 | BlockMarkFreeUnused( ExtendedVCB *vcb, u_int32_t startingBlock, u_int32_t numBlocks); | |
305 | ||
2d21ac55 | 306 | EXTERN_API_C( u_int32_t ) |
55e303ae | 307 | MetaZoneFreeBlocks(ExtendedVCB *vcb); |
6d2010ae A |
308 | |
309 | EXTERN_API_C( u_int32_t ) | |
310 | UpdateAllocLimit (struct hfsmount *hfsmp, u_int32_t new_end_block); | |
316670eb A |
311 | |
312 | EXTERN_API_C( u_int32_t ) | |
39236c6e | 313 | ScanUnmapBlocks(struct hfsmount *hfsmp); |
316670eb | 314 | |
39236c6e A |
315 | EXTERN_API_C( int ) |
316 | hfs_init_summary (struct hfsmount *hfsmp); | |
55e303ae | 317 | |
04b8595b A |
318 | errno_t hfs_find_free_extents(struct hfsmount *hfsmp, |
319 | void (*callback)(void *data, off_t), void *callback_arg); | |
320 | ||
3e170ce0 A |
321 | void hfs_free_tentative(hfsmount_t *hfsmp, struct rl_entry **reservation); |
322 | void hfs_free_locked(hfsmount_t *hfsmp, struct rl_entry **reservation); | |
323 | ||
1c79356b A |
324 | /* File Extent Mapping routines*/ |
325 | EXTERN_API_C( OSErr ) | |
326 | FlushExtentFile (ExtendedVCB * vcb); | |
327 | ||
39236c6e | 328 | #if CONFIG_HFS_STD |
2d21ac55 | 329 | EXTERN_API_C( int32_t ) |
1c79356b A |
330 | CompareExtentKeys (const HFSExtentKey * searchKey, |
331 | const HFSExtentKey * trialKey); | |
39236c6e | 332 | #endif |
1c79356b | 333 | |
2d21ac55 | 334 | EXTERN_API_C( int32_t ) |
1c79356b A |
335 | CompareExtentKeysPlus (const HFSPlusExtentKey *searchKey, |
336 | const HFSPlusExtentKey *trialKey); | |
337 | ||
3e170ce0 A |
338 | OSErr SearchExtentFile(ExtendedVCB *vcb, |
339 | const FCB *fcb, | |
340 | int64_t filePosition, | |
341 | HFSPlusExtentKey *foundExtentKey, | |
342 | HFSPlusExtentRecord foundExtentData, | |
343 | u_int32_t *foundExtentDataIndex, | |
344 | u_int32_t *extentBTreeHint, | |
345 | u_int32_t *endingFABNPlusOne ); | |
346 | ||
1c79356b | 347 | EXTERN_API_C( OSErr ) |
6d2010ae A |
348 | TruncateFileC (ExtendedVCB *vcb, FCB *fcb, int64_t peof, int deleted, |
349 | int rsrc, uint32_t fileid, Boolean truncateToExtent); | |
350 | ||
1c79356b A |
351 | EXTERN_API_C( OSErr ) |
352 | ExtendFileC (ExtendedVCB * vcb, | |
353 | FCB * fcb, | |
2d21ac55 A |
354 | int64_t bytesToAdd, |
355 | u_int32_t blockHint, | |
356 | u_int32_t flags, | |
357 | int64_t * actualBytesAdded); | |
1c79356b A |
358 | |
359 | EXTERN_API_C( OSErr ) | |
360 | MapFileBlockC (ExtendedVCB * vcb, | |
361 | FCB * fcb, | |
362 | size_t numberOfBytes, | |
363 | off_t offset, | |
91447636 | 364 | daddr64_t * startBlock, |
1c79356b A |
365 | size_t * availableBytes); |
366 | ||
2d21ac55 | 367 | OSErr HeadTruncateFile(ExtendedVCB *vcb, FCB *fcb, u_int32_t headblks); |
91447636 | 368 | |
55e303ae | 369 | EXTERN_API_C( int ) |
2d21ac55 | 370 | AddFileExtent (ExtendedVCB *vcb, FCB *fcb, u_int32_t startBlock, u_int32_t blockCount); |
55e303ae | 371 | |
1c79356b A |
372 | #if TARGET_API_MACOS_X |
373 | EXTERN_API_C( Boolean ) | |
374 | NodesAreContiguous (ExtendedVCB * vcb, | |
375 | FCB * fcb, | |
2d21ac55 | 376 | u_int32_t nodeSize); |
1c79356b | 377 | #endif |
1c79356b | 378 | |
1c79356b | 379 | /* Get the current time in UTC (GMT)*/ |
2d21ac55 | 380 | EXTERN_API_C( u_int32_t ) |
1c79356b A |
381 | GetTimeUTC (void); |
382 | ||
2d21ac55 A |
383 | EXTERN_API_C( u_int32_t ) |
384 | LocalToUTC (u_int32_t localTime); | |
1c79356b | 385 | |
2d21ac55 A |
386 | EXTERN_API_C( u_int32_t ) |
387 | UTCToLocal (u_int32_t utcTime); | |
1c79356b A |
388 | |
389 | ||
1c79356b A |
390 | #ifdef __cplusplus |
391 | } | |
392 | #endif | |
393 | ||
9bccf70c A |
394 | #endif /* __APPLE_API_PRIVATE */ |
395 | #endif /* KERNEL */ | |
1c79356b A |
396 | #endif /* __FILEMGRINTERNAL__ */ |
397 |