--- /dev/null
+/*
+ * Copyright (c) 2000-2015 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+/*
+ File: FilesInternal.h
+
+ Contains: IPI for File Manager (HFS Plus)
+
+ Version: HFS Plus 1.0
+
+ Copyright: (c) 1996-2001 by Apple Inc., all rights reserved.
+
+*/
+#ifndef __FILEMGRINTERNAL__
+#define __FILEMGRINTERNAL__
+
+#include <sys/appleapiopts.h>
+
+#ifdef KERNEL
+#ifdef __APPLE_API_PRIVATE
+
+#include <sys/param.h>
+#include <sys/vnode.h>
+
+#if !HFS_ALLOC_TEST
+
+#include "hfs.h"
+#include "hfs_macos_defs.h"
+#include "hfs_format.h"
+#include "hfs_cnode.h"
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* CatalogNodeID is used to track catalog objects */
+typedef u_int32_t HFSCatalogNodeID;
+
+/* internal error codes*/
+
+#if TARGET_API_MACOS_X
+ #define ERR_BASE -32767
+#else
+ #define ERR_BASE 0
+#endif
+
+enum {
+ /* FXM errors*/
+ fxRangeErr = ERR_BASE + 16, /* file position beyond mapped range*/
+ fxOvFlErr = ERR_BASE + 17, /* extents file overflow*/
+ /* Unicode errors*/
+ uniTooLongErr = ERR_BASE + 24, /* Unicode string too long to convert to Str31*/
+ uniBufferTooSmallErr = ERR_BASE + 25, /* Unicode output buffer too small*/
+ uniNotMappableErr = ERR_BASE + 26, /* Unicode string can't be mapped to given script*/
+ /* BTree Manager errors*/
+ btNotFound = ERR_BASE + 32, /* record not found*/
+ btExists = ERR_BASE + 33, /* record already exists*/
+ btNoSpaceAvail = ERR_BASE + 34, /* no available space*/
+ btNoFit = ERR_BASE + 35, /* record doesn't fit in node */
+ btBadNode = ERR_BASE + 36, /* bad node detected*/
+ btBadHdr = ERR_BASE + 37, /* bad BTree header record detected*/
+ dsBadRotate = ERR_BASE + 64, /* bad BTree rotate*/
+ /* Catalog Manager errors*/
+ cmNotFound = ERR_BASE + 48, /* CNode not found*/
+ cmExists = ERR_BASE + 49, /* CNode already exists*/
+ cmNotEmpty = ERR_BASE + 50, /* directory CNode not empty (valence = 0)*/
+ cmRootCN = ERR_BASE + 51, /* invalid reference to root CNode*/
+ cmBadNews = ERR_BASE + 52, /* detected bad catalog structure*/
+ cmFThdDirErr = ERR_BASE + 53, /* thread belongs to a directory not a file*/
+ cmFThdGone = ERR_BASE + 54, /* file thread doesn't exist*/
+ cmParentNotFound = ERR_BASE + 55, /* CNode for parent ID does not exist*/
+ /* TFS internal errors*/
+ fsDSIntErr = -127 /* Internal file system error*/
+};
+
+
+/* internal flags*/
+
+enum {
+ kEFAllMask = 0x01, /* allocate all requested bytes or none */
+ kEFContigMask = 0x02, /* force contiguous allocation */
+ kEFReserveMask = 0x04, /* keep block reserve */
+ kEFDeferMask = 0x08, /* defer file block allocations */
+ kEFNoClumpMask = 0x10, /* don't round up to clump size */
+ kEFMetadataMask = 0x20, /* metadata allocation */
+
+ kTFTrunExtBit = 0, /* truncate to the extent containing new PEOF*/
+ kTFTrunExtMask = 1
+};
+
+enum {
+ kUndefinedStrLen = 0, /* Unknown string length */
+ kNoHint = 0,
+
+ /* FileIDs variables*/
+ kNumExtentsToCache = 4 /* just guessing for ExchangeFiles*/
+};
+
+
+/* Universal Extent Key */
+
+union ExtentKey {
+ HFSExtentKey hfs;
+ HFSPlusExtentKey hfsPlus;
+};
+typedef union ExtentKey ExtentKey;
+/* Universal extent descriptor */
+
+union ExtentDescriptor {
+ HFSExtentDescriptor hfs;
+ HFSPlusExtentDescriptor hfsPlus;
+};
+typedef union ExtentDescriptor ExtentDescriptor;
+/* Universal extent record */
+
+union ExtentRecord {
+ HFSExtentRecord hfs;
+ HFSPlusExtentRecord hfsPlus;
+};
+typedef union ExtentRecord ExtentRecord;
+
+
+enum {
+ CMMaxCName = kHFSMaxFileNameChars
+};
+
+
+
+/* Universal catalog name*/
+
+union CatalogName {
+ Str31 pstr;
+ HFSUniStr255 ustr;
+};
+typedef union CatalogName CatalogName;
+
+
+/*
+ * MacOS accessor routines
+ */
+#define GetFileControlBlock(fref) VTOF((fref))
+#define GetFileRefNumFromFCB(fcb) FTOV((fcb))
+
+/* Test for error and return if error occurred*/
+EXTERN_API_C( void )
+ReturnIfError (OSErr result);
+
+#define ReturnIfError(result) do { if ( (result) != noErr ) return (result); } while(0)
+
+/* Exit function on error*/
+EXTERN_API_C( void )
+ExitOnError (OSErr result);
+
+#define ExitOnError( result ) do { if ( ( result ) != noErr ) goto ErrorExit; } while(0)
+
+
+
+/* Catalog Manager Routines (IPI)*/
+
+EXTERN_API_C( OSErr )
+ExchangeFileIDs (ExtendedVCB * volume,
+ ConstUTF8Param srcName,
+ ConstUTF8Param destName,
+ HFSCatalogNodeID srcID,
+ HFSCatalogNodeID destID,
+ u_int32_t srcHint,
+ u_int32_t destHint );
+
+EXTERN_API_C( OSErr )
+MoveData( ExtendedVCB *vcb, HFSCatalogNodeID srcID, HFSCatalogNodeID destID, int rsrc);
+
+/* BTree Manager Routines*/
+
+typedef CALLBACK_API_C( int32_t , KeyCompareProcPtr )(void *a, void *b);
+
+
+EXTERN_API_C( OSErr )
+ReplaceBTreeRecord (FileReference refNum,
+ const void * key,
+ u_int32_t hint,
+ void * newData,
+ u_int16_t dataSize,
+ u_int32_t * newHint);
+
+
+/* Prototypes for exported routines in VolumeAllocation.c*/
+
+/*
+ * Flags for BlockAllocate(), BlockDeallocate() and hfs_block_alloc.
+ * Some of these are for internal use only. See the comment at the
+ * top of hfs_alloc_int for more details on the semantics of these
+ * flags.
+ */
+#define HFS_ALLOC_FORCECONTIG 0x001 //force contiguous block allocation; minblocks must be allocated
+#define HFS_ALLOC_METAZONE 0x002 //can use metazone blocks
+#define HFS_ALLOC_SKIPFREEBLKS 0x004 //skip checking/updating freeblocks during alloc/dealloc
+#define HFS_ALLOC_FLUSHTXN 0x008 //pick best fit for allocation, even if a jnl flush is req'd
+#define HFS_ALLOC_TENTATIVE 0x010 //reserved allocation that can be claimed back
+#define HFS_ALLOC_LOCKED 0x020 //reserved allocation that can't be claimed back
+#define HFS_ALLOC_IGNORE_TENTATIVE 0x040 //Steal tentative blocks if necessary
+#define HFS_ALLOC_IGNORE_RESERVED 0x080 //Ignore tentative/committed blocks
+#define HFS_ALLOC_USE_TENTATIVE 0x100 //Use the supplied tentative range (if possible)
+#define HFS_ALLOC_COMMIT 0x200 //Commit the supplied extent to disk
+#define HFS_ALLOC_TRY_HARD 0x400 //Search hard to try and get maxBlocks; implies HFS_ALLOC_FLUSHTXN
+#define HFS_ALLOC_ROLL_BACK 0x800 //Reallocate blocks that were just deallocated
+#define HFS_ALLOC_FAST_DEV 0x1000 //Prefer fast device for allocation
+
+typedef uint32_t hfs_block_alloc_flags_t;
+
+struct rl_entry;
+EXTERN_API_C( OSErr )
+BlockAllocate (ExtendedVCB * vcb,
+ u_int32_t startingBlock,
+ u_int32_t minBlocks,
+ u_int32_t maxBlocks,
+ hfs_block_alloc_flags_t flags,
+ u_int32_t * startBlock,
+ u_int32_t * actualBlocks);
+
+typedef struct hfs_alloc_extra_args {
+ // Used with HFS_ALLOC_TRY_HARD and HFS_ALLOC_FORCECONTIG
+ uint32_t max_blocks;
+
+ // Used with with HFS_ALLOC_USE_TENTATIVE & HFS_ALLOC_COMMIT
+ struct rl_entry **reservation_in;
+
+ // Used with HFS_ALLOC_TENTATIVE & HFS_ALLOC_LOCKED
+ struct rl_entry **reservation_out;
+
+ /*
+ * If the maximum cannot be returned, the allocation will be
+ * trimmed to the specified alignment after taking
+ * @alignment_offset into account. @alignment and
+ * @alignment_offset are both in terms of blocks, *not* bytes.
+ * The result will be such that:
+ *
+ * (block_count + @alignment_offset) % @alignment == 0
+ *
+ * Alignment is *not* guaranteed.
+ *
+ * One example where alignment might be useful is in the case
+ * where the page size is greater than the allocation block size
+ * and I/O is being performed in multiples of the page size.
+ */
+ int alignment;
+ int alignment_offset;
+} hfs_alloc_extra_args_t;
+
+/*
+ * Same as BlockAllocate but slightly different API.
+ * @extent.startBlock is a hint for where to start searching and
+ * @extent.blockCount is the minimum number of blocks acceptable.
+ * Additional arguments can be passed in @extra_args and use will
+ * depend on @flags. See comment at top of hfs_block_alloc_int for
+ * more information.
+ */
+errno_t hfs_block_alloc(hfsmount_t *hfsmp,
+ HFSPlusExtentDescriptor *extent,
+ hfs_block_alloc_flags_t flags,
+ hfs_alloc_extra_args_t *extra_args);
+
+EXTERN_API_C( OSErr )
+BlockDeallocate (ExtendedVCB * vcb,
+ u_int32_t firstBlock,
+ u_int32_t numBlocks,
+ hfs_block_alloc_flags_t flags);
+
+EXTERN_API_C ( void )
+ResetVCBFreeExtCache(struct hfsmount *hfsmp);
+
+EXTERN_API_C( OSErr )
+BlockMarkAllocated(ExtendedVCB *vcb, u_int32_t startingBlock, u_int32_t numBlocks);
+
+EXTERN_API_C( OSErr )
+BlockMarkFree( ExtendedVCB *vcb, u_int32_t startingBlock, u_int32_t numBlocks);
+
+EXTERN_API_C( OSErr )
+BlockMarkFreeUnused( ExtendedVCB *vcb, u_int32_t startingBlock, u_int32_t numBlocks);
+
+EXTERN_API_C( u_int32_t )
+MetaZoneFreeBlocks(ExtendedVCB *vcb);
+
+EXTERN_API_C( u_int32_t )
+UpdateAllocLimit (struct hfsmount *hfsmp, u_int32_t new_end_block);
+
+EXTERN_API_C( u_int32_t )
+ScanUnmapBlocks(struct hfsmount *hfsmp);
+
+EXTERN_API_C( int )
+hfs_init_summary (struct hfsmount *hfsmp);
+
+errno_t hfs_find_free_extents(struct hfsmount *hfsmp,
+ void (*callback)(void *data, off_t), void *callback_arg);
+
+void hfs_free_tentative(hfsmount_t *hfsmp, struct rl_entry **reservation);
+void hfs_free_locked(hfsmount_t *hfsmp, struct rl_entry **reservation);
+
+/* File Extent Mapping routines*/
+EXTERN_API_C( OSErr )
+FlushExtentFile (ExtendedVCB * vcb);
+
+#if CONFIG_HFS_STD
+EXTERN_API_C( int32_t )
+CompareExtentKeys (const HFSExtentKey * searchKey,
+ const HFSExtentKey * trialKey);
+#endif
+
+EXTERN_API_C( int32_t )
+CompareExtentKeysPlus (const HFSPlusExtentKey *searchKey,
+ const HFSPlusExtentKey *trialKey);
+
+OSErr SearchExtentFile(ExtendedVCB *vcb,
+ const FCB *fcb,
+ int64_t filePosition,
+ HFSPlusExtentKey *foundExtentKey,
+ HFSPlusExtentRecord foundExtentData,
+ u_int32_t *foundExtentDataIndex,
+ u_int32_t *extentBTreeHint,
+ u_int32_t *endingFABNPlusOne );
+
+EXTERN_API_C( OSErr )
+TruncateFileC (ExtendedVCB *vcb, FCB *fcb, int64_t peof, int deleted,
+ int rsrc, uint32_t fileid, Boolean truncateToExtent);
+
+EXTERN_API_C( OSErr )
+ExtendFileC (ExtendedVCB * vcb,
+ FCB * fcb,
+ int64_t bytesToAdd,
+ u_int32_t blockHint,
+ u_int32_t flags,
+ int64_t * actualBytesAdded);
+
+EXTERN_API_C( OSErr )
+MapFileBlockC (ExtendedVCB * vcb,
+ FCB * fcb,
+ size_t numberOfBytes,
+ off_t offset,
+ daddr64_t * startBlock,
+ size_t * availableBytes);
+
+OSErr HeadTruncateFile(ExtendedVCB *vcb, FCB *fcb, u_int32_t headblks);
+
+EXTERN_API_C( int )
+AddFileExtent (ExtendedVCB *vcb, FCB *fcb, u_int32_t startBlock, u_int32_t blockCount);
+
+#if TARGET_API_MACOS_X
+EXTERN_API_C( Boolean )
+NodesAreContiguous (ExtendedVCB * vcb,
+ FCB * fcb,
+ u_int32_t nodeSize);
+#endif
+
+/* Get the current time in UTC (GMT)*/
+EXTERN_API_C( u_int32_t )
+GetTimeUTC (void);
+
+EXTERN_API_C( u_int32_t )
+LocalToUTC (u_int32_t localTime);
+
+EXTERN_API_C( u_int32_t )
+UTCToLocal (u_int32_t utcTime);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __APPLE_API_PRIVATE */
+#endif /* KERNEL */
+#endif /* __FILEMGRINTERNAL__ */
+