2 * Copyright (c) 2000-2015 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@
31 Contains: IPI for File Manager (HFS Plus)
35 Copyright: (c) 1996-2001 by Apple Inc., all rights reserved.
38 #ifndef __FILEMGRINTERNAL__
39 #define __FILEMGRINTERNAL__
41 #include <sys/appleapiopts.h>
44 #ifdef __APPLE_API_PRIVATE
46 #include <sys/param.h>
47 #include <sys/vnode.h>
52 #include "hfs_macos_defs.h"
53 #include "hfs_format.h"
54 #include "hfs_cnode.h"
62 /* CatalogNodeID is used to track catalog objects */
63 typedef u_int32_t HFSCatalogNodeID
;
65 /* internal error codes*/
67 #if TARGET_API_MACOS_X
68 #define ERR_BASE -32767
75 fxRangeErr
= ERR_BASE
+ 16, /* file position beyond mapped range*/
76 fxOvFlErr
= ERR_BASE
+ 17, /* extents file overflow*/
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*/
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 */
111 kEFMetadataMask
= 0x20, /* metadata allocation */
113 kTFTrunExtBit
= 0, /* truncate to the extent containing new PEOF*/
118 kUndefinedStrLen
= 0, /* Unknown string length */
121 /* FileIDs variables*/
122 kNumExtentsToCache
= 4 /* just guessing for ExchangeFiles*/
126 /* Universal Extent Key */
130 HFSPlusExtentKey hfsPlus
;
132 typedef union ExtentKey ExtentKey
;
133 /* Universal extent descriptor */
135 union ExtentDescriptor
{
136 HFSExtentDescriptor hfs
;
137 HFSPlusExtentDescriptor hfsPlus
;
139 typedef union ExtentDescriptor ExtentDescriptor
;
140 /* Universal extent record */
144 HFSPlusExtentRecord hfsPlus
;
146 typedef union ExtentRecord ExtentRecord
;
150 CMMaxCName
= kHFSMaxFileNameChars
155 /* Universal catalog name*/
161 typedef union CatalogName CatalogName
;
165 * MacOS accessor routines
167 #define GetFileControlBlock(fref) VTOF((fref))
168 #define GetFileRefNumFromFCB(fcb) FTOV((fcb))
170 /* Test for error and return if error occurred*/
172 ReturnIfError (OSErr result
);
174 #define ReturnIfError(result) do { if ( (result) != noErr ) return (result); } while(0)
176 /* Exit function on error*/
178 ExitOnError (OSErr result
);
180 #define ExitOnError( result ) do { if ( ( result ) != noErr ) goto ErrorExit; } while(0)
184 /* Catalog Manager Routines (IPI)*/
186 EXTERN_API_C( OSErr
)
187 ExchangeFileIDs (ExtendedVCB
* volume
,
188 ConstUTF8Param srcName
,
189 ConstUTF8Param destName
,
190 HFSCatalogNodeID srcID
,
191 HFSCatalogNodeID destID
,
193 u_int32_t destHint
);
195 EXTERN_API_C( OSErr
)
196 MoveData( ExtendedVCB
*vcb
, HFSCatalogNodeID srcID
, HFSCatalogNodeID destID
, int rsrc
);
198 /* BTree Manager Routines*/
200 typedef CALLBACK_API_C( int32_t , KeyCompareProcPtr
)(void *a
, void *b
);
203 EXTERN_API_C( OSErr
)
204 ReplaceBTreeRecord (FileReference refNum
,
209 u_int32_t
* newHint
);
212 /* Prototypes for exported routines in VolumeAllocation.c*/
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
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
234 typedef uint32_t hfs_block_alloc_flags_t
;
237 EXTERN_API_C( OSErr
)
238 BlockAllocate (ExtendedVCB
* vcb
,
239 u_int32_t startingBlock
,
242 hfs_block_alloc_flags_t flags
,
243 u_int32_t
* startBlock
,
244 u_int32_t
* actualBlocks
);
246 typedef struct hfs_alloc_extra_args
{
247 // Used with HFS_ALLOC_TRY_HARD and HFS_ALLOC_FORCECONTIG
250 // Used with with HFS_ALLOC_USE_TENTATIVE & HFS_ALLOC_COMMIT
251 struct rl_entry
**reservation_in
;
253 // Used with HFS_ALLOC_TENTATIVE & HFS_ALLOC_LOCKED
254 struct rl_entry
**reservation_out
;
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:
263 * (block_count + @alignment_offset) % @alignment == 0
265 * Alignment is *not* guaranteed.
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.
272 int alignment_offset
;
273 } hfs_alloc_extra_args_t
;
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
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
);
288 EXTERN_API_C( OSErr
)
289 BlockDeallocate (ExtendedVCB
* vcb
,
290 u_int32_t firstBlock
,
292 hfs_block_alloc_flags_t flags
);
294 EXTERN_API_C ( void )
295 ResetVCBFreeExtCache(struct hfsmount
*hfsmp
);
297 EXTERN_API_C( OSErr
)
298 BlockMarkAllocated(ExtendedVCB
*vcb
, u_int32_t startingBlock
, u_int32_t numBlocks
);
300 EXTERN_API_C( OSErr
)
301 BlockMarkFree( ExtendedVCB
*vcb
, u_int32_t startingBlock
, u_int32_t numBlocks
);
303 EXTERN_API_C( OSErr
)
304 BlockMarkFreeUnused( ExtendedVCB
*vcb
, u_int32_t startingBlock
, u_int32_t numBlocks
);
306 EXTERN_API_C( u_int32_t
)
307 MetaZoneFreeBlocks(ExtendedVCB
*vcb
);
309 EXTERN_API_C( u_int32_t
)
310 UpdateAllocLimit (struct hfsmount
*hfsmp
, u_int32_t new_end_block
);
312 EXTERN_API_C( u_int32_t
)
313 ScanUnmapBlocks(struct hfsmount
*hfsmp
);
316 hfs_init_summary (struct hfsmount
*hfsmp
);
318 errno_t
hfs_find_free_extents(struct hfsmount
*hfsmp
,
319 void (*callback
)(void *data
, off_t
), void *callback_arg
);
321 void hfs_free_tentative(hfsmount_t
*hfsmp
, struct rl_entry
**reservation
);
322 void hfs_free_locked(hfsmount_t
*hfsmp
, struct rl_entry
**reservation
);
324 /* File Extent Mapping routines*/
325 EXTERN_API_C( OSErr
)
326 FlushExtentFile (ExtendedVCB
* vcb
);
329 EXTERN_API_C( int32_t )
330 CompareExtentKeys (const HFSExtentKey
* searchKey
,
331 const HFSExtentKey
* trialKey
);
334 EXTERN_API_C( int32_t )
335 CompareExtentKeysPlus (const HFSPlusExtentKey
*searchKey
,
336 const HFSPlusExtentKey
*trialKey
);
338 OSErr
SearchExtentFile(ExtendedVCB
*vcb
,
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
);
347 EXTERN_API_C( OSErr
)
348 TruncateFileC (ExtendedVCB
*vcb
, FCB
*fcb
, int64_t peof
, int deleted
,
349 int rsrc
, uint32_t fileid
, Boolean truncateToExtent
);
351 EXTERN_API_C( OSErr
)
352 ExtendFileC (ExtendedVCB
* vcb
,
357 int64_t * actualBytesAdded
);
359 EXTERN_API_C( OSErr
)
360 MapFileBlockC (ExtendedVCB
* vcb
,
362 size_t numberOfBytes
,
364 daddr64_t
* startBlock
,
365 size_t * availableBytes
);
367 OSErr
HeadTruncateFile(ExtendedVCB
*vcb
, FCB
*fcb
, u_int32_t headblks
);
370 AddFileExtent (ExtendedVCB
*vcb
, FCB
*fcb
, u_int32_t startBlock
, u_int32_t blockCount
);
372 #if TARGET_API_MACOS_X
373 EXTERN_API_C( Boolean
)
374 NodesAreContiguous (ExtendedVCB
* vcb
,
379 /* Get the current time in UTC (GMT)*/
380 EXTERN_API_C( u_int32_t
)
383 EXTERN_API_C( u_int32_t
)
384 LocalToUTC (u_int32_t localTime
);
386 EXTERN_API_C( u_int32_t
)
387 UTCToLocal (u_int32_t utcTime
);
394 #endif /* __APPLE_API_PRIVATE */
396 #endif /* __FILEMGRINTERNAL__ */