- VCB_LOCK(vcb);
-
- a = alist->commonattr;
-
- if (a & ATTR_CMN_SCRIPT) {
- vcb->volumeNameEncodingHint = (u_int32_t)*(((text_encoding_t *)attrbufptr)++);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_SCRIPT;
-#endif
- };
- if (a & ATTR_CMN_CRTIME) {
- vcb->localCreateDate = UTCToLocal(to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec));
- ++((struct timespec *)attrbufptr);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_CRTIME;
-#endif
- };
- if (a & ATTR_CMN_MODTIME) {
- vcb->vcbLsMod = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- ++((struct timespec *)attrbufptr);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_MODTIME;
-#endif
- };
- if (a & ATTR_CMN_BKUPTIME) {
- vcb->vcbVolBkUp = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- ++((struct timespec *)attrbufptr);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_BKUPTIME;
-#endif
- };
- if (a & ATTR_CMN_FNDRINFO) {
- bcopy (attrbufptr, &vcb->vcbFndrInfo, sizeof(vcb->vcbFndrInfo));
- (char *)attrbufptr += sizeof(vcb->vcbFndrInfo);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_FNDRINFO;
-#endif
- };
-
- DBG_ASSERT(a == 0); /* All common attributes for volumes must've been handled by now... */
-
- a = alist->volattr & ~ATTR_VOL_INFO;
- if (a & ATTR_VOL_NAME) {
- copystr(((char *)attrbufptr) + *((u_long *)attrbufptr), vcb->vcbVN, sizeof(vcb->vcbVN), NULL);
- (char *)attrbufptr += sizeof(struct attrreference);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_VOL_NAME;
-#endif
- };
-
- DBG_ASSERT(a == 0); /* All common attributes for volumes must've been handled by now... */
-
- vcb->vcbFlags |= 0xFF00; // Mark the VCB dirty
-
- VCB_UNLOCK(vcb);
-}
-
-
-void UnpackCommonAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- struct hfsnode *hp = VTOH(vp);
- void *attrbufptr;
- attrgroup_t a;
-
- attrbufptr = *attrbufptrptr;
-
- DBG_ASSERT(catInfo != NULL);
-
- a = alist->commonattr;
- if (a & ATTR_CMN_SCRIPT) {
- catInfo->nodeData.cnd_textEncoding = (u_int32_t)*((text_encoding_t *)attrbufptr)++;
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_SCRIPT;
-#endif
- };
- if (a & ATTR_CMN_CRTIME) {
- catInfo->nodeData.cnd_createDate = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- VTOH(vp)->h_meta->h_crtime = (UInt32)((struct timespec *)attrbufptr)->tv_sec;
- ++((struct timespec *)attrbufptr);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_CRTIME;
-#endif
- };
- if (a & ATTR_CMN_MODTIME) {
- catInfo->nodeData.cnd_contentModDate = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- VTOH(vp)->h_meta->h_mtime = (UInt32)((struct timespec *)attrbufptr)->tv_sec;
- ++((struct timespec *)attrbufptr);
- hp->h_nodeflags &= ~IN_UPDATE;
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_MODTIME;
-#endif
- };
- if (a & ATTR_CMN_CHGTIME) {
- catInfo->nodeData.cnd_attributeModDate = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- VTOH(vp)->h_meta->h_ctime = (UInt32)((struct timespec *)attrbufptr)->tv_sec;
- ++((struct timespec *)attrbufptr);
- hp->h_nodeflags &= ~IN_CHANGE;
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_CHGTIME;
-#endif
- };
- if (a & ATTR_CMN_ACCTIME) {
- catInfo->nodeData.cnd_accessDate = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- VTOH(vp)->h_meta->h_atime = (UInt32)((struct timespec *)attrbufptr)->tv_sec;
- ++((struct timespec *)attrbufptr);
- hp->h_nodeflags &= ~IN_ACCESS;
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_ACCTIME;
-#endif
- };
- if (a & ATTR_CMN_BKUPTIME) {
- catInfo->nodeData.cnd_backupDate = to_hfs_time((UInt32)((struct timespec *)attrbufptr)->tv_sec);
- VTOH(vp)->h_meta->h_butime = (UInt32)((struct timespec *)attrbufptr)->tv_sec;
- ++((struct timespec *)attrbufptr);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_BKUPTIME;
-#endif
- };
- if (a & ATTR_CMN_FNDRINFO) {
- bcopy (attrbufptr, &catInfo->nodeData.cnd_finderInfo, sizeof(catInfo->nodeData.cnd_finderInfo));
- (char *)attrbufptr += sizeof(catInfo->nodeData.cnd_finderInfo);
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_FNDRINFO;
-#endif
- };
- if (a & ATTR_CMN_OWNERID) {
- if (VTOVCB(vp)->vcbSigWord == kHFSPlusSigWord) {
- u_int32_t uid = (u_int32_t)*((uid_t *)attrbufptr)++;
- if (uid != (uid_t)VNOVAL)
- hp->h_meta->h_uid = uid; /* catalog will get updated by hfs_chown() */
- }
- else {
- ((uid_t *)attrbufptr)++;
- }
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_OWNERID;
-#endif
- };
- if (a & ATTR_CMN_GRPID) {
- u_int32_t gid = (u_int32_t)*((gid_t *)attrbufptr)++;
- if (VTOVCB(vp)->vcbSigWord == kHFSPlusSigWord) {
- if (gid != (gid_t)VNOVAL)
- hp->h_meta->h_gid = gid; /* catalog will get updated by hfs_chown() */
- };
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_GRPID;
-#endif
- };
- if (a & ATTR_CMN_ACCESSMASK) {
- u_int16_t mode = (u_int16_t)*((u_long *)attrbufptr)++;
- if (VTOVCB(vp)->vcbSigWord == kHFSPlusSigWord) {
- if (mode != (mode_t)VNOVAL) {
- hp->h_meta->h_mode &= ~ALLPERMS;
- hp->h_meta->h_mode |= (mode & ALLPERMS); /* catalog will get updated by hfs_chmod() */
- }
- };
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_ACCESSMASK;
-#endif
- };
- if (a & ATTR_CMN_FLAGS) {
- u_long flags = *((u_long *)attrbufptr)++;
- /* Flags are settable only on HFS+ volumes. A special exception is made for the IMMUTABLE
- flags (SF_IMMUTABLE and UF_IMMUTABLE), which can be set on HFS volumes as well: */
- if ((VTOVCB(vp)->vcbSigWord == kHFSPlusSigWord) ||
- ((VTOVCB(vp)->vcbSigWord == kHFSSigWord) && ((flags & ~IMMUTABLE) == 0))) {
- if (flags != (u_long)VNOVAL) {
- hp->h_meta->h_pflags = flags; /* catalog will get updated by hfs_chflags */
- };
- };
-#if HFS_DIAGNOSTIC
- a &= ~ATTR_CMN_FLAGS;
-#endif
- };
-
-#if HFS_DIAGNOSTIC
- if (a != 0) {
- DEBUG_BREAK_MSG(("UnpackCommonAttributes: unhandled bit: 0x%08X\n", a));
- };
-#endif
-
- *attrbufptrptr = attrbufptr;
-// *varbufptrptr = varbufptr;
-}
-
-
-
-#if 0
-void UnpackDirAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- void *attrbufptr;
- void *varbufptr;
- attrgroup_t a;
- u_long attrlength;
-
- attrbufptr = *attrbufptrptr;
- varbufptr = *varbufptrptr;
-
- /* XXX PPD TBC */
-
- *attrbufptrptr = attrbufptr;
- *varbufptrptr = varbufptr;
-}
-#endif
-
-
-
-#if 0
-void UnpackFileAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- void *attrbufptr;
- void *varbufptr;
- attrgroup_t a;
- u_long attrlength;
-
- attrbufptr = *attrbufptrptr;
- varbufptr = *varbufptrptr;
-
- /* XXX PPD TBC */
-
- *attrbufptrptr = attrbufptr;
- *varbufptrptr = varbufptr;
-}
-#endif
-
-
-
-#if 0
-void UnpackForkAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
- void *attrbufptr;
- void *varbufptr;
- attrgroup_t a;
- u_long attrlength;
-
- attrbufptr = *attrbufptrptr;
- varbufptr = *varbufptrptr;
-
- /* XXX PPD TBC */
-
- *attrbufptrptr = attrbufptr;
- *varbufptrptr = varbufptr;
-}
-#endif
-
-
-
-void UnpackAttributeBlock(struct attrlist *alist,
- struct vnode *vp,
- struct hfsCatalogInfo *catInfo,
- void **attrbufptrptr,
- void **varbufptrptr) {
-
-
- if (alist->volattr != 0) {
- UnpackVolumeAttributeBlock(alist, vp, VTOVCB(vp), attrbufptrptr, varbufptrptr);
- return;
- };
-
- /* We're dealing with a vnode object here: */
- UnpackCommonAttributeBlock(alist, vp, catInfo, attrbufptrptr, varbufptrptr);
-
-#if 0
- switch (vp->v_type) {
- case VDIR:
- UnpackDirAttributeBlock(alist, vp, catInfo, attrbufptrptr, varbufptrptr);
- break;
-
- case VREG:
- /* case VCPLX: */ /* XXX PPD TBC */
- UnpackFileAttributeBlock(alist, vp, catInfo, attrbufptrptr, varbufptrptr);
- break;
-
- case VFORK:
- UnpackForkAttributeBlock(alist, vp, catInfo, attrbufptrptr, varbufptrptr);
- break;
-
- /* Without this the compiler complains about VNON,VBLK,VCHR,VLNK,VSOCK,VFIFO,VBAD and VSTR
- not being handled...
- */
- default:
- /* XXX PPD - Panic? */
- break;
- };
-#endif
-
-};
-
-
-unsigned long BestBlockSizeFit(unsigned long allocationBlockSize,
- unsigned long blockSizeLimit,
- unsigned long baseMultiple) {
- /*
- Compute the optimal (largest) block size (no larger than allocationBlockSize) that is less than the
- specified limit but still an even multiple of the baseMultiple.
- */
- int baseBlockCount, blockCount;
- unsigned long trialBlockSize;
-
- if (allocationBlockSize % baseMultiple != 0) {
- /*
- Whoops: the allocation blocks aren't even multiples of the specified base:
- no amount of dividing them into even parts will be a multiple, either then!
- */
- return 512; /* Hope for the best */
- };
-
- /* Try the obvious winner first, to prevent 12K allocation blocks, for instance,
- from being handled as two 6K logical blocks instead of 3 4K logical blocks.
- Even though the former (the result of the loop below) is the larger allocation
- block size, the latter is more efficient: */
- if (allocationBlockSize % PAGE_SIZE == 0) return PAGE_SIZE;
-
- /* No clear winner exists: pick the largest even fraction <= MAXBSIZE: */
- baseBlockCount = allocationBlockSize / baseMultiple; /* Now guaranteed to be an even multiple */
-
- for (blockCount = baseBlockCount; blockCount > 0; --blockCount) {
- trialBlockSize = blockCount * baseMultiple;
- if (allocationBlockSize % trialBlockSize == 0) { /* An even multiple? */
- if ((trialBlockSize <= blockSizeLimit) &&
- (trialBlockSize % baseMultiple == 0)) {
- return trialBlockSize;
- };
- };
- };
-
- /* Note: we should never get here, since blockCount = 1 should always work,
- but this is nice and safe and makes the compiler happy, too ... */
- return 512;
-}
-
-
-/*
- * To make the HFS Plus filesystem follow UFS unlink semantics, a remove
- * of an active vnode is translated to a move/rename so the file appears
- * deleted. The destination folder for these move/renames is setup here
- * and a reference to it is place in hfsmp->hfs_private_metadata_dir.
- */
-u_long
-FindMetaDataDirectory(ExtendedVCB *vcb)
-{
- char namep[32];
- hfsCatalogInfo catInfo;
- HFSCatalogNodeID dirID;
- u_int32_t metadata_createdate;
- int retval;
-
- if (vcb->vcbSigWord != kHFSPlusSigWord)
- return (0);
-
- dirID = 0;
- metadata_createdate = 0;
- strncpy(namep, HFSPLUSMETADATAFOLDER, sizeof(namep));
- INIT_CATALOGDATA(&catInfo.nodeData, kCatNameNoCopyName);
- catInfo.hint = kNoHint;
-
- /* lock catalog b-tree */
- retval = hfs_metafilelocking(VCBTOHFS(vcb), kHFSCatalogFileID, LK_SHARED, current_proc());
- if (retval) goto Err_Exit;
-
- if (hfs_getcatalog(vcb, kRootDirID, namep, -1, &catInfo) == 0) {
- 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) {
- catInfo.hint = kNoHint;
- if (hfs_getcatalog(vcb, kRootDirID, namep, -1, &catInfo) == 0) {
-
- /* create date is later used for validation */
- catInfo.nodeData.cnd_createDate = vcb->vcbCrDate;
- metadata_createdate = catInfo.nodeData.cnd_createDate;
-
- /* directory with no permissions owned by root */
- catInfo.nodeData.cnd_mode = IFDIR;
- catInfo.nodeData.cnd_adminFlags = (SF_IMMUTABLE >> 16);
-
- /* hidden and off the desktop view */
- ((struct DInfo *)(&catInfo.nodeData.cnd_finderInfo))->frLocation.v = SWAP_BE16 (22460);
- ((struct DInfo *)(&catInfo.nodeData.cnd_finderInfo))->frLocation.h = SWAP_BE16 (22460);
- ((struct DInfo *)(&catInfo.nodeData.cnd_finderInfo))->frFlags |= SWAP_BE16 (kIsInvisible + kNameLocked);
-
- (void) UpdateCatalogNode(vcb, kRootDirID, namep, catInfo.hint, &catInfo.nodeData);
- }
- }
- }
-
- /* unlock catalog b-tree */
- (void) hfs_metafilelocking(VCBTOHFS(vcb), kHFSCatalogFileID, LK_RELEASE, current_proc());
-
- VCBTOHFS(vcb)->hfs_metadata_createdate = metadata_createdate;
-Err_Exit:
- CLEAN_CATALOGDATA(&catInfo.nodeData);
-
- return dirID;
-}
-
-
-static void
-RemovedMetaDataDirectory(ExtendedVCB *vcb)
-{
- char name[32];
- hfsCatalogInfo catInfo;
- int retval;
-
- strncpy(name, HFSPLUSMETADATAFOLDER, sizeof(name));
- INIT_CATALOGDATA(&catInfo.nodeData, kCatNameNoCopyName);
-
- /* lock catalog b-tree */
- retval = hfs_metafilelocking(VCBTOHFS(vcb), kHFSCatalogFileID, LK_SHARED, current_proc());
- if (retval) goto Err_Exit;
-
- /* If the HFSPLUSMETADATAFOLDER exists then delete it. */
- retval = GetCatalogNode(vcb, kRootDirID, name, strlen(name), kNoHint,
- &catInfo.nodeData, &catInfo.hint);
- if (retval == 0 && (catInfo.nodeData.cnd_type == kCatalogFolderNode)) {
- (void) DeleteCatalogNode(vcb, kRootDirID, name, catInfo.hint);
- printf("hfs_mount: removed \"%s\" from hfs volume \"%s\"\n", name, vcb->vcbVN);
- }
-
- /* unlock catalog b-tree */
- (void) hfs_metafilelocking(VCBTOHFS(vcb), kHFSCatalogFileID, LK_RELEASE, current_proc());
-
-Err_Exit:
- CLEAN_CATALOGDATA(&catInfo.nodeData);
-}
-
-/*
- * This will return the correct logical block size for a given vnode.
- * For most files, it is the allocation block size, for meta data like
- * BTrees, this is kept as part of the BTree private nodeSize
- */
-u_int32_t
-GetLogicalBlockSize(struct vnode *vp)
-{
-u_int32_t logBlockSize;
-
- DBG_ASSERT(vp != NULL);
-
- if ((vp->v_flag & VSYSTEM) && (VTOH(vp)->fcbBTCBPtr!=NULL)) {
- BTreeInfoRec bTreeInfo;
- int retval;
-
- /*
- * 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
- logBlockSize = VTOHFS(vp)->hfs_logBlockSize;
-
-
- DBG_ASSERT(logBlockSize > 0);
-
- return logBlockSize;
-}
-
-/*
- * Map HFS Common errors (negative) to BSD error codes (positive).
- * Positive errors (ie BSD errors) are passed through unchanged.
- */
-short MacToVFSError(OSErr err)
-{
- if (err >= 0) {
- if (err > 0) {
- DBG_ERR(("MacToVFSError: passing error #%d unchanged...\n", err));
- };
- return err;
- };
-
- if (err != 0) {
- DBG_ERR(("MacToVFSError: mapping error code %d...\n", err));
- };
-
- switch (err) {
- case dirFulErr: /* -33 */
- case dskFulErr: /* -34 */
- case btNoSpaceAvail: /* -32733 */
- case fxOvFlErr: /* -32750 */
- return ENOSPC; /* +28 */
-
- case btBadNode: /* -32731 */
- case ioErr: /* -36 */
- return EIO; /* +5 */
-
- case mFulErr: /* -41 */
- case memFullErr: /* -108 */
- return ENOMEM; /* +12 */
-
- case tmfoErr: /* -42 */
- /* Consider EMFILE (Too many open files, 24)? */
- return ENFILE; /* +23 */
-
- case nsvErr: /* -35 */
- case fnfErr: /* -43 */
- case dirNFErr: /* -120 */
- case fidNotFound: /* -1300 */
- return ENOENT; /* +2 */
-
- case wPrErr: /* -44 */
- case vLckdErr: /* -46 */
- case fsDSIntErr: /* -127 */
- return EROFS; /* +30 */
-
- case opWrErr: /* -49 */
- case fLckdErr: /* -45 */
- return EACCES; /* +13 */
-
- case permErr: /* -54 */
- case wrPermErr: /* -61 */
- return EPERM; /* +1 */
-
- case fBsyErr: /* -47 */
- return EBUSY; /* +16 */
-
- case dupFNErr: /* -48 */
- case fidExists: /* -1301 */
- case cmExists: /* -32718 */
- case btExists: /* -32734 */
- return EEXIST; /* +17 */
-
- case rfNumErr: /* -51 */
- return EBADF; /* +9 */
-
- case notAFileErr: /* -1302 */
- return EISDIR; /* +21 */
-
- case cmNotFound: /* -32719 */
- case btNotFound: /* -32735 */
- return ENOENT; /* 28 */
-
- case cmNotEmpty: /* -32717 */
- return ENOTEMPTY; /* 66 */
-
- case cmFThdDirErr: /* -32714 */
- return EISDIR; /* 21 */
-
- case fxRangeErr: /* -32751 */
- return EIO; /* 5 */
-
- case bdNamErr: /* -37 */
- return ENAMETOOLONG; /* 63 */
-
- case fnOpnErr: /* -38 */
- case eofErr: /* -39 */
- case posErr: /* -40 */
- case paramErr: /* -50 */
- case badMDBErr: /* -60 */
- case badMovErr: /* -122 */
- case sameFileErr: /* -1306 */
- case badFidErr: /* -1307 */
- case fileBoundsErr: /* -1309 */
- return EINVAL; /* +22 */
-
- default:
- DBG_UTILS(("Unmapped MacOS error: %d\n", err));
- return EIO; /* +5 */
- }
-}
-
-
-/*
- * All of our debugging functions
- */
-
-#if HFS_DIAGNOSTIC
-
-void debug_vn_status (char* introStr, struct vnode *vn)
-{
- DBG_VOP(("%s:\t",introStr));
- if (vn != NULL)
- {
- if (vn->v_tag != VT_HFS)
- {
- DBG_VOP(("NON-HFS VNODE Ox%08lX\n", (unsigned long)vn));
- }
- else if(vn->v_tag==VT_HFS && (vn->v_data==NULL || VTOH((vn))->h_valid != HFS_VNODE_MAGIC))
- {
- DBG_VOP(("BAD VNODE PRIVATE DATA!!!!\n"));
- }
- else
- {
- DBG_VOP(("r: %d & ", vn->v_usecount));
- if (lockstatus(&VTOH(vn)->h_lock))
- {
- DBG_VOP_CONT(("is L\n"));
- }
- else
- {
- DBG_VOP_CONT(("is U\n"));
- }
- }
- }
- else
- {
- DBG_VOP(("vnode is NULL\n"));
- };
-}
-
-void debug_vn_print (char* introStr, struct vnode *vn)
-{
-// DBG_FUNC_NAME("DBG_VN_PRINT");
- DBG_ASSERT (vn != NULL);
- DBG_VFS(("%s: ",introStr));
- DBG_VFS_CONT(("vnode: 0x%x is a ", (uint)vn));
- switch (vn->v_tag)
- {
- case VT_UFS:
- DBG_VFS_CONT(("%s","UFS"));
- break;
- case VT_HFS:
- DBG_VFS_CONT(("%s","HFS"));
- break;
- default:
- DBG_VFS_CONT(("%s","UNKNOWN"));
- break;
- }
-
- DBG_VFS_CONT((" vnode\n"));
- if (vn->v_tag==VT_HFS)
- {
- if (vn->v_data==NULL)
- {
- DBG_VFS(("BAD VNODE PRIVATE DATA!!!!\n"));
- }
- else
- {
- DBG_VFS((" Name: %s Id: %ld ",H_NAME(VTOH(vn)), H_FILEID(VTOH(vn))));
- }
- }
- else
- DBG_VFS((" "));
-
- DBG_VFS_CONT(("Refcount: %d\n", vn->v_usecount));
- if (VOP_ISLOCKED(vn))
- {
- DBG_VFS((" The vnode is locked\n"));
- }
- else
- {
- DBG_VFS((" The vnode is not locked\n"));
- }
-}
-
-void debug_rename_test_locks (char* introStr,
- struct vnode *fvp,
- struct vnode *fdvp,
- struct vnode *tvp,
- struct vnode *tdvp,
- int fstatus,
- int fdstatus,
- int tstatus,
- int tdstatus
-)
-{
- DBG_VOP(("\t%s: ", introStr));
- if (fvp) {if(lockstatus(&VTOH(fvp)->h_lock)){DBG_VFS_CONT(("L"));} else {DBG_VFS_CONT(("U"));}} else { DBG_VFS_CONT(("X"));};
- if (fdvp) {if(lockstatus(&VTOH(fdvp)->h_lock)){DBG_VFS_CONT(("L"));} else {DBG_VFS_CONT(("U"));}} else { DBG_VFS_CONT(("X"));};
- if (tvp) {if(lockstatus(&VTOH(tvp)->h_lock)){DBG_VFS_CONT(("L"));} else {DBG_VFS_CONT(("U"));}} else { DBG_VFS_CONT(("X"));};
- if (tdvp) {if(lockstatus(&VTOH(tdvp)->h_lock)){DBG_VFS_CONT(("L"));} else {DBG_VFS_CONT(("U"));}} else { DBG_VFS_CONT(("X"));};
- DBG_VFS_CONT(("\n"));
-
- if (fvp) {
- if (lockstatus(&VTOH(fvp)->h_lock)) {
- if (fstatus==VOPDBG_UNLOCKED) {
- DBG_VOP(("\tfvp should be NOT LOCKED and it is\n"));
- }
- } else if (fstatus == VOPDBG_LOCKED) {
- DBG_VOP(("\tfvp should be LOCKED and it isnt\n"));
- }
- }
-
- if (fdvp) {
- if (lockstatus(&VTOH(fdvp)->h_lock)) {
- if (fdstatus==VOPDBG_UNLOCKED) {
- DBG_VOP(("\tfdvp should be NOT LOCKED and it is\n"));
- }
- } else if (fdstatus == VOPDBG_LOCKED) {
- DBG_VOP(("\tfdvp should be LOCKED and it isnt\n"));
- }
- }
-
- if (tvp) {
- if (lockstatus(&VTOH(tvp)->h_lock)) {
- if (tstatus==VOPDBG_UNLOCKED) {
- DBG_VOP(("\ttvp should be NOT LOCKED and it is\n"));
- }
- } else if (tstatus == VOPDBG_LOCKED) {
- DBG_VOP(("\ttvp should be LOCKED and it isnt\n"));
- }
- }
-
- if (tdvp) {
- if (lockstatus(&VTOH(tdvp)->h_lock)) {
- if (tdstatus==VOPDBG_UNLOCKED) {
- DBG_VOP(("\ttdvp should be NOT LOCKED and it is\n"));
- }
- } else if (tdstatus == VOPDBG_LOCKED) {
- DBG_VOP(("\ttdvp should be LOCKED and it isnt\n"));
-
- }
- }
-
-}
-#endif /* HFS_DIAGNOSTIC */
-
-
-#if HFS_DIAGNOSTIC
-void debug_check_buffersizes(struct vnode *vp, struct hfsnode *hp, struct buf *bp) {
- DBG_ASSERT(bp->b_validoff == 0);
- DBG_ASSERT(bp->b_dirtyoff == 0);
- DBG_ASSERT((bp->b_bcount == HTOHFS(hp)->hfs_logBlockSize) ||
- ((bp->b_bcount % 512 == 0) &&
- (bp->b_validend > 0) &&
- (bp->b_dirtyend > 0) &&
- (bp->b_bcount < HTOHFS(hp)->hfs_logBlockSize)));
-
- if (bp->b_validend == 0) {
- DBG_ASSERT(bp->b_dirtyend == 0);
- } else {
- DBG_ASSERT(bp->b_validend == bp->b_bcount);
- DBG_ASSERT(bp->b_dirtyend <= bp->b_bcount);
- };
-}
-
-
-void debug_check_blocksizes(struct vnode *vp) {
- struct hfsnode *hp = VTOH(vp);
- struct buf *bp;
-
- if (vp->v_flag & VSYSTEM) return;
-
- for (bp = vp->v_cleanblkhd.lh_first; bp != NULL; bp = bp->b_vnbufs.le_next) {
- debug_check_buffersizes(vp, hp, bp);
- };
-
- for (bp = vp->v_dirtyblkhd.lh_first; bp != NULL; bp = bp->b_vnbufs.le_next) {
- debug_check_buffersizes(vp, hp, bp);
- };
-}
-
-void debug_check_catalogdata(struct CatalogNodeData *cat) {
-
- if (cat->cnm_nameptr == NULL) {
- DBG_ASSERT((cat->cnm_flags & kCatNameIsAllocated) == 0);
- }
- else if (cat->cnm_nameptr == cat->cnm_namespace) {
- DBG_ASSERT((cat->cnm_flags & kCatNameIsAllocated) == 0);
- }
- else {
- DBG_ASSERT((cat->cnm_flags & kCatNameIsAllocated) == kCatNameIsAllocated);
- }
-
- if (cat->cnm_nameptr) {
- DBG_ASSERT(strlen(cat->cnm_nameptr) == cat->cnm_length);
- }
-
- if (cat->cnm_flags & kCatNameIsConsumed) {
- DBG_ASSERT((cat->cnm_flags & kCatNameIsAllocated) == 0);
- }
-
- if (cat->cnm_flags & kCatNameNoCopyName) {
- DBG_ASSERT((cat->cnm_flags & (kCatNameIsAllocated|kCatNameIsConsumed|kCatNameIsMangled)) == 0);
- DBG_ASSERT(cat->cnm_length == 0);
- DBG_ASSERT(cat->cnm_nameptr == 0);
- DBG_ASSERT(strlen(cat->cnm_namespace) == 0);
- }
-
-}
-
-extern void hfs_vhash_dbg(struct hfsnode *hp);
-
-/* Checks the valicity of a hfs vnode */
-void debug_check_vnode(struct vnode *vp, int stage) {
- struct hfsnode *hp;
- u_long size;
- int i;
-
- /* vcb stuff */
- if (VTOHFS(vp)->hfs_mount_flags & kHFSBootVolumeInconsistentMask)
- DEBUG_BREAK_MSG(("Volume is damaged!"));
-
- /* vnode stuff */
- if (vp==NULL)
- DEBUG_BREAK_MSG(("Null vnode"));
- if (vp->v_tag != VT_HFS)
- DEBUG_BREAK_MSG(("Not a HFS vnode, it is a %d", vp->v_tag));
- if (vp->v_data==NULL)
- DEBUG_BREAK_MSG(("v_data is NULL"));
-
- /* hfsnode stuff */
- hp = VTOH(vp);
- if (hp->h_valid != HFS_VNODE_MAGIC)
- DEBUG_BREAK_MSG(("Bad Formed HFS node"));
- if (hp->h_vp==NULL || hp->h_vp!=vp)
- DEBUG_BREAK_MSG(("Bad hfsnode vnode pte"));
- if (hp->h_meta == NULL)
- DEBUG_BREAK_MSG(("Bad hfsnode meta ptr"));
- switch (H_FORKTYPE(hp)) {
- case kDataFork:
- case kRsrcFork:
- if ((hp->h_meta->h_siblinghead.cqh_first == NULL) || (hp->h_meta->h_siblinghead.cqh_last == NULL))
- DEBUG_BREAK_MSG(("Null sibling header"));
- if ((hp->h_sibling.cqe_next==NULL) || (hp->h_sibling.cqe_prev==NULL))
- DEBUG_BREAK_MSG(("Null sibling list"));
- if (hp->h_meta->h_usecount<1 || hp->h_meta->h_usecount>2)
- DEBUG_BREAK_MSG(("Bad sibling usecount"));
- break;
- case kDirectory:
- case kSysFile:
- if ((hp->h_meta->h_siblinghead.cqh_first != NULL) || (hp->h_meta->h_siblinghead.cqh_last != NULL))
- DEBUG_BREAK_MSG(("Non Null sibling header"));
- if ((hp->h_sibling.cqe_next!=NULL) || (hp->h_sibling.cqe_prev!=NULL))
- DEBUG_BREAK_MSG(("Null sibling list"));
- if (hp->h_meta->h_usecount!=1)
- DEBUG_BREAK_MSG(("Bad usecount"));
-
- break;
- default:
- DEBUG_BREAK_MSG(("Bad hfsnode fork type"));
- }
-
- /* hfsmeta stuff */
- if (hp->h_meta->h_devvp == NULL)
- DEBUG_BREAK_MSG(("Bad hfsnode dev vnode"));
- if (H_DEV(hp) == 0)
- DEBUG_BREAK_MSG(("Bad dev id"));
- if (H_FILEID(hp) == 0)
- DEBUG_BREAK_MSG(("Bad file id"));
-
- if (((hp->h_meta->h_metaflags & IN_DATANODE)==0) && (H_DIRID(hp) == 0) && (H_FILEID(hp) != 1))
- DEBUG_BREAK_MSG(("Bad dir id"));
-
- if (hp->h_meta->h_namePtr == NULL && hp->h_meta->h_namelen!=0)
- DEBUG_BREAK_MSG(("hfs meta h_namelen is not 0"));
- if (hp->h_meta->h_namePtr != NULL && strlen(hp->h_meta->h_namePtr) != hp->h_meta->h_namelen)
- DEBUG_BREAK_MSG(("Bad hfs meta h_namelen"));
-
- /* Check the hash */
- hfs_vhash_dbg(hp);
-
- /* Check to see if we want to compare with the disk */
- if (stage > 200) {
- int retval;
- hfsCatalogInfo catInfo;
-
- INIT_CATALOGDATA(&catInfo.nodeData, 0);
- catInfo.hint = 0;
-
- if (hfs_metafilelocking(VTOHFS(vp), kHFSCatalogFileID, LK_SHARED, current_proc()))
- return;
-
- if (hfs_getcatalog(VTOVCB(vp), H_DIRID(hp), hp->h_meta->h_namePtr, hp->h_meta->h_namelen, &catInfo))
- DEBUG_BREAK_MSG(("Could not find hfsnode Catalog record"));
-
- (void) hfs_metafilelocking(VTOHFS(vp), kHFSCatalogFileID, LK_RELEASE, current_proc());
-
- if (H_FILEID(hp) != catInfo.nodeData.cnd_nodeID)
- DEBUG_BREAK_MSG(("hfsnode catalog node id mismatch"));
- if (H_DIRID(hp) != catInfo.nodeData.cnm_parID)
- DEBUG_BREAK_MSG(("hfsnode catalog dir id mismatch"));
- if (strcmp(hp->h_meta->h_namePtr, catInfo.nodeData.cnm_nameptr) != 0)
- DEBUG_BREAK_MSG(("hfsnode catalog name mismatch"));
- /* Check dates too??? */
-
- CLEAN_CATALOGDATA(&catInfo.nodeData);
-
- }
-
-
- /* Check Extents */
- {
- for(i = 0, size = 0; i < kHFSPlusExtentDensity; i++)
- {
- size += hp->fcbExtents[i].blockCount;
- }
-
- if (hp->fcbEOF > hp->fcbPLen)
- DEBUG_BREAK_MSG(("fcbPLen is smaller than fcbEOF"));
-
- if (hp->fcbExtents[kHFSPlusExtentDensity-1].blockCount == 0) {
- if ((off_t)size * (off_t)VTOVCB(vp)->blockSize != hp->fcbPLen)
- DEBUG_BREAK_MSG(("fcbPLen does not match extents"));
- } else {
- if ( hp->fcbPLen < (off_t)size * (off_t)VTOVCB(vp)->blockSize)
- DEBUG_BREAK_MSG(("fcbPLen is smaller than extents"));
- }
- for(i = 0; i < kHFSPlusExtentDensity; i++)
- {
- if (hp->fcbExtents[i].blockCount == 0 || hp->fcbExtents[i].startBlock == 0)
- break;
- }
- if ((VTOVCB(vp)->vcbSigWord == kHFSSigWord) && i > kHFSExtentDensity)
- DEBUG_BREAK_MSG(("Illegal value in extents for ordinary HFS"));
- if (i > kHFSPlusExtentDensity) {
- for(; i < kHFSPlusExtentDensity; i++)
- {
- if (hp->fcbExtents[i].blockCount != 0 || hp->fcbExtents[i].startBlock != 0)
- DEBUG_BREAK_MSG(("Illegal value in extents"));
- }
- }
- }
-
-
- /* BTree stuff */
- if (0 && vp->v_flag & VSYSTEM) {
- BTreeInfoRec info;
-
- BTGetInformation(hp, 0, &info);
- if (hp->fcbBTCBPtr == NULL)
- DEBUG_BREAK_MSG(("Null fcbBTCBPtr"));
- if (H_HINT(hp) == 0)
- DEBUG_BREAK_MSG(("hint is 0"));
- if (H_HINT(hp) > info.numNodes)
- DEBUG_BREAK_MSG(("hint > numNodes"));
- }