2 * Copyright (c) 2000-2001 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
25 Contains: IPI for File Manager (HFS Plus)
29 Copyright: © 1996-2001 by Apple Computer, Inc., all rights reserved.
32 #ifndef __FILEMGRINTERNAL__
33 #define __FILEMGRINTERNAL__
35 #include <sys/param.h>
36 #include <sys/vnode.h>
38 #include "../../hfs.h"
39 #include "../../hfs_macos_defs.h"
40 #include "../../hfs_format.h"
55 #if PRAGMA_STRUCT_ALIGN
56 #pragma options align=mac68k
57 #elif PRAGMA_STRUCT_PACKPUSH
59 #elif PRAGMA_STRUCT_PACK
63 /* CatalogNodeID is used to track catalog objects */
64 typedef UInt32 HFSCatalogNodeID
;
66 /* internal error codes*/
68 #if TARGET_API_MACOS_X
69 #define ERR_BASE -32767
76 fxRangeErr
= ERR_BASE
+ 16, /* file position beyond mapped range*/
77 fxOvFlErr
= ERR_BASE
+ 17, /* extents file overflow*/
79 uniTooLongErr
= ERR_BASE
+ 24, /* Unicode string too long to convert to Str31*/
80 uniBufferTooSmallErr
= ERR_BASE
+ 25, /* Unicode output buffer too small*/
81 uniNotMappableErr
= ERR_BASE
+ 26, /* Unicode string can't be mapped to given script*/
82 /* BTree Manager errors*/
83 btNotFound
= ERR_BASE
+ 32, /* record not found*/
84 btExists
= ERR_BASE
+ 33, /* record already exists*/
85 btNoSpaceAvail
= ERR_BASE
+ 34, /* no available space*/
86 btNoFit
= ERR_BASE
+ 35, /* record doesn't fit in node */
87 btBadNode
= ERR_BASE
+ 36, /* bad node detected*/
88 btBadHdr
= ERR_BASE
+ 37, /* bad BTree header record detected*/
89 dsBadRotate
= ERR_BASE
+ 64, /* bad BTree rotate*/
90 /* Catalog Manager errors*/
91 cmNotFound
= ERR_BASE
+ 48, /* CNode not found*/
92 cmExists
= ERR_BASE
+ 49, /* CNode already exists*/
93 cmNotEmpty
= ERR_BASE
+ 50, /* directory CNode not empty (valence = 0)*/
94 cmRootCN
= ERR_BASE
+ 51, /* invalid reference to root CNode*/
95 cmBadNews
= ERR_BASE
+ 52, /* detected bad catalog structure*/
96 cmFThdDirErr
= ERR_BASE
+ 53, /* thread belongs to a directory not a file*/
97 cmFThdGone
= ERR_BASE
+ 54, /* file thread doesn't exist*/
98 cmParentNotFound
= ERR_BASE
+ 55, /* CNode for parent ID does not exist*/
99 /* TFS internal errors*/
100 fsDSIntErr
= -127 /* Internal file system error*/
107 kEFContigBit
= 1, /* force contiguous allocation*/
108 kEFContigMask
= 0x02,
109 kEFAllBit
= 0, /* allocate all requested bytes or none*/
110 kEFAllMask
= 0x01, /* TruncateFile option flags*/
111 kTFTrunExtBit
= 0, /* truncate to the extent containing new PEOF*/
116 kUndefinedStrLen
= 0, /* Unknown string length */
119 /* FileIDs variables*/
120 kNumExtentsToCache
= 4 /* just guessing for ExchangeFiles*/
125 kInvalidMRUCacheKey
= -1L, /* flag to denote current MRU cache key is invalid*/
126 kDefaultNumMRUCacheBlocks
= 16 /* default number of blocks in each cache*/
130 /* Universal Extent Key */
134 HFSPlusExtentKey hfsPlus
;
136 typedef union ExtentKey ExtentKey
;
137 /* Universal extent descriptor */
139 union ExtentDescriptor
{
140 HFSExtentDescriptor hfs
;
141 HFSPlusExtentDescriptor hfsPlus
;
143 typedef union ExtentDescriptor ExtentDescriptor
;
144 /* Universal extent record */
148 HFSPlusExtentRecord hfsPlus
;
150 typedef union ExtentRecord ExtentRecord
;
151 /* Universal catalog key */
155 HFSPlusCatalogKey hfsPlus
;
157 typedef union CatalogKey CatalogKey
;
158 /* Universal catalog data record */
160 union CatalogRecord
{
162 HFSCatalogFolder hfsFolder
;
163 HFSCatalogFile hfsFile
;
164 HFSCatalogThread hfsThread
;
165 HFSPlusCatalogFolder hfsPlusFolder
;
166 HFSPlusCatalogFile hfsPlusFile
;
167 HFSPlusCatalogThread hfsPlusThread
;
169 typedef union CatalogRecord CatalogRecord
;
173 CMMaxCName
= kHFSMaxFileNameChars
178 vcbMaxNam
= 27, /* volumes currently have a 27 byte max name length*/
180 vcbManualEjectMask
= 0x0001, /* bit 0 manual-eject bit: set if volume is in a manual-eject drive*/
181 vcbFlushCriticalInfoMask
= 0x0002, /* bit 1 critical info bit: set if critical MDB information needs to flush*/
182 /* IoParam->ioVAtrb*/
183 kDefaultVolumeMask
= 0x0020,
184 kFilesOpenMask
= 0x0040
188 /* Universal catalog name*/
194 typedef union CatalogName CatalogName
;
198 * MacOS accessor routines
200 #define GetFileControlBlock(fref) ((FCB *)((fref)->v_data))
201 #define GetFileRefNumFromFCB(filePtr) ((filePtr)->h_vp)
204 /* The following macro marks a VCB as dirty by setting the upper 8 bits of the flags*/
206 MarkVCBDirty (ExtendedVCB
*vcb
);
209 MarkVCBClean (ExtendedVCB
*vcb
);
211 EXTERN_API_C( Boolean
)
212 IsVCBDirty (ExtendedVCB
*vcb
);
215 #define VCB_LOCK_INIT(vcb) simple_lock_init(&vcb->vcbSimpleLock)
216 #define VCB_LOCK(vcb) simple_lock(&vcb->vcbSimpleLock)
217 #define VCB_UNLOCK(vcb) simple_unlock(&vcb->vcbSimpleLock)
219 #define MarkVCBDirty(vcb) { VCB_LOCK((vcb)); ((vcb)->vcbFlags |= 0xFF00); VCB_UNLOCK((vcb)); }
220 #define MarkVCBClean(vcb) { VCB_LOCK((vcb)); ((vcb)->vcbFlags &= 0x00FF); VCB_UNLOCK((vcb)); }
221 #define IsVCBDirty(vcb) ((Boolean) ((vcb->vcbFlags & 0xFF00) != 0))
224 /* Test for error and return if error occurred*/
226 ReturnIfError (OSErr result
);
228 #define ReturnIfError(result) if ( (result) != noErr ) return (result); else ;
229 /* Test for passed condition and return if true*/
231 ReturnErrorIf (Boolean condition
,
234 #define ReturnErrorIf(condition, error) if ( (condition) ) return( (error) );
235 /* Exit function on error*/
237 ExitOnError (OSErr result
);
239 #define ExitOnError( result ) if ( ( result ) != noErr ) goto ErrorExit; else ;
243 /* Catalog Manager Routines (IPI)*/
245 EXTERN_API_C( OSErr
)
246 CreateCatalogNode (ExtendedVCB
* volume
,
247 HFSCatalogNodeID parentID
,
250 HFSCatalogNodeID
* catalogNodeID
,
251 UInt32
* catalogHint
,
254 EXTERN_API_C( OSErr
)
255 DeleteCatalogNode (ExtendedVCB
* volume
,
256 HFSCatalogNodeID parentID
,
260 EXTERN_API_C( OSErr
)
261 GetCatalogNode (ExtendedVCB
* volume
,
262 HFSCatalogNodeID parentID
,
266 CatalogNodeData
* nodeData
,
269 EXTERN_API_C( OSErr
)
270 GetCatalogOffspring (ExtendedVCB
* volume
,
271 HFSCatalogNodeID folderID
,
273 CatalogNodeData
* nodeData
,
274 HFSCatalogNodeID
* nodeID
,
277 EXTERN_API_C( OSErr
)
278 MoveRenameCatalogNode (ExtendedVCB
* volume
,
279 HFSCatalogNodeID srcParentID
,
280 ConstUTF8Param srcName
,
282 HFSCatalogNodeID dstParentID
,
283 ConstUTF8Param dstName
,
287 EXTERN_API_C( OSErr
)
288 UpdateCatalogNode (ExtendedVCB
* volume
,
289 HFSCatalogNodeID parentID
,
292 const CatalogNodeData
* nodeData
);
294 EXTERN_API_C( OSErr
)
295 CreateFileIDRef (ExtendedVCB
* volume
,
296 HFSCatalogNodeID parentID
,
299 HFSCatalogNodeID
* threadID
);
301 EXTERN_API_C( OSErr
)
302 ExchangeFileIDs (ExtendedVCB
* volume
,
303 ConstUTF8Param srcName
,
304 ConstUTF8Param destName
,
305 HFSCatalogNodeID srcID
,
306 HFSCatalogNodeID destID
,
310 EXTERN_API_C( OSErr
)
311 LinkCatalogNode (ExtendedVCB
* volume
,
312 HFSCatalogNodeID parentID
,
314 HFSCatalogNodeID linkParentID
,
315 ConstUTF8Param linkName
);
317 EXTERN_API_C( SInt32
)
318 CompareCatalogKeys (HFSCatalogKey
* searchKey
,
319 HFSCatalogKey
* trialKey
);
321 EXTERN_API_C( SInt32
)
322 CompareExtendedCatalogKeys (HFSPlusCatalogKey
* searchKey
,
323 HFSPlusCatalogKey
* trialKey
);
325 EXTERN_API_C( OSErr
)
326 InitCatalogCache (void);
329 InvalidateCatalogCache (ExtendedVCB
* volume
);
332 /* GenericMRUCache Routines*/
333 EXTERN_API_C( OSErr
)
334 InitMRUCache (UInt32 bufferSize
,
335 UInt32 numCacheBlocks
,
338 EXTERN_API_C( OSErr
)
339 DisposeMRUCache (Ptr cachePtr
);
342 TrashMRUCache (Ptr cachePtr
);
344 EXTERN_API_C( OSErr
)
345 GetMRUCacheBlock (UInt32 key
,
350 InvalidateMRUCacheBlock (Ptr cachePtr
,
354 InsertMRUCacheBlock (Ptr cachePtr
,
358 /* BTree Manager Routines*/
360 typedef CALLBACK_API_C( SInt32
, KeyCompareProcPtr
)(void *a
, void *b
);
363 EXTERN_API_C( OSErr
)
364 SearchBTreeRecord (FileReference refNum
,
372 EXTERN_API_C( OSErr
)
373 InsertBTreeRecord (FileReference refNum
,
379 EXTERN_API_C( OSErr
)
380 DeleteBTreeRecord (FileReference refNum
,
383 EXTERN_API_C( OSErr
)
384 ReplaceBTreeRecord (FileReference refNum
,
392 /* Prototypes for exported routines in VolumeAllocation.c*/
393 EXTERN_API_C( OSErr
)
394 BlockAllocate (ExtendedVCB
* vcb
,
395 UInt32 startingBlock
,
396 SInt64 bytesRequested
,
398 Boolean forceContiguous
,
400 UInt32
* actualBlocks
);
402 EXTERN_API_C( OSErr
)
403 BlockDeallocate (ExtendedVCB
* vcb
,
407 EXTERN_API_C( UInt32
)
408 FileBytesToBlocks (SInt64 numerator
,
411 /* File Extent Mapping routines*/
412 EXTERN_API_C( OSErr
)
413 FlushExtentFile (ExtendedVCB
* vcb
);
415 EXTERN_API_C( SInt32
)
416 CompareExtentKeys (const HFSExtentKey
* searchKey
,
417 const HFSExtentKey
* trialKey
);
419 EXTERN_API_C( SInt32
)
420 CompareExtentKeysPlus (const HFSPlusExtentKey
*searchKey
,
421 const HFSPlusExtentKey
*trialKey
);
423 EXTERN_API_C( OSErr
)
424 DeleteFile (ExtendedVCB
* vcb
,
425 HFSCatalogNodeID parDirID
,
426 ConstUTF8Param catalogName
,
429 EXTERN_API_C( OSErr
)
430 TruncateFileC (ExtendedVCB
* vcb
,
433 Boolean truncateToExtent
);
435 EXTERN_API_C( OSErr
)
436 ExtendFileC (ExtendedVCB
* vcb
,
441 SInt64
* actualBytesAdded
);
443 EXTERN_API_C( OSErr
)
444 MapFileBlockC (ExtendedVCB
* vcb
,
446 size_t numberOfBytes
,
448 daddr_t
* startBlock
,
449 size_t * availableBytes
);
451 #if TARGET_API_MACOS_X
452 EXTERN_API_C( Boolean
)
453 NodesAreContiguous (ExtendedVCB
* vcb
,
458 /* Utility routines*/
461 ClearMemory (void * start
,
464 EXTERN_API_C( OSErr
)
465 VolumeWritable (ExtendedVCB
* vcb
);
468 /* Get the current time in UTC (GMT)*/
469 EXTERN_API_C( UInt32
)
472 /* Get the current local time*/
473 EXTERN_API_C( UInt32
)
474 GetTimeLocal (Boolean forHFS
);
476 EXTERN_API_C( UInt32
)
477 LocalToUTC (UInt32 localTime
);
479 EXTERN_API_C( UInt32
)
480 UTCToLocal (UInt32 utcTime
);
483 /* Volumes routines*/
484 EXTERN_API_C( OSErr
)
485 FlushVolumeControlBlock (ExtendedVCB
* vcb
);
487 EXTERN_API_C( OSErr
)
488 ValidVolumeHeader (HFSPlusVolumeHeader
* volumeHeader
);
491 #if PRAGMA_STRUCT_ALIGN
492 #pragma options align=reset
493 #elif PRAGMA_STRUCT_PACKPUSH
495 #elif PRAGMA_STRUCT_PACK
499 #ifdef PRAGMA_IMPORT_OFF
509 #endif /* __FILEMGRINTERNAL__ */