]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/hfs/hfscommon/Catalog/FileIDsServices.c
xnu-2050.7.9.tar.gz
[apple/xnu.git] / bsd / hfs / hfscommon / Catalog / FileIDsServices.c
index fee50fe6de2001cb795e415081fe6c6d4d7e02ae..29242d367f91ef9b226cb3fe1edae93683636f7f 100644 (file)
@@ -32,6 +32,9 @@
 #include       "../headers/FileMgrInternal.h"
 #include       "../headers/HFSUnicodeWrappers.h"
 #include       "../headers/CatalogPrivate.h"
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <libkern/libkern.h>
 
 
 struct ExtentsRecBuffer {
@@ -112,13 +115,13 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
        int16_t         numDestExtentBlocks;
        OSErr           err;
        Boolean         isHFSPlus = ( vcb->vcbSigWord == kHFSPlusSigWord );
-       
+
        err = BuildCatalogKeyUTF8(vcb, srcID, srcName, kUndefinedStrLen, &srcKey, NULL);
        ReturnIfError(err);
-       
+
        err = BuildCatalogKeyUTF8(vcb, destID, destName, kUndefinedStrLen, &destKey, NULL);
        ReturnIfError(err);
-       
+
        if ( isHFSPlus )
        {
                //--    Step 1: Check the catalog nodes for extents
@@ -126,27 +129,27 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                //--    locate the source file, test for extents in extent file, and copy the cat record for later
                err = LocateCatalogNodeByKey( vcb, srcHint, &srcKey, &srcData, &srcHint );
                ReturnIfError( err );
-               
+       
                if ( srcData.recordType != kHFSPlusFileRecord )
                        return( cmFThdDirErr );                                 //      Error "cmFThdDirErr = it is a directory"
-               
+                       
                //--    Check if there are any extents in the source file
                //\80\80    I am only checling the extents in the low 32 bits, routine will fail if files extents after 2 gig are in overflow
                numSrcExtentBlocks = CheckExtents( srcData.hfsPlusFile.dataFork.extents, srcData.hfsPlusFile.dataFork.totalBlocks, isHFSPlus );
                if ( numSrcExtentBlocks == 0 )                                  //      then check the resource fork extents
                        numSrcExtentBlocks = CheckExtents( srcData.hfsPlusFile.resourceFork.extents, srcData.hfsPlusFile.resourceFork.totalBlocks, isHFSPlus );
-               
+
                //--    Check if there are any extents in the destination file
                err = LocateCatalogNodeByKey( vcb, destHint, &destKey, &destData, &destHint );
                ReturnIfError( err );
-               
+       
                if ( destData.recordType != kHFSPlusFileRecord )
                        return( cmFThdDirErr );                                 //      Error "cmFThdDirErr = it is a directory"
-               
+
                numDestExtentBlocks = CheckExtents( destData.hfsPlusFile.dataFork.extents, destData.hfsPlusFile.dataFork.totalBlocks, isHFSPlus );
                if ( numDestExtentBlocks == 0 )                                 //      then check the resource fork extents
                        numDestExtentBlocks = CheckExtents( destData.hfsPlusFile.resourceFork.extents, destData.hfsPlusFile.resourceFork.totalBlocks, isHFSPlus );
-               
+
                //--    Step 2: Exchange the Extent key in the extent file
                
                //--    Exchange the extents key in the extent file
@@ -156,7 +159,7 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                if ( numSrcExtentBlocks && numDestExtentBlocks )        //      if both files have extents
                {
                        //--    Change the source extents file ids to our known bogus value
-                       err = MoveExtents( vcb, srcData.hfsPlusFile.fileID, kHFSBogusExtentFileID, 0, 0, isHFSPlus );
+                       err = MoveExtents( vcb, srcData.hfsPlusFile.fileID, kHFSBogusExtentFileID, 0,0, isHFSPlus );
                        if ( err != noErr )
                        {
                                if ( err != dskFulErr )
@@ -171,13 +174,13 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                        {
                                if ( err != dskFulErr )
                                        return( err );
-                               
-                       ExUndo2aPlus:   err = DeleteExtents( vcb, srcData.hfsPlusFile.fileID, 0, 0, isHFSPlus );
+
+ExUndo2aPlus:  err = DeleteExtents( vcb, srcData.hfsPlusFile.fileID, 0, 0, isHFSPlus );
                                ReturnIfError( err );                                   //      we are doomed. Just QUIT!
-                               
+
                 err = MoveExtents( vcb, kHFSBogusExtentFileID, srcData.hfsPlusFile.fileID, 0, 0, isHFSPlus );  //      Move the extents back
                                ReturnIfError( err );                                   //      we are doomed. Just QUIT!
-                               
+                                       
                                goto ExUndo1a;
                        }
                        
@@ -187,13 +190,13 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                        {
                                if ( err != dskFulErr )
                                        return( err );
-                               
+
                                err = DeleteExtents( vcb, destData.hfsPlusFile.fileID, 0, 0, isHFSPlus );
                                ReturnIfError( err );                                   //      we are doomed. Just QUIT!
-                               
+
                                err = MoveExtents( vcb, srcData.hfsPlusFile.fileID, destData.hfsPlusFile.fileID, 0, 0, isHFSPlus );     //      Move the extents back
                                ReturnIfError( err );                                   //      we are doomed. Just QUIT!
-                               
+                                       
                                goto ExUndo2aPlus;
                        }
                        
@@ -205,10 +208,10 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                        {
                                if ( err != dskFulErr )
                                        return( err );
-                               
+
                                err = DeleteExtents( vcb, srcData.hfsPlusFile.fileID, 0, 0, isHFSPlus );
                                ReturnIfError( err );                                   //      we are doomed. Just QUIT!
-                               
+
                                goto FlushAndReturn;
                        }
                }
@@ -219,14 +222,14 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                        {
                                if ( err != dskFulErr )
                                        return( err );
-                               
+
                                err = DeleteExtents( vcb, destData.hfsPlusFile.fileID, 0, 0, isHFSPlus );
                                ReturnIfError( err );                                   //      we are doomed. Just QUIT!
-                               
+
                                goto FlushAndReturn;
                        }
                }
-               
+
                //--    Step 3: Change the data in the catalog nodes
                
                //--    find the source cnode and put dest info in it
@@ -239,12 +242,12 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                
                err = ReplaceBTreeRecord( vcb->catalogRefNum, &srcKey, srcHint, &srcData, sizeof(HFSPlusCatalogFile), &srcHint );
                ReturnIfError( err );
-               
+
                //      find the destination cnode and put source info in it            
                err = LocateCatalogNodeByKey( vcb, destHint, &destKey, &destData, &destHint );
                if ( err != noErr )
                        return( cmBadNews );
-               
+                       
                CopyBigCatalogNodeInfo( &swapData, &destData );
                err = ReplaceBTreeRecord( vcb->catalogRefNum, &destKey, destHint, &destData, sizeof(HFSPlusCatalogFile), &destHint );
                ReturnIfError( err );
@@ -256,10 +259,10 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                //--    locate the source file, test for extents in extent file, and copy the cat record for later
                err = LocateCatalogNodeByKey( vcb, srcHint, &srcKey, &srcData, &srcHint );
                ReturnIfError( err );
-               
+       
                if ( srcData.recordType != kHFSFileRecord )
                        return( cmFThdDirErr );                                 //      Error "cmFThdDirErr = it is a directory"
-               
+                       
                //--    Check if there are any extents in the source file
                numSrcExtentBlocks = CheckExtents( srcData.hfsFile.dataExtents, srcData.hfsFile.dataPhysicalSize / vcb->blockSize, isHFSPlus );
                if ( numSrcExtentBlocks == 0 )                                  //      then check the resource fork extents
@@ -268,21 +271,21 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                
                //\80\80    Do we save the found source node for later use?
                
-               
+                               
                //--    Check if there are any extents in the destination file
                err = LocateCatalogNodeByKey( vcb, destHint, &destKey, &destData, &destHint );
                ReturnIfError( err );
-               
+       
                if ( destData.recordType != kHFSFileRecord )
                        return( cmFThdDirErr );                                 //      Error "cmFThdDirErr = it is a directory"
-               
+
                numDestExtentBlocks = CheckExtents( destData.hfsFile.dataExtents, destData.hfsFile.dataPhysicalSize / vcb->blockSize, isHFSPlus );
                if ( numDestExtentBlocks == 0 )                                 //      then check the resource fork extents
                        numDestExtentBlocks = CheckExtents( destData.hfsFile.rsrcExtents, destData.hfsFile.rsrcPhysicalSize / vcb->blockSize, isHFSPlus );
-               
+                       
                //\80\80    Do we save the found destination node for later use?
-               
-               
+
+
                //--    Step 2: Exchange the Extent key in the extent file
                
                //--    Exchange the extents key in the extent file
@@ -292,15 +295,15 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                if ( numSrcExtentBlocks && numDestExtentBlocks )        //      if both files have extents
                {
                        //--    Change the source extents file ids to our known bogus value
-                       err = MoveExtents( vcb, srcData.hfsFile.fileID, kHFSBogusExtentFileID, 0, 0, isHFSPlus );
+        err = MoveExtents( vcb, srcData.hfsFile.fileID, kHFSBogusExtentFileID, 0, 0, isHFSPlus );
                        if ( err != noErr )
                        {
                                if ( err != dskFulErr )
                                        return( err );
-                               
-                       ExUndo1a:               err = DeleteExtents( vcb, kHFSBogusExtentFileID, 0, 0, isHFSPlus );
+
+ExUndo1a:              err = DeleteExtents( vcb, kHFSBogusExtentFileID, 0, 0, isHFSPlus );
                                ReturnIfError( err );                                   //      we are doomed. Just QUIT!
-                               
+
                                err = FlushCatalog( vcb );                      //      flush the catalog
                                err = FlushExtentFile( vcb );                   //      flush the extent file (unneeded for common case, but it's cheap)                        
                                return( dskFulErr );
@@ -312,13 +315,13 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                        {
                                if ( err != dskFulErr )
                                        return( err );
-                               
-                       ExUndo2a:               err = DeleteExtents( vcb, srcData.hfsFile.fileID, 0, 0, isHFSPlus );
+
+ExUndo2a:              err = DeleteExtents( vcb, srcData.hfsFile.fileID, 0, 0, isHFSPlus );
                                ReturnIfError( err );                                   //      we are doomed. Just QUIT!
-                               
+
                 err = MoveExtents( vcb, kHFSBogusExtentFileID, srcData.hfsFile.fileID, 0, 0, isHFSPlus );      //      Move the extents back
                                ReturnIfError( err );                                   //      we are doomed. Just QUIT!
-                               
+                                       
                                goto ExUndo1a;
                        }
                        
@@ -328,13 +331,13 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                        {
                                if ( err != dskFulErr )
                                        return( err );
-                               
+
                                err = DeleteExtents( vcb, destData.hfsFile.fileID, 0, 0, isHFSPlus );
                                ReturnIfError( err );                                   //      we are doomed. Just QUIT!
-                               
+
                                err = MoveExtents( vcb, srcData.hfsFile.fileID, destData.hfsFile.fileID, 0, 0, isHFSPlus );     //      Move the extents back
                                ReturnIfError( err );                                   //      we are doomed. Just QUIT!
-                               
+                                       
                                goto ExUndo2a;
                        }
                        
@@ -346,10 +349,10 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                        {
                                if ( err != dskFulErr )
                                        return( err );
-                               
+
                                err = DeleteExtents( vcb, srcData.hfsFile.fileID, 0, 0, isHFSPlus );
                                ReturnIfError( err );                                   //      we are doomed. Just QUIT!
-                               
+
                                goto FlushAndReturn;
                        }
                }
@@ -360,14 +363,14 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                        {
                                if ( err != dskFulErr )
                                        return( err );
-                               
+
                                err = DeleteExtents( vcb, destData.hfsFile.fileID, 0, 0, isHFSPlus );
                                ReturnIfError( err );                                   //      we are doomed. Just QUIT!
-                               
+
                                goto FlushAndReturn;
                        }
                }
-               
+
                //--    Step 3: Change the data in the catalog nodes
                
                //--    find the source cnode and put dest info in it
@@ -381,23 +384,23 @@ OSErr ExchangeFileIDs( ExtendedVCB *vcb, ConstUTF8Param srcName, ConstUTF8Param
                
                err = ReplaceBTreeRecord( vcb->catalogRefNum, &srcKey, srcHint, &srcData, sizeof(HFSCatalogFile), &srcHint );
                ReturnIfError( err );
-               
+
                
                //      find the destination cnode and put source info in it            
                err = LocateCatalogNodeByKey( vcb, destHint, &destKey, &destData, &destHint );
                if ( err != noErr )
                        return( cmBadNews );
-               
+                       
                CopyCatalogNodeInfo( &swapData, &destData );
                err = ReplaceBTreeRecord( vcb->catalogRefNum, &destKey, destHint, &destData, sizeof(HFSCatalogFile), &destHint );
                ReturnIfError( err );
        }
        
        err = noErr;
-       
+
        //--    Step 4: Error Handling section
-       
-       
+
+
 FlushAndReturn:
        err = FlushCatalog( vcb );                      //      flush the catalog
        err = FlushExtentFile( vcb );                   //      flush the extent file (unneeded for common case, but it's cheap)                        
@@ -430,23 +433,39 @@ static OSErr  MoveExtents( ExtendedVCB *vcb, u_int32_t srcFileID, u_int32_t dest
        ExtentsRecBuffer        extentsBuffer[kNumExtentsToCache];
        ExtentKey *                     extentKeyPtr;
        ExtentRecord            extentData;
-       BTreeIterator           btIterator;
+       struct BTreeIterator *btIterator = NULL;
+       struct BTreeIterator *tmpIterator = NULL;
        FSBufferDescriptor      btRecord;
        u_int16_t                       btKeySize;
        u_int16_t                       btRecordSize;
        int16_t                         i, j;
        OSErr                           err;
        
-       
+       MALLOC (btIterator, struct BTreeIterator*, sizeof(struct BTreeIterator), M_TEMP, M_WAITOK);
+       if (btIterator == NULL) {
+               return memFullErr;  // translates to ENOMEM
+       }
+
+
+       MALLOC (tmpIterator, struct BTreeIterator*, sizeof(struct BTreeIterator), M_TEMP, M_WAITOK);
+       if (tmpIterator == NULL) {      
+               FREE (btIterator, M_TEMP);      
+               return memFullErr;  // translates to ENOMEM
+       }
+
+       bzero(btIterator, sizeof(*btIterator));
+       bzero (tmpIterator, sizeof(*tmpIterator));
+
+
        fcb = GetFileControlBlock(vcb->extentsRefNum);
        
-       (void) BTInvalidateHint(&btIterator);
-       extentKeyPtr = (ExtentKey*) &btIterator.key;
+       (void) BTInvalidateHint(btIterator);
+       extentKeyPtr = (ExtentKey*) &btIterator->key;
        btRecord.bufferAddress = &extentData;
        btRecord.itemCount = 1;
-       
+
        //--    Collect the extent records
-       
+
        //
        //      A search on the following key will cause the BTree to be positioned immediately
        //      before the first extent record for file #srcFileID, but not actually positioned
@@ -459,7 +478,7 @@ static OSErr  MoveExtents( ExtendedVCB *vcb, u_int32_t srcFileID, u_int32_t dest
        if (isHFSPlus) {
                btRecord.itemSize = sizeof(HFSPlusExtentRecord);
                btKeySize = sizeof(HFSPlusExtentKey);
-               
+
                extentKeyPtr->hfsPlus.keyLength  = kHFSPlusExtentKeyMaximumLength;
                extentKeyPtr->hfsPlus.forkType   = forkType;
                extentKeyPtr->hfsPlus.pad                = 0;
@@ -469,7 +488,7 @@ static OSErr  MoveExtents( ExtendedVCB *vcb, u_int32_t srcFileID, u_int32_t dest
        else {
                btRecord.itemSize = sizeof(HFSExtentRecord);
                btKeySize = sizeof(HFSExtentKey);
-               
+
                extentKeyPtr->hfs.keyLength      = kHFSExtentKeyMaximumLength;
                extentKeyPtr->hfs.forkType       = 0;
                extentKeyPtr->hfs.fileID         = srcFileID;
@@ -491,8 +510,8 @@ static OSErr  MoveExtents( ExtendedVCB *vcb, u_int32_t srcFileID, u_int32_t dest
        //      of BTIterateRecord.  We'd need to set up the key for BTSearchRecord to find the last record
        //      we found, so that BTIterateRecord would get the next one (the first we haven't processed).
        //
-       
-       err = BTSearchRecord(fcb, &btIterator, &btRecord, &btRecordSize, &btIterator);
+
+       err = BTSearchRecord(fcb, btIterator, &btRecord, &btRecordSize, btIterator);
        
        //      We expect a btNotFound here, since there shouldn't be an extent record with FABN = 0.
        if (err != btNotFound)
@@ -503,24 +522,28 @@ static OSErr  MoveExtents( ExtendedVCB *vcb, u_int32_t srcFileID, u_int32_t dest
                if (err == noErr)                       //      If we found such a bogus extent record, then the tree is really messed up
                        err = cmBadNews;                //      so return an error that conveys the disk is hosed.
                
+               FREE (tmpIterator, M_TEMP);     
+               FREE (btIterator, M_TEMP);
                return err;
        }
-       
+
        do
        {
                btRecord.bufferAddress = &extentData;
                btRecord.itemCount = 1;
-               
+
                for ( i=0 ; i<kNumExtentsToCache ; i++ )
                {
                        HFSCatalogNodeID        foundFileID;
                        
-                       err = BTIterateRecord(fcb, kBTreeNextRecord, &btIterator, &btRecord, &btRecordSize);
+                       err = BTIterateRecord(fcb, kBTreeNextRecord, btIterator, &btRecord, &btRecordSize);
                        if ( err == btNotFound )                //      Did we run out of extent records in the extents tree?
                                break;                                          //      if xkrFNum(A0) is cleared on this error, then this test is bogus!
-                       else if ( err != noErr )
+                       else if ( err != noErr ) {
+                               FREE (btIterator, M_TEMP);
+                               FREE (tmpIterator, M_TEMP);
                                return( err );                          //      must be ioError
-                       
+                       }
                        foundFileID = isHFSPlus ? extentKeyPtr->hfsPlus.fileID : extentKeyPtr->hfs.fileID;
                        if ( foundFileID == srcFileID ) {
                                /* Check if we need to quit early. */
@@ -537,39 +560,45 @@ static OSErr  MoveExtents( ExtendedVCB *vcb, u_int32_t srcFileID, u_int32_t dest
                        }
                }
                
+               
+               
                //--    edit each extent key, and reinsert each extent record in the extent file
                if (isHFSPlus)
                        btRecordSize = sizeof(HFSPlusExtentRecord);
                else
                        btRecordSize = sizeof(HFSExtentRecord);
-               
-               for ( j=0 ; j<i ; j++ ) {
-                       BTreeIterator tmpIterator;
-                       
+
+               for ( j=0 ; j<i ; j++ )
+               {
+
                        if (isHFSPlus)
                                extentsBuffer[j].extentKey.hfsPlus.fileID = destFileID; //      change only the id in the key to dest ID
                        else
                                extentsBuffer[j].extentKey.hfs.fileID = destFileID;     //      change only the id in the key to dest ID
-                       
+
                        // get iterator and buffer descriptor ready...
-                       (void) BTInvalidateHint(&tmpIterator);
-                       BlockMoveData(&(extentsBuffer[j].extentKey), &tmpIterator.key, btKeySize);
+                       (void) BTInvalidateHint(tmpIterator);
+                       BlockMoveData(&(extentsBuffer[j].extentKey), &tmpIterator->key, btKeySize);
                        btRecord.bufferAddress = &(extentsBuffer[j].extentData);
-                       
-                       err = BTInsertRecord(fcb, &tmpIterator, &btRecord, btRecordSize);
-                       if ( err != noErr )
-                       {                                                                       //      parse the error
+
+                       err = BTInsertRecord(fcb, tmpIterator, &btRecord, btRecordSize);
+                       if ( err != noErr ) {                                                           
+                               /* Parse the error and free iterators */
+                               FREE (btIterator, M_TEMP);
+                               FREE (tmpIterator, M_TEMP);
                                if ( err == btExists )
                                {
-                                       if ( DEBUG_BUILD )
-                                               DebugStr("Can't insert record -- already exists");
+                                       if ( DEBUG_BUILD ) {
+                                               DebugStr("Can't insert record -- already exists"); 
+                                       }
                                        return( cmBadNews );
                                }
-                               else
+                               else {
                                        return( err );
+                               }                       
                        }
                }
-               
+
                //--    okay, done with this buffered batch, go get the next set of extent records
                //      If our buffer is not full, we must be done, or recieved an error
                
@@ -582,6 +611,9 @@ static OSErr  MoveExtents( ExtendedVCB *vcb, u_int32_t srcFileID, u_int32_t dest
                }
        } while ( true );
        
+       FREE (tmpIterator, M_TEMP);
+       FREE (btIterator, M_TEMP);
+
        return( err );
 }
 
@@ -593,33 +625,47 @@ static void  CopyExtentInfo( ExtentKey *key, ExtentRecord *data, ExtentsRecBuffe
 }
 
 
-
-
 //--   Delete all extents in extent file that have the ID given.
 static OSErr  DeleteExtents( ExtendedVCB *vcb, u_int32_t fileID, int quitEarly,  u_int8_t forkType, Boolean isHFSPlus )
 {
        FCB *                           fcb;
        ExtentKey *                     extentKeyPtr;
        ExtentRecord            extentData;
-       BTreeIterator           btIterator;
+       struct BTreeIterator *btIterator = NULL;
+       struct BTreeIterator *tmpIterator = NULL;
        FSBufferDescriptor      btRecord;
        u_int16_t                       btRecordSize;
        OSErr                           err;
-       
+
+
+       MALLOC (btIterator, struct BTreeIterator*, sizeof(struct BTreeIterator), M_TEMP, M_WAITOK);
+       if (btIterator == NULL) {
+               return memFullErr;  // translates to ENOMEM
+       }
+
+       MALLOC (tmpIterator, struct BTreeIterator*, sizeof(struct BTreeIterator), M_TEMP, M_WAITOK);
+       if (tmpIterator == NULL) {      
+               FREE (btIterator, M_TEMP);      
+               return memFullErr;  // translates to ENOMEM
+       }
+
+       bzero(btIterator, sizeof(*btIterator));
+       bzero (tmpIterator, sizeof(*tmpIterator));
+
        fcb = GetFileControlBlock(vcb->extentsRefNum);
-       
-       (void) BTInvalidateHint(&btIterator);
-       extentKeyPtr = (ExtentKey*) &btIterator.key;
+
+       (void) BTInvalidateHint(btIterator);
+       extentKeyPtr = (ExtentKey*) &btIterator->key;
        btRecord.bufferAddress = &extentData;
        btRecord.itemCount = 1;
-       
+
        //      The algorithm is to position the BTree just before any extent records for fileID.
        //      Then just keep getting successive records.  If the record is still for fileID,
        //      then delete it.
        
        if (isHFSPlus) {
                btRecord.itemSize = sizeof(HFSPlusExtentRecord);
-               
+
                extentKeyPtr->hfsPlus.keyLength  = kHFSPlusExtentKeyMaximumLength;
                extentKeyPtr->hfsPlus.forkType   = forkType;
                extentKeyPtr->hfsPlus.pad                = 0;
@@ -628,14 +674,14 @@ static OSErr  DeleteExtents( ExtendedVCB *vcb, u_int32_t fileID, int quitEarly,
        }
        else {
                btRecord.itemSize = sizeof(HFSExtentRecord);
-               
+
                extentKeyPtr->hfs.keyLength      = kHFSExtentKeyMaximumLength;
                extentKeyPtr->hfs.forkType       = forkType;
                extentKeyPtr->hfs.fileID         = fileID;
                extentKeyPtr->hfs.startBlock = 0;
        }
-       
-       err = BTSearchRecord(fcb, &btIterator, &btRecord, &btRecordSize, &btIterator);
+
+       err = BTSearchRecord(fcb, btIterator, &btRecord, &btRecordSize, btIterator);
        if ( err != btNotFound )
        {
                if (err == noErr) {             //      Did we find a bogus extent record?
@@ -644,18 +690,17 @@ static OSErr  DeleteExtents( ExtendedVCB *vcb, u_int32_t fileID, int quitEarly,
                
                return err;                             //      Got some unexpected error, so return it
        }
-       
+
        do
        {
-               BTreeIterator           tmpIterator;
                HFSCatalogNodeID        foundFileID;
-               
-               err = BTIterateRecord(fcb, kBTreeNextRecord, &btIterator, &btRecord, &btRecordSize);
+
+               err = BTIterateRecord(fcb, kBTreeNextRecord, btIterator, &btRecord, &btRecordSize);
                if ( err != noErr )
                {
                        if (err == btNotFound)  //      If we hit the end of the BTree
                                err = noErr;            //              then it's OK
-                       
+                               
                        break;                                  //      We're done now.
                }
                
@@ -670,12 +715,15 @@ static OSErr  DeleteExtents( ExtendedVCB *vcb, u_int32_t fileID, int quitEarly,
                        }
                }
                
-               tmpIterator = btIterator;
-               err = BTDeleteRecord( fcb, &tmpIterator );
+               *tmpIterator = *btIterator;
+               err = BTDeleteRecord( fcb, tmpIterator );
                if (err != noErr)
                        break;
        }       while ( true );
        
+       FREE (tmpIterator, M_TEMP);
+       FREE (btIterator, M_TEMP);
+
        return( err );
 }