]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/hfs/hfs_vfsutils.c
xnu-201.19.3.tar.gz
[apple/xnu.git] / bsd / hfs / hfs_vfsutils.c
index 36c3e550e3c2f37dbc268a5c672eebd3008dc32f..e6cfc9684cb4db7c6bf246e13f1e000124cc363d 100644 (file)
 
 #define BYPASSBLOCKINGOPTIMIZATION 0
 
-#define kMaxLockedMetaBuffers          32              /* number of locked buffer caches to hold for meta data */
-
 extern int (**hfs_vnodeop_p)(void *);
 extern int (**hfs_specop_p)(void *);
 extern int (**hfs_fifoop_p)(void *);
@@ -142,7 +140,6 @@ extern int count_lock_queue __P((void));
 extern uid_t console_user;
 
 OSErr  ValidMasterDirectoryBlock( HFSMasterDirectoryBlock *mdb );
-UInt16 DivUp( UInt32 byteRun, UInt32 blockSize );
 
 /* Externs from vhash */
 extern void hfs_vhashins_sibling(dev_t dev, UInt32 nodeID, struct hfsnode *hp, struct hfsfilemeta **fm);
@@ -151,7 +148,6 @@ extern struct vnode *hfs_vhashget(dev_t dev, UInt32 nodeID, UInt8 forkType);
 
 extern int hfs_vinit( struct mount *mntp, int (**specops)(void *), int (**fifoops)(), struct vnode **vpp);
 
-extern UInt16 CountRootFiles(ExtendedVCB *vcb);
 extern OSErr GetVolumeNameFromCatalog(ExtendedVCB *vcb);
 
 static int InitMetaFileVNode(struct vnode *vp, off_t eof, u_long clumpSize, const HFSPlusExtentRecord extents,
@@ -215,6 +211,7 @@ OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb,
 
        vcb->vcbSigWord                 = SWAP_BE16 (mdb->drSigWord);
        vcb->vcbCrDate                  = LocalToUTC (SWAP_BE32 (mdb->drCrDate));
+       vcb->localCreateDate    = SWAP_BE32 (mdb->drCrDate);
        vcb->vcbLsMod                   = LocalToUTC (SWAP_BE32 (mdb->drLsMod));
        vcb->vcbAtrb                    = SWAP_BE16 (mdb->drAtrb);
        vcb->vcbNmFls                   = SWAP_BE16 (mdb->drNmFls);
@@ -227,7 +224,6 @@ OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb,
        vcb->vcbNxtCNID                 = SWAP_BE32 (mdb->drNxtCNID);
        vcb->freeBlocks                 = SWAP_BE16 (mdb->drFreeBks);
        vcb->vcbVolBkUp                 = LocalToUTC (SWAP_BE32 (mdb->drVolBkUp));
-       vcb->vcbVSeqNum                 = SWAP_BE16 (mdb->drVSeqNum);
        vcb->vcbWrCnt                   = SWAP_BE32 (mdb->drWrCnt);
        vcb->vcbNmRtDirs                = SWAP_BE16 (mdb->drNmRtDirs);
        vcb->vcbFilCnt                  = SWAP_BE32 (mdb->drFilCnt);
@@ -256,6 +252,7 @@ OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb,
     ReturnIfError( err );
 
     hfsmp->hfs_logBlockSize = BestBlockSizeFit(vcb->blockSize, MAXBSIZE, hfsmp->hfs_phys_block_size);
+       vcb->vcbVBMIOSize = kHFSBlockSize;
 
     // XXX PPD: Should check here for hardware lock flag and set flags in VCB/MP appropriately
        VCB_LOCK_INIT(vcb);
@@ -263,7 +260,7 @@ OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb,
        /*
         * Set up Extents B-tree vnode...
         */ 
-       err = GetInitializedVNode(hfsmp, &tmpvnode, 0);
+       err = GetInitializedVNode(hfsmp, &tmpvnode);
        if (err) goto MtVolErr;
     /* HFSToHFSPlusExtents(mdb->drXTExtRec, extents); */ /* ASDFADSFSD */
        extents[0].startBlock = SWAP_BE16 (mdb->drXTExtRec[0].startBlock);
@@ -280,7 +277,7 @@ OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb,
        /*
         * Set up Catalog B-tree vnode...
         */ 
-       err = GetInitializedVNode(hfsmp, &tmpvnode, 0);
+       err = GetInitializedVNode(hfsmp, &tmpvnode);
        if (err) goto MtVolErr;
     /* HFSToHFSPlusExtents(mdb->drCTExtRec, extents); */
        extents[0].startBlock = SWAP_BE16 (mdb->drCTExtRec[0].startBlock);
@@ -399,6 +396,7 @@ OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
     /* Update the logical block size in the mount struct (currently set up from the wrapper MDB)
        using the new blocksize value: */
     hfsmp->hfs_logBlockSize = BestBlockSizeFit(vcb->blockSize, MAXBSIZE, hfsmp->hfs_phys_block_size);
+       vcb->vcbVBMIOSize = min(vcb->blockSize, MAXPHYSIO);
 
     // XXX PPD: Should check here for hardware lock flag and set flags in VCB/MP appropriately
     // vcb->vcbAtrb |= kVolumeHardwareLockMask;        // XXX this line for debugging only!!!!
@@ -410,7 +408,7 @@ OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
        /*
         * Set up Extents B-tree vnode...
         */ 
-       retval = GetInitializedVNode(hfsmp, &tmpvnode, 0);
+       retval = GetInitializedVNode(hfsmp, &tmpvnode);
        if (retval) goto ErrorExit;
     fdp = &vhp->extentsFile;
     SWAP_HFS_PLUS_FORK_DATA (fdp);
@@ -422,7 +420,7 @@ OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
        /*
         * Set up Catalog B-tree vnode...
         */ 
-       retval = GetInitializedVNode(hfsmp, &tmpvnode, 0);
+       retval = GetInitializedVNode(hfsmp, &tmpvnode);
        if (retval) goto ErrorExit;
        fdp = &vhp->catalogFile;
     SWAP_HFS_PLUS_FORK_DATA (fdp);
@@ -434,7 +432,7 @@ OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
        /*
         * Set up Allocation file vnode...
         */  
-       retval = GetInitializedVNode(hfsmp, &tmpvnode, 0);
+       retval = GetInitializedVNode(hfsmp, &tmpvnode);
        if (retval) goto ErrorExit;
        fdp = &vhp->allocationFile;
     SWAP_HFS_PLUS_FORK_DATA (fdp);
@@ -613,6 +611,59 @@ short hfsUnmount( register struct hfsmount *hfsmp, struct proc *p)
 }
 
 
+/*
+ * hfs_resolvelink - auto resolve HFS+ hardlinks
+ *
+ * Used after calling GetCatalogNode or GetCatalogOffspring
+ */
+void hfs_resolvelink(ExtendedVCB *vcb, CatalogNodeData *cndp)
+{
+       struct FInfo *fip;
+       char iNodeName[32];
+       UInt32 hint;
+       UInt32 indlinkno;
+       UInt32 linkparid, linkcnid;
+       OSErr result;
+
+       fip = (struct FInfo *) &cndp->cnd_finderInfo;
+
+       /*
+        * if this is an indirect link (hardlink) then auto resolve it...
+        */
+       if ((vcb->vcbSigWord == kHFSPlusSigWord)
+               && (cndp->cnd_type == kCatalogFileNode)
+           && (fip->fdType == kHardLinkFileType)
+           && (fip->fdCreator == kHFSPlusCreator)
+           && ((cndp->cnd_createDate == vcb->vcbCrDate) ||
+                       (cndp->cnd_createDate == VCBTOHFS(vcb)->hfs_metadata_createdate))) {
+               
+               indlinkno = cndp->cnd_iNodeNum;
+               MAKE_INODE_NAME(iNodeName, indlinkno);
+               /*
+                * Get nodeData from the data node file. 
+                * Flag the node data to NOT copy the name (ie preserve the original)
+                * Also preserve the parent directory ID.
+                */
+               linkparid = cndp->cnm_parID;
+               linkcnid = cndp->cnd_nodeID;
+               cndp->cnm_flags |= kCatNameNoCopyName;
+               result = GetCatalogNode(vcb, VCBTOHFS(vcb)->hfs_private_metadata_dir,
+                               iNodeName, 0, 0, cndp, &hint);
+               cndp->cnm_flags &= ~kCatNameNoCopyName;
+
+               /* Make sure there's a reference */
+               if (result == 0) {
+                       if (cndp->cnd_linkCount == 0) cndp->cnd_linkCount = 2;
+                       
+                       /* Keep a copy of iNodeNum to put into h_indnodeno */
+                       cndp->cnd_iNodeNumCopy = indlinkno;
+                       cndp->cnm_parID = linkparid;
+                       cndp->cnd_linkCNID = linkcnid;
+               }
+       }
+}
+
+
 /*
  * Performs a lookup on the given dirID, name. Returns the catalog info
  *
@@ -623,7 +674,6 @@ short hfs_getcatalog (ExtendedVCB *vcb, UInt32 parentDirID, char *name, short le
 {
        OSErr result;
     UInt32             length;
-       struct FInfo *fip;
        
     if (len == -1 )    {               /* Convert it to MacOS terms */
         if (name)
@@ -642,56 +692,8 @@ short hfs_getcatalog (ExtendedVCB *vcb, UInt32 parentDirID, char *name, short le
        }
 #endif
 
-#if HFS_HARDLINKS
-       if (result)
-               goto exit;
-
-       fip = (struct FInfo *) &catInfo->nodeData.cnd_finderInfo;
-
-       /*
-        * if we encounter an indirect link (hardlink) then auto resolve it...
-        */
-       if ((catInfo->nodeData.cnd_type == kCatalogFileNode)   &&
-           (fip->fdType == kHardLinkFileType)                 &&
-           (fip->fdCreator == kHFSPlusCreator)                &&
-           ((catInfo->nodeData.cnd_createDate == vcb->vcbCrDate) ||
-           (catInfo->nodeData.cnd_createDate == VCBTOHFS(vcb)->hfs_metadata_createdate))) {
-
-               u_int32_t indlinkno;
-               char iNodeName[32];
-               UInt32 privDir = VCBTOHFS(vcb)->hfs_private_metadata_dir;
-               
-               indlinkno = catInfo->nodeData.cnd_iNodeNum;
-               MAKE_INODE_NAME(iNodeName, indlinkno);
-
-               /*
-                * Get nodeData from the data node file. 
-                * Flag the node data to NOT copy the name, perserver the original
-                */
-               catInfo->nodeData.cnm_flags |= kCatNameNoCopyName;
-               result = GetCatalogNode(vcb, privDir, iNodeName, 0, 0, &catInfo->nodeData, &catInfo->hint);
-               catInfo->nodeData.cnm_flags &= ~kCatNameNoCopyName;             /* Just to keep things like they should be */
-
-               /* make sure there's at lease 1 reference */
-               if (result == 0) {
-                       if (catInfo->nodeData.cnd_linkCount == 0)
-                               catInfo->nodeData.cnd_linkCount = 2;
-                       /* keep a copy of iNodeNum to put into h_indnodeno */
-                       catInfo->nodeData.cnd_iNodeNumCopy = indlinkno;
-               }
-               
-               /* if we can not resolve the link, allow the link to be
-                * exposed (as an empty file) so it can be deleted
-                */
-               if (result == cmNotFound)
-                       result = 0;
-       }
-
-exit:
-#endif
-
-       if (result)
-               DBG_ERR(("on Lookup, GetCatalogNode returned: %d: dirid: %ld name: %s\n", result, parentDirID, name));
+       if (result == 0)
+               hfs_resolvelink(vcb, &catInfo->nodeData);
 
        return MacToVFSError(result);
 }
@@ -724,7 +726,7 @@ short hfsMoveRename (ExtendedVCB *vcb, UInt32 oldDirID, char *oldName, UInt32 ne
 {
     OSErr result = noErr;
 
-    result = MoveRenameCatalogNode(vcb, oldDirID,oldName, *hint, newDirID, newName, hint);
+    result = MoveRenameCatalogNode(vcb, oldDirID,oldName, *hint, newDirID, newName, hint, 0);
 
     if (result)
         DBG_ERR(("on hfsMoveRename, MoveRenameCatalogNode returned: %d: newdirid: %ld newname: %s\n", result, newDirID, newName));
@@ -736,7 +738,7 @@ short hfsMoveRename (ExtendedVCB *vcb, UInt32 oldDirID, char *oldName, UInt32 ne
 /* XXX SER pass back the hint so other people can use it */
 
 
-short hfsCreate(ExtendedVCB *vcb, UInt32 dirID, char *name, int        mode)
+short hfsCreate(ExtendedVCB *vcb, UInt32 dirID, char *name, int        mode, UInt32 tehint)
 {
     OSErr                              result = noErr;
     HFSCatalogNodeID   catalogNodeID;
@@ -749,7 +751,7 @@ short hfsCreate(ExtendedVCB *vcb, UInt32 dirID, char *name, int     mode)
        else
                type = kCatalogFileNode;
 
-    result = CreateCatalogNode (vcb, dirID, name, type, &catalogNodeID, &catalogHint);
+    result = CreateCatalogNode (vcb, dirID, name, type, &catalogNodeID, &catalogHint, tehint);
  
     return MacToVFSError(result);
 }
@@ -771,83 +773,23 @@ int hfs_vget_catinfo(struct vnode *parent_vp, struct hfsCatalogInfo *catInfo, u_
 {
        int             retval = E_NONE;
 
-
+    if (forkType == kDefault) {
+        if (catInfo->nodeData.cnd_type == kCatalogFolderNode)
+            forkType = kDirectory;
+        else
+            forkType = kDataFork;
+    }
+    
        *target_vp = hfs_vhashget(H_DEV(VTOH(parent_vp)), catInfo->nodeData.cnd_nodeID, forkType);
 
-       if (*target_vp == NULL) {
-               if (forkType == kAnyFork)
-                       if (catInfo->nodeData.cnd_type == kCatalogFolderNode) 
-                               forkType = kDirectory;
-                       else
-                               forkType = kDataFork;
-               
+       if (*target_vp == NULL)
                retval = hfs_vcreate( VTOVCB(parent_vp), catInfo, forkType, target_vp);
-       };
 
        return (retval);
 }
 
 
 
-/********************************************************************************/
-/*                                                                                                                                                             */
-/*     hfs_vget_fork - Returns a vnode derived from a sibling                                          */
-/*             vp is locked                                                                                                                    */
-/*                                                                                                                                                             */
-/********************************************************************************/
-
-int hfs_vget_sibling(struct vnode *vp, u_int16_t forkType, struct vnode **vpp)
-{
-    struct vnode       * target_vp = NULL;
-    int                                retval = E_NONE;
-
-
-    DBG_ASSERT(vp != NULL);
-    DBG_ASSERT(VTOH(vp) != NULL);
-    DBG_ASSERT(VTOH(vp)->h_meta != NULL);
-    DBG_ASSERT(forkType==kDataFork || forkType==kRsrcFork);
-
-    target_vp = hfs_vhashget(H_DEV(VTOH(vp)), H_FILEID(VTOH(vp)), forkType);
-    
-       /* 
-        * If not in the hash, then we have to create it 
-        */
-       if (target_vp == NULL) {
-               struct proc *p = current_proc();
-               hfsCatalogInfo catInfo;
-
-               INIT_CATALOGDATA(&catInfo.nodeData, 0);
-               catInfo.hint = H_HINT(VTOH(vp));
-
-               /* lock catalog b-tree */
-               retval = hfs_metafilelocking(VTOHFS(vp), kHFSCatalogFileID, LK_SHARED, p);
-               if (retval) goto GetCatErr_Exit;
-               
-               retval = hfs_getcatalog (VTOVCB(vp), H_DIRID(VTOH(vp)), H_NAME(VTOH(vp)), VTOH(vp)->h_meta->h_namelen, &catInfo);
-               
-               /* unlock catalog b-tree */
-               (void) hfs_metafilelocking(VTOHFS(vp), kHFSCatalogFileID, LK_RELEASE, p);
-               if (retval)  goto GetCatErr_Exit;
-       
-               retval = hfs_vcreate( VTOVCB(vp), &catInfo, forkType, &target_vp);
-
-GetCatErr_Exit:
-               CLEAN_CATALOGDATA(&catInfo.nodeData);
-       };
-
-Err_Exit:
-
-       if (!retval) {
-               DBG_ASSERT(target_vp!=NULL);
-       } else {
-               DBG_ASSERT(target_vp==NULL);
-       }
-       
-       *vpp = target_vp;
-    return (retval);
-}
-
-
 /************************************************************************/
 /*     hfs_vcreate - Returns a vnode derived from hfs                                                  */
 /*                                                                                                                                             */
@@ -870,18 +812,6 @@ short hfs_vcreate(ExtendedVCB *vcb, hfsCatalogInfo *catInfo, UInt8 forkType, str
        dev_t                           dev;
        short                           retval;
 
-#if HFS_DIAGNOSTIC
-       DBG_ASSERT(vcb != NULL);
-       DBG_ASSERT(catInfo != NULL);
-       DBG_ASSERT(vpp != NULL);
-       DBG_ASSERT((forkType == kDirectory) || (forkType == kDataFork) || (forkType == kRsrcFork));
-       if (catInfo->nodeData.cnd_type == kCatalogFolderNode) {
-                       DBG_ASSERT(forkType == kDirectory);
-       } else {
-                       DBG_ASSERT(forkType != kDirectory);
-       }
-#endif
-
        hfsmp   = VCBTOHFS(vcb);
        mp              = HFSTOVFS(hfsmp);
        dev             = hfsmp->hfs_raw_dev;
@@ -891,48 +821,78 @@ short hfs_vcreate(ExtendedVCB *vcb, hfsCatalogInfo *catInfo, UInt8 forkType, str
                *vpp = NULL;
                return (EPERM);
        }
-       DBG_UTILS(("\thfs_vcreate: On '%s' with forktype of %d, nodeType of 0x%08lX\n", catInfo->nodeData.cnm_nameptr, forkType, (unsigned long)catInfo->nodeData.cnd_type));
-       
-       /* Must malloc() here, since getnewvnode() can sleep */
-       MALLOC_ZONE(hp, struct hfsnode *, sizeof(struct hfsnode), M_HFSNODE, M_WAITOK);
-       bzero((caddr_t)hp, sizeof(struct hfsnode));
-       
+
        /*
-        * Set that this node is in the process of being allocated
-        * Set it as soon as possible, so context switches well always hit upon it.
-        * if this is set then wakeup() MUST be called on hp after the flag is cleared
-        * DO NOT exit without clearing and waking up !!!!
+        * If this is a hard link then check if the
+        * data node already exists in our hash.
         */
-       hp->h_nodeflags |= IN_ALLOCATING;                               /* Mark this as being allocating */
-       lockinit(&hp->h_lock, PINOD, "hfsnode", 0, 0);
-
+       if ((forkType == kDataFork)
+               && (catInfo->nodeData.cnd_type == kCatalogFileNode)
+               && ((catInfo->nodeData.cnd_mode & IFMT) == IFREG)
+               && (catInfo->nodeData.cnd_linkCount > 0)) {
+               vp = hfs_vhashget(dev, catInfo->nodeData.cnd_nodeID, kDataFork);
+               if (vp != NULL) {
+                       /* Use the name of the link and it's parent ID. */
+                       hp = VTOH(vp);
+                       H_DIRID(hp) = catInfo->nodeData.cnm_parID;
+                       hfs_set_metaname(catInfo->nodeData.cnm_nameptr, hp->h_meta, hfsmp);
+                       *vpp = vp;
+                       return (0);
+               }
+       }
 
-       /* getnewvnode() does a VREF() on the vnode */
-       /* Allocate a new vnode. If unsuccesful, leave after freeing memory */
-       if ((retval = getnewvnode(VT_HFS, mp, hfs_vnodeop_p, &vp))) {
-               wakeup(hp);                             /* Shouldnt happen, but just to make sure */
-               FREE_ZONE(hp, sizeof(struct hfsnode), M_HFSNODE);
-               *vpp = NULL;
-               return (retval);
-       };
+       MALLOC_ZONE(hp, struct hfsnode *, sizeof(struct hfsnode), M_HFSNODE, M_WAITOK);
+       bzero((caddr_t)hp, sizeof(struct hfsnode));
+       hp->h_nodeflags |= IN_ALLOCATING;
+       lockinit(&hp->h_lock, PINOD, "hfsnode", 0, 0);
+       H_FORKTYPE(hp) = forkType;
+       rl_init(&hp->h_invalidranges);
 
        /*
-        * Set the essentials before locking it down
+        * There were several blocking points since we first
+        * checked the hash. Now that we're through blocking,
+        * check the hash again in case we're racing for the
+        * same hnode.
         */
-       hp->h_vp = vp;                                                                  /* Make HFSTOV work */
-       vp->v_data = hp;                                                                /* Make VTOH work */
-       H_FORKTYPE(hp) = forkType;
-       fm = NULL;
-       
+       vp = hfs_vhashget(dev, catInfo->nodeData.cnd_nodeID, forkType);
+       if (vp != NULL) {
+               /* We lost the race, use the winner's vnode */
+               FREE_ZONE(hp, sizeof(struct hfsnode), M_HFSNODE);
+               *vpp = vp;
+               UBCINFOCHECK("hfs_vcreate", vp);
+               return (0);
+       }
+
        /*
-        * Lock the hfsnode and insert the hfsnode into the hash queue, also if meta exists
+        * Insert the hfsnode into the hash queue, also if meta exists
         * add to sibling list and return the meta address
         */
+       fm = NULL;
        if  (SIBLING_FORKTYPE(forkType))
                hfs_vhashins_sibling(dev, catInfo->nodeData.cnd_nodeID, hp, &fm);
        else
                hfs_vhashins(dev, catInfo->nodeData.cnd_nodeID, hp);
 
+       /* Allocate a new vnode. If unsuccesful, leave after freeing memory */
+       if ((retval = getnewvnode(VT_HFS, mp, hfs_vnodeop_p, &vp))) {
+               hfs_vhashrem(hp);
+               if (hp->h_nodeflags & IN_WANT) {
+                       hp->h_nodeflags &= ~IN_WANT;
+                       wakeup(hp);
+               }
+               FREE_ZONE(hp, sizeof(struct hfsnode), M_HFSNODE);
+               *vpp = NULL;
+               return (retval);
+       }
+       hp->h_vp = vp;
+       vp->v_data = hp;
+
+       hp->h_nodeflags &= ~IN_ALLOCATING;
+       if (hp->h_nodeflags & IN_WANT) {
+               hp->h_nodeflags &= ~IN_WANT;
+               wakeup((caddr_t)hp);
+       }
+
        /*
         * If needed allocate and init the object meta data:
         */
@@ -966,7 +926,6 @@ short hfs_vcreate(ExtendedVCB *vcb, hfsCatalogInfo *catInfo, UInt8 forkType, str
        };
        fm->h_usecount++;
 
-
        /*
         * Init the File Control Block.
         */
@@ -986,48 +945,24 @@ short hfs_vcreate(ExtendedVCB *vcb, hfsCatalogInfo *catInfo, UInt8 forkType, str
                ubc_info_init(vp);
        }
 
-    /*
+       /*
         * Initialize the vnode from the inode, check for aliases, sets the VROOT flag.
         * Note that the underlying vnode may have changed.
         */
        if ((retval = hfs_vinit(mp, hfs_specop_p, hfs_fifoop_p, &vp))) {
-               wakeup((caddr_t)hp);
                vput(vp);
                *vpp = NULL;
                return (retval);
        }
 
-    /*
-     * Finish inode initialization now that aliasing has been resolved.
-     */
-    hp->h_meta->h_devvp = hfsmp->hfs_devvp;
-    VREF(hp->h_meta->h_devvp);
+       /*
+        * Finish inode initialization now that aliasing has been resolved.
+        */
+       hp->h_meta->h_devvp = hfsmp->hfs_devvp;
+       VREF(hp->h_meta->h_devvp);
     
-#if HFS_DIAGNOSTIC
-       hp->h_valid = HFS_VNODE_MAGIC;
-#endif
-       hp->h_nodeflags &= ~IN_ALLOCATING;                              /* vnode is completely initialized */
-
-       /* Wake up anybody waiting for us to finish..see hfs_vhash.c */
-       wakeup((caddr_t)hp);
-
-#if HFS_DIAGNOSTIC
-
-       /* Lets do some testing here */
-       DBG_ASSERT(hp->h_meta);
-       DBG_ASSERT(VTOH(vp)==hp);
-       DBG_ASSERT(HTOV(hp)==vp);
-       DBG_ASSERT(hp->h_meta->h_usecount>=1 && hp->h_meta->h_usecount<=2);
-       if (catInfo->nodeData.cnd_type == kCatalogFolderNode) {
-               DBG_ASSERT(vp->v_type == VDIR);
-               DBG_ASSERT(H_FORKTYPE(VTOH(vp)) == kDirectory);
-       }
-#endif // HFS_DIAGNOSTIC
-
-
        *vpp = vp;
        return 0;
-
 }
 
 void CopyCatalogToObjectMeta(struct hfsCatalogInfo *catalogInfo, struct vnode *vp, struct hfsfilemeta *fm)
@@ -1345,7 +1280,9 @@ int hfs_metafilelocking(struct hfsmount *hfsmp, u_long fileID, u_int flags, stru
  *
  * 1. (a) Your UID matches the UID of the vnode
  *    (b) The object in question is owned by "unknown" and your UID matches the console user's UID
- * 2. Permissions on the filesystem are being ignored and your UID matches the replacement UID
+ * 2. (a) Permissions on the filesystem are being ignored and your UID matches the replacement UID
+ *    (b) Permissions on the filesystem are being ignored and the replacement UID is "unknown" and
+ *        your UID matches the console user UID
  * 3. You are root
  *
  */
@@ -1353,7 +1290,8 @@ int hfs_owner_rights(struct vnode *vp, struct ucred *cred, struct proc *p, Boole
     return ((cred->cr_uid == VTOH(vp)->h_meta->h_uid) ||                                                                               /* [1a] */
                ((VTOH(vp)->h_meta->h_uid == UNKNOWNUID) && (cred->cr_uid == console_user)) ||          /* [1b] */
                ((VTOVFS(vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) &&                                                                     /* [2] */
-                (cred->cr_uid == VTOHFS(vp)->hfs_uid)) ||                                                                                      /* [2] */
+                ((cred->cr_uid == VTOHFS(vp)->hfs_uid) ||                                                                                      /* [2a] */
+                 ((VTOHFS(vp)->hfs_uid == UNKNOWNUID) && (cred->cr_uid == console_user)))) ||          /* [2b] */
                (invokesuperuserstatus && (suser(cred, &p->p_acflag) == 0))) ? 0 : EPERM;
 }
 
@@ -1361,9 +1299,10 @@ int hfs_owner_rights(struct vnode *vp, struct ucred *cred, struct proc *p, Boole
 
 int hfs_catalogentry_owner_rights(uid_t obj_uid, struct mount *mp, struct ucred *cred, struct proc *p, Boolean invokesuperuserstatus) {
     return ((cred->cr_uid == obj_uid) ||                                                                                                               /* [1a] */
-               ((VFSTOHFS(mp)->hfs_uid == UNKNOWNUID) && (cred->cr_uid == console_user)) ||            /* [1b] */
+               ((obj_uid == UNKNOWNUID) && (cred->cr_uid == console_user)) ||                                          /* [1b] */
                ((mp->mnt_flag & MNT_UNKNOWNPERMISSIONS) &&                                                                                     /* [2] */
-                (cred->cr_uid == VFSTOHFS(mp)->hfs_uid)) ||                                                                            /* [2] */
+                ((cred->cr_uid == VFSTOHFS(mp)->hfs_uid) ||                                                                            /* [2a] */
+                 ((VFSTOHFS(mp)->hfs_uid == UNKNOWNUID) && (cred->cr_uid == console_user)))) ||        /* [2b] */
                (invokesuperuserstatus && (suser(cred, &p->p_acflag) == 0))) ? 0 : EPERM;
 }
 
@@ -1376,6 +1315,7 @@ void CopyVNodeToCatalogNode (struct vnode *vp, struct CatalogNodeData *nodeData)
     struct hfsnode                     *hp;
     Boolean                                    isHFSPlus, isResource;
     HFSPlusExtentDescriptor    *extents;
+    off_t                                      fileReadLimit;
 
     hp = VTOH(vp);
     vcb = HTOVCB(hp);
@@ -1423,13 +1363,18 @@ void CopyVNodeToCatalogNode (struct vnode *vp, struct CatalogNodeData *nodeData)
                        /* The file is unlocked: make sure the locked bit in the catalog is clear. */
                        nodeData->cnd_flags &= ~kHFSFileLockedMask;
                };
+               if (CIRCLEQ_EMPTY(&hp->h_invalidranges)) {
+                       fileReadLimit = fcb->fcbEOF;
+               } else {
+                       fileReadLimit = CIRCLEQ_FIRST(&hp->h_invalidranges)->rl_start;
+               };
                if (isResource) {
                        extents = nodeData->cnd_rsrcfork.extents;
-                       nodeData->cnd_rsrcfork.logicalSize = fcb->fcbEOF;
+                       nodeData->cnd_rsrcfork.logicalSize = fileReadLimit;
                        nodeData->cnd_rsrcfork.totalBlocks = fcb->fcbPLen / vcb->blockSize;
                } else {
                        extents = nodeData->cnd_datafork.extents;
-                       nodeData->cnd_datafork.logicalSize = fcb->fcbEOF;
+                       nodeData->cnd_datafork.logicalSize = fileReadLimit;
                        nodeData->cnd_datafork.totalBlocks = fcb->fcbPLen / vcb->blockSize;
                };
 
@@ -1870,7 +1815,7 @@ void PackVolCommonAttributes(struct attrlist *alist,
         if (a & ATTR_CMN_SCRIPT) *((text_encoding_t *)attrbufptr)++ = vcb->volumeNameEncodingHint;
                /* NOTE: all VCB dates are in Mac OS time */
                if (a & ATTR_CMN_CRTIME) {
-                       ((struct timespec *)attrbufptr)->tv_sec = to_bsd_time(LocalToUTC(vcb->localCreateDate));
+                       ((struct timespec *)attrbufptr)->tv_sec = to_bsd_time(vcb->vcbCrDate);
                        ((struct timespec *)attrbufptr)->tv_nsec = 0;
                        ++((struct timespec *)attrbufptr);
                };
@@ -2020,17 +1965,22 @@ void PackVolAttributeBlock(struct attrlist *alist,
         };
         if (a & ATTR_VOL_ENCODINGSUSED) *((unsigned long long *)attrbufptr)++ = (unsigned long long)vcb->encodingsBitmap;
         if (a & ATTR_VOL_CAPABILITIES) {
-               ((vol_capabilities_attr_t *)attrbufptr)->capabilities[VOL_CAPABILITIES_FORMAT] =
-                               VOL_CAP_FMT_PERSISTENTOBJECTIDS | VOL_CAP_FMT_SYMBOLICLINKS | VOL_CAP_FMT_HARDLINKS;
+               if (vcb->vcbSigWord == kHFSPlusSigWord) {
+                   ((vol_capabilities_attr_t *)attrbufptr)->capabilities[VOL_CAPABILITIES_FORMAT] =
+                   VOL_CAP_FMT_PERSISTENTOBJECTIDS | VOL_CAP_FMT_SYMBOLICLINKS | VOL_CAP_FMT_HARDLINKS;
+               } else { /* Plain HFS */
+                   ((vol_capabilities_attr_t *)attrbufptr)->capabilities[VOL_CAPABILITIES_FORMAT] =
+                   VOL_CAP_FMT_PERSISTENTOBJECTIDS;
+               }
                ((vol_capabilities_attr_t *)attrbufptr)->capabilities[VOL_CAPABILITIES_INTERFACES] =
-                               VOL_CAP_INT_SEARCHFS | VOL_CAP_INT_ATTRLIST | VOL_CAP_INT_NFSEXPORT;
+                               VOL_CAP_INT_SEARCHFS | VOL_CAP_INT_ATTRLIST | VOL_CAP_INT_NFSEXPORT | VOL_CAP_INT_READDIRATTR;
                ((vol_capabilities_attr_t *)attrbufptr)->capabilities[VOL_CAPABILITIES_RESERVED1] = 0;
                ((vol_capabilities_attr_t *)attrbufptr)->capabilities[VOL_CAPABILITIES_RESERVED2] = 0;
 
                ((vol_capabilities_attr_t *)attrbufptr)->valid[VOL_CAPABILITIES_FORMAT] =
                                VOL_CAP_FMT_PERSISTENTOBJECTIDS | VOL_CAP_FMT_SYMBOLICLINKS | VOL_CAP_FMT_HARDLINKS;
                ((vol_capabilities_attr_t *)attrbufptr)->valid[VOL_CAPABILITIES_INTERFACES] =
-                               VOL_CAP_INT_SEARCHFS | VOL_CAP_INT_ATTRLIST | VOL_CAP_INT_NFSEXPORT;
+                               VOL_CAP_INT_SEARCHFS | VOL_CAP_INT_ATTRLIST | VOL_CAP_INT_NFSEXPORT | VOL_CAP_INT_READDIRATTR;
                ((vol_capabilities_attr_t *)attrbufptr)->valid[VOL_CAPABILITIES_RESERVED1] = 0;
                ((vol_capabilities_attr_t *)attrbufptr)->valid[VOL_CAPABILITIES_RESERVED2] = 0;
 
@@ -2083,10 +2033,12 @@ void PackCommonCatalogInfoAttributeBlock(struct attrlist                *alist,
        void                    *varbufptr;
        attrgroup_t             a;
        u_long                  attrlength;
+       Boolean                 isHFSPlus;
        
        hp                      = VTOH(root_vp);
        attrbufptr      = *attrbufptrptr;
        varbufptr       = *varbufptrptr;
+       isHFSPlus = (VTOVCB(root_vp)->vcbSigWord == kHFSPlusSigWord);
        
        if ((a = alist->commonattr) != 0)
        {
@@ -2131,15 +2083,27 @@ void PackCommonCatalogInfoAttributeBlock(struct attrlist                *alist,
                        };
                }
                if (a & ATTR_CMN_OBJTAG) *((fsobj_tag_t *)attrbufptr)++ = root_vp->v_tag;
-        if (a & ATTR_CMN_OBJID)
-        {
-            ((fsobj_id_t *)attrbufptr)->fid_objno = catalogInfo->nodeData.cnd_nodeID;
+        if (a & ATTR_CMN_OBJID) {
+            u_int32_t cnid;
+            /* For hard links use the link's cnid */
+            if (catalogInfo->nodeData.cnd_iNodeNumCopy != 0)
+                               cnid = catalogInfo->nodeData.cnd_linkCNID;
+            else
+                               cnid = catalogInfo->nodeData.cnd_nodeID;
+            ((fsobj_id_t *)attrbufptr)->fid_objno = cnid;
             ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
             ++((fsobj_id_t *)attrbufptr);
         };
-        if (a & ATTR_CMN_OBJPERMANENTID)
-        {
-            ((fsobj_id_t *)attrbufptr)->fid_objno = catalogInfo->nodeData.cnd_nodeID;
+        if (a & ATTR_CMN_OBJPERMANENTID) {
+            u_int32_t cnid;
+            /* For hard links use the link's cnid */
+            if (catalogInfo->nodeData.cnd_iNodeNumCopy != 0)
+                               cnid = catalogInfo->nodeData.cnd_linkCNID;
+                       else
+                               cnid = catalogInfo->nodeData.cnd_nodeID;
+            ((fsobj_id_t *)attrbufptr)->fid_objno = cnid;
             ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
             ++((fsobj_id_t *)attrbufptr);
         };
@@ -2193,7 +2157,8 @@ void PackCommonCatalogInfoAttributeBlock(struct attrlist          *alist,
                        (char *)attrbufptr += sizeof(catalogInfo->nodeData.cnd_finderInfo);
                };
                if (a & ATTR_CMN_OWNERID) {
-                       if (VTOVFS(root_vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) {
+                       if ((VTOVFS(root_vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) ||
+                               ((catalogInfo->nodeData.cnd_mode & IFMT) == 0)) {
                                *((uid_t *)attrbufptr)++ =
                                        (VTOHFS(root_vp)->hfs_uid == UNKNOWNUID) ? console_user : VTOHFS(root_vp)->hfs_uid;
                        } else {
@@ -2202,34 +2167,37 @@ void PackCommonCatalogInfoAttributeBlock(struct attrlist                *alist,
                        };
                }
                if (a & ATTR_CMN_GRPID) {
-                       if (VTOVFS(root_vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) {
+                       if ((VTOVFS(root_vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) ||
+                               ((catalogInfo->nodeData.cnd_mode & IFMT) == 0)) {
                                *((gid_t *)attrbufptr)++ = VTOHFS(root_vp)->hfs_gid;
                        } else {
                                *((gid_t *)attrbufptr)++ = catalogInfo->nodeData.cnd_groupID;
                        };
                }
                if (a & ATTR_CMN_ACCESSMASK) {
+                       if (((catalogInfo->nodeData.cnd_mode & IFMT) == 0)
 #if OVERRIDE_UNKNOWN_PERMISSIONS
-                       if (VTOVFS(root_vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) {
+                               || (VTOVFS(root_vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS)
+#endif
+                               ) {
                                switch (catalogInfo->nodeData.cnd_type) {
                                  case kCatalogFileNode:
                                        /* Files in an HFS+ catalog can represent many things (regular files, symlinks, block/character devices, ...) */
-                                       *((fsobj_type_t *)attrbufptr)++ = (u_long)(VTOHFS(root_vp)->hfs_file_mask);
+                                       *((u_long *)attrbufptr)++ = (u_long)(IFREG | (ACCESSPERMS & (u_long)(VTOHFS(root_vp)->hfs_file_mask)));
                                        break;
                                        
                                  case kCatalogFolderNode:
-                                       /* Fall through to default case */
+                                       *((u_long *)attrbufptr)++ = (u_long)(IFDIR | (ACCESSPERMS & (u_long)(VTOHFS(root_vp)->hfs_dir_mask)));
+                                       break;
                                  
                                  default:
-                                       *((u_long *)attrbufptr)++ = (u_long)(VTOHFS(root_vp)->hfs_dir_mask);
+                                       *((u_long *)attrbufptr)++ = (u_long)((catalogInfo->nodeData.cnd_mode & IFMT) |
+                                                                                                                VTOHFS(root_vp)->hfs_dir_mask);
                                };
                        } else {
-#endif
                                *((u_long *)attrbufptr)++ =
                                    (u_long)catalogInfo->nodeData.cnd_mode;
-#if OVERRIDE_UNKNOWN_PERMISSIONS
                        };
-#endif
                }
                if (a & ATTR_CMN_NAMEDATTRCOUNT) *((u_long *)attrbufptr)++ = 0;                 /* XXX PPD TBC */
                if (a & ATTR_CMN_NAMEDATTRLIST)
@@ -2242,16 +2210,38 @@ void PackCommonCatalogInfoAttributeBlock(struct attrlist                *alist,
                        (char *)varbufptr += attrlength + ((4 - (attrlength & 3)) & 3);
                        ++((struct attrreference *)attrbufptr);
                };
-        if (a & ATTR_CMN_FLAGS)
-               *((u_long *)attrbufptr)++ =
-                       (u_long) (catalogInfo->nodeData.cnd_ownerFlags |
-                                (catalogInfo->nodeData.cnd_adminFlags << 16));
+               if (a & ATTR_CMN_FLAGS) {
+                       u_long flags;
+
+                       if (catalogInfo->nodeData.cnd_mode & IFMT)
+                               flags = catalogInfo->nodeData.cnd_ownerFlags |
+                                       catalogInfo->nodeData.cnd_adminFlags << 16;
+                       else
+                               flags = 0;
+
+                       if (catalogInfo->nodeData.cnd_type == kCatalogFileNode) {
+                               if (catalogInfo->nodeData.cnd_flags & kHFSFileLockedMask)
+                                       flags |= UF_IMMUTABLE;
+                               else
+                                       flags &= ~UF_IMMUTABLE;
+                       };
+                       *((u_long *)attrbufptr)++ = flags;
+               };
                if (a & ATTR_CMN_USERACCESS) {
-                       if (VTOVFS(root_vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) {
+                       if ((VTOVFS(root_vp)->mnt_flag & MNT_UNKNOWNPERMISSIONS) ||
+                               ((catalogInfo->nodeData.cnd_mode & IFMT) == 0)) {
                                *((u_long *)attrbufptr)++ =
                                        DerivePermissionSummary((VTOHFS(root_vp)->hfs_uid == UNKNOWNUID) ? console_user : VTOHFS(root_vp)->hfs_uid,
                                                                                        VTOHFS(root_vp)->hfs_gid,
+#if OVERRIDE_UNKNOWN_PERMISSIONS
                                                                                        (catalogInfo->nodeData.cnd_type == kCatalogFileNode) ? VTOHFS(root_vp)->hfs_file_mask : VTOHFS(root_vp)->hfs_dir_mask,
+#else
+                                                                                       (catalogInfo->nodeData.cnd_mode & IFMT) ?
+                                                                                               (u_long)catalogInfo->nodeData.cnd_mode :
+                                                                                               ((catalogInfo->nodeData.cnd_type == kCatalogFileNode) ?
+                                                                                                       VTOHFS(root_vp)->hfs_file_mask :
+                                                                                                       VTOHFS(root_vp)->hfs_dir_mask),
+#endif
                                                                                        VTOVFS(root_vp),
                                                                                        current_proc()->p_ucred,
                                                                                        current_proc());
@@ -2300,12 +2290,26 @@ void PackCommonAttributeBlock(struct attrlist *alist,
                if (a & ATTR_CMN_OBJTYPE) *((fsobj_type_t *)attrbufptr)++ = vp->v_type;
                if (a & ATTR_CMN_OBJTAG) *((fsobj_tag_t *)attrbufptr)++ = vp->v_tag;
         if (a & ATTR_CMN_OBJID)        {
-            ((fsobj_id_t *)attrbufptr)->fid_objno = H_FILEID(hp);
+            u_int32_t cnid;
+
+            /* For hard links use the link's cnid */
+            if (hp->h_meta->h_metaflags & IN_DATANODE)
+                cnid = catInfo->nodeData.cnd_linkCNID;
+            else
+                cnid = H_FILEID(hp);
+            ((fsobj_id_t *)attrbufptr)->fid_objno = cnid;
                        ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
                        ++((fsobj_id_t *)attrbufptr);
                };
         if (a & ATTR_CMN_OBJPERMANENTID)       {
-            ((fsobj_id_t *)attrbufptr)->fid_objno = H_FILEID(hp);
+            u_int32_t cnid;
+
+            /* For hard links use the link's cnid */
+            if (hp->h_meta->h_metaflags & IN_DATANODE)
+                cnid = catInfo->nodeData.cnd_linkCNID;
+            else
+                cnid = H_FILEID(hp);
+            ((fsobj_id_t *)attrbufptr)->fid_objno = cnid;
             ((fsobj_id_t *)attrbufptr)->fid_generation = 0;
             ++((fsobj_id_t *)attrbufptr);
         };
@@ -2787,7 +2791,9 @@ void UnpackVolumeAttributeBlock(struct attrlist *alist,
 #endif
        };
        if (a & ATTR_CMN_CRTIME) {
-               vcb->localCreateDate = UTCToLocal(to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec));
+               vcb->vcbCrDate = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
+               /* Need to update the local time also */
+               vcb->localCreateDate = UTCToLocal(vcb->vcbCrDate);
                ++((struct timespec *)attrbufptr);
 #if HFS_DIAGNOSTIC
                a &= ~ATTR_CMN_CRTIME;
@@ -2850,6 +2856,7 @@ void UnpackCommonAttributeBlock(struct attrlist *alist,
        a = alist->commonattr;
        if (a & ATTR_CMN_SCRIPT) {
                catInfo->nodeData.cnd_textEncoding = (u_int32_t)*((text_encoding_t *)attrbufptr)++;
+               UpdateVolumeEncodings(VTOVCB(vp), catInfo->nodeData.cnd_textEncoding);          /* Update the volume encoding */
 #if HFS_DIAGNOSTIC
                a &= ~ATTR_CMN_SCRIPT;
 #endif
@@ -3140,7 +3147,7 @@ FindMetaDataDirectory(ExtendedVCB *vcb)
 
        dirID = 0;
        metadata_createdate = 0;
-       strncpy(namep, HFSPLUSMETADATAFOLDER, sizeof(namep));
+       strncpy(namep, HFSPLUS_PRIVATE_DIR, sizeof(namep));
        INIT_CATALOGDATA(&catInfo.nodeData, kCatNameNoCopyName);
        catInfo.hint = kNoHint;
 
@@ -3152,7 +3159,7 @@ FindMetaDataDirectory(ExtendedVCB *vcb)
                dirID = catInfo.nodeData.cnd_nodeID;
                metadata_createdate = catInfo.nodeData.cnd_createDate;
        } else if (VCBTOHFS(vcb)->hfs_fs_ronly == 0) {
-               if (CreateCatalogNode(vcb, kRootDirID, namep, kCatalogFolderNode, &dirID, &catInfo.hint) == 0) {
+               if (CreateCatalogNode(vcb, kRootDirID, namep, kCatalogFolderNode, &dirID, &catInfo.hint, 0) == 0) {
                        catInfo.hint = kNoHint;
                        if (hfs_getcatalog(vcb, kRootDirID, namep, -1, &catInfo) == 0) {
 
@@ -3192,7 +3199,7 @@ RemovedMetaDataDirectory(ExtendedVCB *vcb)
        hfsCatalogInfo catInfo;
        int retval;
        
-       strncpy(name, HFSPLUSMETADATAFOLDER, sizeof(name));
+       strncpy(name, HFSPLUS_PRIVATE_DIR, sizeof(name));
        INIT_CATALOGDATA(&catInfo.nodeData, kCatNameNoCopyName);
 
        /* lock catalog b-tree */
@@ -3226,26 +3233,30 @@ u_int32_t logBlockSize;
        
        DBG_ASSERT(vp != NULL);
 
-       if ((vp->v_flag & VSYSTEM) && (VTOH(vp)->fcbBTCBPtr!=NULL)) {
-               BTreeInfoRec                    bTreeInfo;
-               int retval;
+       /* start with default */
+       logBlockSize = VTOHFS(vp)->hfs_logBlockSize;
 
-               /*
-                * We do not lock the BTrees, because if we are getting block..then the tree
-                * should be locked in the first place.
-                * We just want the nodeSize wich will NEVER change..so even if the world
-                * is changing..the nodeSize should remain the same. Which argues why lock
-                * it in the first place??
-                */
-               
-               (void) BTGetInformation (VTOFCB(vp), kBTreeInfoVersion, &bTreeInfo);
-                               
-               logBlockSize = bTreeInfo.nodeSize;
+       if (vp->v_flag & VSYSTEM) {
+               if (VTOH(vp)->fcbBTCBPtr != NULL) {
+                       BTreeInfoRec                    bTreeInfo;
+       
+                       /*
+                        * We do not lock the BTrees, because if we are getting block..then the tree
+                        * should be locked in the first place.
+                        * We just want the nodeSize wich will NEVER change..so even if the world
+                        * is changing..the nodeSize should remain the same. Which argues why lock
+                        * it in the first place??
+                        */
+                       
+                       (void) BTGetInformation (VTOFCB(vp), kBTreeInfoVersion, &bTreeInfo);
+                                       
+                       logBlockSize = bTreeInfo.nodeSize;
+
+               } else if (H_FILEID(VTOH(vp)) == kHFSAllocationFileID) {
+                               logBlockSize = VTOVCB(vp)->vcbVBMIOSize;
                }
-       else
-               logBlockSize = VTOHFS(vp)->hfs_logBlockSize;
-               
-               
+       }
+
        DBG_ASSERT(logBlockSize > 0);
        
        return logBlockSize;