|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* @(#)MacOSStubs.c 4.0 ! 26: * ! 27: * (c) 1997-1998 Apple Computer, Inc. All Rights Reserved ! 28: * ! 29: * MacOSStubs.c -- Contains routines called by MacOS code, that is not defined. ! 30: * ! 31: * HISTORY ! 32: * 20-Nov-1998 Don Brady Remove UFSToHFSStr and HFSToUFSStr routines (obsolete). ! 33: * 31-Aug-1998 Don Brady Move DST adjustments to GetTimeLocal (radar #2265075). ! 34: * 28-Jul-1998 Don Brady Add GetDiskBlocks routine (radar #2258148). ! 35: * 23-Jul-1998 Don Brady Use bdwrite instead of bwrite for default in RelBlock_glue (radar #2257225). ! 36: * 7-Jul-1998 Don Brady Remove character mappings from/to hfs (ufs_hfs and hfs_ufs tables). ! 37: * 22-Jun-1998 Pat Dirks Added the vice versa mappings in ufs_hfs and hfs_ufs to more ! 38: * thoroughly interchange ":" and "/" in name strings. ! 39: * 4-Jun-1998 Pat Dirks Changed to do all B*-Tree writes synchronously (FORCESYNCBTREEWRITES = 1) ! 40: * 4-jun-1998 Don Brady Use VPUT macro instead of vput. ! 41: * 6-may-1998 Don Brady Bump h_devvp refcount in GetInitializedVNode (radar #2232480). ! 42: * 27-apr-1998 Don Brady Change printf to kprintf. ! 43: * 23-Apr-1998 Pat Dirks Cleaned up GetBlock_glue to add brelse on I/O errors from bread. ! 44: * 23-apr-1998 Don Brady Add '/' to ':' mapping and vice versa to mapping tables. ! 45: * 21-apr-1998 Don Brady Clean up time/date conversion routines. ! 46: * 11-apr-1998 Don Brady Add RequireFileLock routine. ! 47: * 8-apr-1998 Don Brady C_FlushMDB now calls hfs_flushvolumeheader and hfs_flushMDB. ! 48: * 12-nov-1997 Scott Roberts ! 49: * Initially created file. ! 50: * ! 51: */ ! 52: #include <sys/types.h> ! 53: #include <sys/malloc.h> ! 54: #include <sys/kernel.h> ! 55: #include <libkern/libkern.h> ! 56: #include <sys/systm.h> ! 57: #include <bsd/dev/disk.h> ! 58: #include "hfs.h" ! 59: #include "hfs_dbg.h" ! 60: ! 61: ! 62: #include "hfscommon/headers/system/MacOSTypes.h" ! 63: #include "hfscommon/headers/system/MacOSStubs.h" ! 64: #include "hfscommon/headers/BTreesPrivate.h" ! 65: ! 66: extern int (**hfs_vnodeop_p)(); ! 67: ! 68: ! 69: struct timezone gTimeZone = {8*60,1}; /*XXX need to dynamically set this global from HFS Util */ ! 70: ! 71: ! 72: /*************************************************************************************/ ! 73: ! 74: /*************************************************************************************/ ! 75: ! 76: FCB* GetFileControlBlock(FileReference fref) ! 77: { ! 78: return VTOFCB(fref); ! 79: } ! 80: ! 81: FileReference GetFileRefNumFromFCB(const FCB *filePtr) ! 82: { ! 83: return (FileReference)FCBTOV(filePtr); ! 84: } ! 85: ! 86: /* ! 87: * The following two routines work in tandem: StoreBufferMapping stores ! 88: * successive buffer address -> buffer pointer mappings in a circular ! 89: * match list, advancing the list index forward each time, while LookupBufferMapping ! 90: * looks backwards through the list to look up a particular mapping (which is ! 91: * typically the entry currently pointed to by gBufferAddress). ! 92: * ! 93: */ ! 94: static void StoreBufferMapping(caddr_t bufferAddress, struct buf *bp) ! 95: { ! 96: int i; ! 97: ! 98: DBG_ASSERT(gBufferListIndex >= 0); ! 99: DBG_ASSERT(gBufferListIndex < BUFFERPTRLISTSIZE); ! 100: ! 101: simple_lock(&gBufferPtrListLock); ! 102: ! 103: /* We've got at most BUFFERPTRLISTSIZE tries at this... */ ! 104: for (i = BUFFERPTRLISTSIZE; i > 0; --i) { ! 105: if (gBufferAddress[gBufferListIndex] == NULL) { ! 106: gBufferAddress[gBufferListIndex] = bufferAddress; ! 107: gBufferHeaderPtr[gBufferListIndex] = bp; ! 108: break; ! 109: } ! 110: gBufferListIndex = (gBufferListIndex + 1) % BUFFERPTRLISTSIZE; ! 111: }; ! 112: ! 113: if (i == 0) { ! 114: panic("StoreBufferMapping: couldn't find an empty slot in buffer list."); ! 115: }; ! 116: ! 117: DBG_ASSERT(gBufferListIndex >= 0); ! 118: DBG_ASSERT(gBufferListIndex < BUFFERPTRLISTSIZE); ! 119: ! 120: simple_unlock(&gBufferPtrListLock); ! 121: } ! 122: ! 123: ! 124: /*static*/ OSErr LookupBufferMapping(caddr_t bufferAddress, struct buf **bpp, int *mappingIndexPtr) ! 125: { ! 126: OSErr err = E_NONE; ! 127: int i; ! 128: int listIndex = gBufferListIndex; ! 129: struct buf *bp = NULL; ! 130: ! 131: DBG_ASSERT(gBufferListIndex >= 0); ! 132: DBG_ASSERT(gBufferListIndex < BUFFERPTRLISTSIZE); ! 133: ! 134: simple_lock(&gBufferPtrListLock); ! 135: ! 136: /* We've got at most BUFFERPTRLISTSIZE tries at this... */ ! 137: for (i = BUFFERPTRLISTSIZE; i > 0; --i) { ! 138: if (gBufferAddress[listIndex] == bufferAddress) { ! 139: *mappingIndexPtr = listIndex; ! 140: bp = gBufferHeaderPtr[listIndex]; ! 141: break; ! 142: }; ! 143: ! 144: listIndex = (listIndex - 1); ! 145: if (listIndex < 0) { ! 146: listIndex = BUFFERPTRLISTSIZE - 1; ! 147: }; ! 148: }; ! 149: ! 150: if (bp == NULL) { ! 151: DEBUG_BREAK_MSG(("LookupBufferMapping: couldn't find buffer header for buffer in list.\n")); ! 152: err = -1; ! 153: }; ! 154: ! 155: DBG_ASSERT(gBufferListIndex >= 0); ! 156: DBG_ASSERT(gBufferListIndex < BUFFERPTRLISTSIZE); ! 157: ! 158: simple_unlock(&gBufferPtrListLock); ! 159: ! 160: *bpp = bp; ! 161: return err; ! 162: } ! 163: ! 164: ! 165: static void ReleaseMappingEntry(int entryIndex) { ! 166: ! 167: DBG_ASSERT(gBufferListIndex >= 0); ! 168: DBG_ASSERT(gBufferListIndex < BUFFERPTRLISTSIZE); ! 169: ! 170: simple_lock(&gBufferPtrListLock); ! 171: gBufferAddress[entryIndex] = NULL; ! 172: simple_unlock(&gBufferPtrListLock); ! 173: }; ! 174: #if DIAGNOSTIC ! 175: #define DBG_GETBLOCK 0 ! 176: #else ! 177: #define DBG_GETBLOCK 0 ! 178: #endif ! 179: ! 180: OSErr GetBlock_glue (UInt16 options, UInt32 blockNum, Ptr *baddress, FileReference fileRefNum, ExtendedVCB * vcb) ! 181: { ! 182: int status; ! 183: struct buf *bp = NULL; ! 184: int readcount = 0; ! 185: ! 186: #if DBG_GETBLOCK ! 187: DBG_IO(("Getting block %ld with options %d and a refnum of %x\n", blockNum, options, fileRefNum )); ! 188: #endif ! 189: ! 190: if ((options & ~(gbReadMask | gbNoReadMask)) != 0) { ! 191: DEBUG_BREAK_MSG(("GetBlock_glue: options = 0x%04X.\n", options)); ! 192: }; ! 193: ! 194: *baddress = NULL; ! 195: ! 196: if (options & gbNoReadMask) { ! 197: if (fileRefNum == NULL) { ! 198: bp = getblk (VCBTOHFS(vcb)->hfs_devvp, ! 199: IOBLKNOFORBLK(blockNum, VCBTOHFS(vcb)->hfs_phys_block_size), ! 200: IOBYTECCNTFORBLK(blockNum, kHFSBlockSize, VCBTOHFS(vcb)->hfs_phys_block_size), ! 201: 0, ! 202: 0); ! 203: } else { ! 204: bp = getblk (fileRefNum, ! 205: IOBLKNOFORBLK(blockNum, VCBTOHFS(vcb)->hfs_phys_block_size), ! 206: IOBYTECCNTFORBLK(blockNum, kHFSBlockSize, VCBTOHFS(vcb)->hfs_phys_block_size), ! 207: 0, ! 208: 0); ! 209: }; ! 210: status = E_NONE; ! 211: } else { ! 212: do { ! 213: if (fileRefNum == NULL) { ! 214: status = bread (VCBTOHFS(vcb)->hfs_devvp, ! 215: IOBLKNOFORBLK(blockNum, VCBTOHFS(vcb)->hfs_phys_block_size), ! 216: IOBYTECCNTFORBLK(blockNum, kHFSBlockSize, VCBTOHFS(vcb)->hfs_phys_block_size), ! 217: NOCRED, ! 218: &bp); ! 219: } else { ! 220: status = bread (fileRefNum, ! 221: IOBLKNOFORBLK(blockNum, VCBTOHFS(vcb)->hfs_phys_block_size), ! 222: IOBYTECCNTFORBLK(blockNum, kHFSBlockSize, VCBTOHFS(vcb)->hfs_phys_block_size), ! 223: NOCRED, ! 224: &bp); ! 225: }; ! 226: if (status != E_NONE) { ! 227: if (bp) brelse(bp); ! 228: goto Error_Exit; ! 229: }; ! 230: ! 231: if (bp == NULL) { ! 232: status = -1; ! 233: goto Error_Exit; ! 234: }; ! 235: ! 236: ++readcount; ! 237: ! 238: if ((options & gbReadMask) && (bp->b_flags & B_CACHE)) { ! 239: /* Rats! The block was found in the cache just when we really wanted a ! 240: fresh copy off disk... ! 241: */ ! 242: if (bp->b_flags & B_DIRTY) { ! 243: DEBUG_BREAK_MSG(("GetBlock_glue: forced read for dirty block!\n")) ! 244: }; ! 245: bp->b_flags |= B_INVAL; ! 246: brelse(bp); ! 247: ! 248: /* Fall through and try again until we get a fresh copy from the disk... */ ! 249: }; ! 250: } while (((options & gbReadMask) != 0) && (readcount <= 1)); ! 251: }; ! 252: ! 253: *baddress = bp->b_data + IOBYTEOFFSETFORBLK(bp->b_blkno, VCBTOHFS(vcb)->hfs_phys_block_size); ! 254: StoreBufferMapping(*baddress, bp); ! 255: ! 256: Error_Exit: ; ! 257: return status; ! 258: } ! 259: ! 260: void MarkBlock_glue (Ptr address) ! 261: { ! 262: int err; ! 263: struct buf *bp = NULL; ! 264: int mappingEntry; ! 265: ! 266: if ((err = LookupBufferMapping(address, &bp, &mappingEntry))) { ! 267: PANIC("Failed to find buffer pointer for buffer in MarkBlock_glue."); ! 268: } else { ! 269: bp->b_flags |= B_DIRTY; ! 270: }; ! 271: } ! 272: ! 273: OSErr RelBlock_glue (Ptr address, UInt16 options ) ! 274: { ! 275: int err; ! 276: struct buf *bp; ! 277: int mappingEntry; ! 278: ! 279: if (options & ~(rbTrashMask | rbDirtyMask | rbWriteMask) == 0) { ! 280: DEBUG_BREAK_MSG(("RelBlock_glue: options = 0x%04X.\n", options)); ! 281: }; ! 282: ! 283: if ((err = LookupBufferMapping(address, &bp, &mappingEntry))) { ! 284: DEBUG_BREAK_MSG(("Failed to find buffer pointer for buffer in RelBlock_glue.\n")); ! 285: } else { ! 286: if (bp->b_flags & B_DIRTY) { ! 287: /* The buffer was previously marked dirty (using MarkBlock_glue): ! 288: now's the time to write it. */ ! 289: options |= rbDirtyMask; ! 290: }; ! 291: ReleaseMappingEntry(mappingEntry); ! 292: if (options & rbTrashMask) { ! 293: bp->b_flags |= B_INVAL; ! 294: brelse(bp); ! 295: } else { ! 296: if (options & (rbDirtyMask | rbWriteMask)) { ! 297: bp->b_flags |= B_DIRTY; ! 298: if (options & rbWriteMask) { ! 299: bwrite(bp); ! 300: } else { ! 301: bdwrite(bp); ! 302: } ! 303: } else { ! 304: brelse(bp); ! 305: }; ! 306: }; ! 307: err = E_NONE; ! 308: }; ! 309: return err; ! 310: } ! 311: ! 312: /* */ ! 313: /* Creates a new vnode to hold a psuedo file like an extents tree file */ ! 314: /* */ ! 315: ! 316: OSStatus GetInitializedVNode(struct hfsmount *hfsmp, struct vnode **tmpvnode ) ! 317: { ! 318: ! 319: struct hfsnode *hp; ! 320: struct vnode *vp = NULL; ! 321: int rtn; ! 322: ! 323: DBG_ASSERT(hfsmp != NULL); ! 324: DBG_ASSERT(tmpvnode != NULL); ! 325: ! 326: /* Allocate a new hfsnode. */ ! 327: /* Must malloc() here, since getnewvnode() can sleep */ ! 328: MALLOC(hp, struct hfsnode *, sizeof(struct hfsnode), M_HFSNODE, M_WAITOK); ! 329: if(hp == NULL) { ! 330: rtn = ENOMEM; ! 331: goto Err_Exit; ! 332: } ! 333: bzero((caddr_t)hp, sizeof(struct hfsnode)); ! 334: lockinit(&hp->h_lock, PINOD, "hfsnode", 0, 0); ! 335: ! 336: /* Allocate a new vnode. */ ! 337: if ((rtn = getnewvnode(VT_HFS, HFSTOVFS(hfsmp), hfs_vnodeop_p, &vp))) { ! 338: goto Err_Exit; ! 339: } ! 340: ! 341: /* Init the structure */ ! 342: MALLOC(hp->h_meta, struct hfsfilemeta *, sizeof(struct hfsfilemeta), M_HFSNODE, M_WAITOK); ! 343: bzero(hp->h_meta, sizeof(struct hfsfilemeta)); ! 344: lockinit(&hp->h_meta->h_fmetalock, PINOD, "hfsfilemeta", 0, 0); ! 345: MALLOC(hp->h_xfcb, struct vfsFCB *, sizeof(struct vfsFCB), M_HFSNODE, M_WAITOK); ! 346: bzero(hp->h_xfcb, sizeof(struct vfsFCB)); ! 347: ! 348: hp->h_vp = vp; /* Make HFSTOV work */ ! 349: hp->h_xfcb->fcb_vp = vp; /* Make FCBTOV work */ ! 350: hp->h_devvp = hfsmp->hfs_devvp; ! 351: hp->h_dev = hfsmp->hfs_raw_dev; ! 352: hp->h_meta->h_logBlockSize = hfsmp->hfs_log_block_size; ! 353: hp->h_meta->h_physBlkPerLogBlk = hp->h_meta->h_logBlockSize/kHFSBlockSize; ! 354: hp->h_meta->h_nodeflags |= IN_ACCESS | IN_CHANGE | IN_UPDATE; ! 355: hp->h_valid = HFS_VNODE_MAGIC; ! 356: ! 357: vp->v_data = hp; /* Make VTOH work */ ! 358: vp->v_type = VREG; ! 359: ! 360: *tmpvnode = vp; ! 361: ! 362: VREF(hp->h_devvp); ! 363: ! 364: return noErr; ! 365: ! 366: Err_Exit: ! 367: if (vp) ! 368: { ! 369: VPUT(vp); ! 370: vp->v_type = VNON; ! 371: vgone(vp); ! 372: } ! 373: ! 374: *tmpvnode = NULL; ! 375: ! 376: return rtn; ! 377: } ! 378: ! 379: OSErr GetNewFCB(ExtendedVCB *vcb, FileReference* fRefPtr) ! 380: { ! 381: OSErr err; ! 382: ! 383: err = GetInitializedVNode( VCBTOHFS(vcb), fRefPtr ); ! 384: panic("This node is not completely initialized in GetNewFCB!"); /* XXX SER */ ! 385: ! 386: return( err ); ! 387: } ! 388: ! 389: Boolean BlockCameFromDisk() ! 390: { ! 391: /* Did the last block read, really come from a disk hit */ ! 392: return true; ! 393: ! 394: } ! 395: ! 396: ! 397: /* ! 398: * Mac OS Stubs ! 399: */ ! 400: void UprText (Ptr textPtr, short len) ! 401: { ! 402: char * cptr; ! 403: char c; ! 404: int count; ! 405: ! 406: for (cptr = (char *)textPtr, count = len; count > 0; --count) { ! 407: c = *cptr; ! 408: *(cptr++) = (('a' <= c) && (c <= 'z')) ? c - ('a' - 'A') : c; ! 409: }; ! 410: } ! 411: ! 412: ! 413: ! 414: Boolean CaseAndMarkSensitiveEqualString (void * str1, ! 415: void * str2, ! 416: unsigned long firstStringLength, ! 417: unsigned long secondStringLength) ! 418: ! 419: { ! 420: return (strncmp(str1, str2, max (firstStringLength,secondStringLength))); ! 421: ! 422: } ! 423: ! 424: ! 425: Ptr PLstrstr(ConstStr255Param str1, ConstStr255Param str2) ! 426: { ! 427: int searchStringLength, targetStringLength; ! 428: char searchString[256]; ! 429: char targetString[256]; ! 430: Ptr searchResult; ! 431: ! 432: searchStringLength = (int)str1[0]; ! 433: memcpy(searchString, str1+1, searchStringLength); ! 434: searchString[searchStringLength] = (char)0; ! 435: ! 436: targetStringLength = (int)str2[0]; ! 437: memcpy(targetString, str2+1, targetStringLength); ! 438: targetString[targetStringLength] = (char)0; ! 439: ! 440: /* ! 441: Do the search on the newly created search string but if the search ! 442: returns a non-NULL result return a pointer that's the same offset ! 443: into the original Pascal search string. ! 444: */ ! 445: if ((searchResult = (Ptr)strstr(searchString, targetString))) { ! 446: searchResult = (const Ptr)(str1 + 1 + (searchResult - (Ptr)searchString)); ! 447: }; ! 448: ! 449: return searchResult; ! 450: } ! 451: ! 452: ! 453: OSErr CheckVolumeOffLine( ExtendedVCB *vcb ) ! 454: { ! 455: ! 456: return( 0 ); ! 457: } ! 458: ! 459: ! 460: OSErr C_FlushMDB( ExtendedVCB *volume) ! 461: { ! 462: short err; ! 463: ! 464: if (volume->vcbSigWord == kHFSPlusSigWord) ! 465: err = hfs_flushvolumeheader(VCBTOHFS(volume), MNT_WAIT); ! 466: else ! 467: err = hfs_flushMDB(VCBTOHFS(volume), MNT_WAIT); ! 468: ! 469: return err; ! 470: } ! 471: ! 472: ! 473: /* ! 474: * GetTimeUTC - get the GMT Mac OS time (in seconds since 1/1/1904) ! 475: * ! 476: * called by the Catalog Manager when creating/updating records ! 477: */ ! 478: UInt32 GetTimeUTC(void) ! 479: { ! 480: return (time.tv_sec + MAC_GMT_FACTOR); ! 481: } ! 482: ! 483: /* ! 484: * GetTimeLocal - get the local Mac OS time (in seconds since 1/1/1904) ! 485: * ! 486: * called by the Catalog Manager when creating/updating records ! 487: * also used to update the VCB last modify date ! 488: */ ! 489: UInt32 GetTimeLocal(Boolean forHFS) ! 490: { ! 491: UInt32 localTime; ! 492: ! 493: localTime = UTCToLocal(GetTimeUTC()); ! 494: ! 495: if (forHFS && gTimeZone.tz_dsttime) ! 496: localTime += 3600; ! 497: ! 498: return localTime; ! 499: } ! 500: ! 501: /* ! 502: * LocalToUTC - convert from Mac OS local time to Mac OS GMT time ! 503: */ ! 504: UInt32 LocalToUTC(UInt32 localTime) ! 505: { ! 506: UInt32 gtime = localTime; ! 507: ! 508: if (gtime != 0) { ! 509: gtime += (gTimeZone.tz_minuteswest * 60); ! 510: /* ! 511: * We no longer do DST adjustments here since we don't ! 512: * know if time supplied needs adjustment! ! 513: * ! 514: * if (gTimeZone.tz_dsttime) ! 515: * gtime -= 3600; ! 516: */ ! 517: } ! 518: return (gtime); ! 519: } ! 520: ! 521: /* ! 522: * UTCToLocal - convert from Mac OS GMT time to Mac OS local time ! 523: */ ! 524: UInt32 UTCToLocal(UInt32 utcTime) ! 525: { ! 526: UInt32 ltime = utcTime; ! 527: ! 528: if (ltime != 0) { ! 529: ltime -= (gTimeZone.tz_minuteswest * 60); ! 530: /* ! 531: * We no longer do DST adjustments here since we don't ! 532: * know if time supplied needs adjustment! ! 533: * ! 534: * if (gTimeZone.tz_dsttime) ! 535: * ltime += 3600; ! 536: */ ! 537: } ! 538: return (ltime); ! 539: } ! 540: ! 541: /* ! 542: * to_bsd_time - convert from Mac OS local time (seconds since 1/1/1904) to ! 543: * BSD time (seconds since 1/1/1970) ! 544: */ ! 545: u_int32_t to_bsd_time(u_int32_t hfs_time) ! 546: { ! 547: u_int32_t gmt = LocalToUTC(hfs_time); ! 548: ! 549: if (gmt > MAC_GMT_FACTOR) ! 550: gmt -= MAC_GMT_FACTOR; ! 551: else ! 552: gmt = 0; /* don't let date go negative! */ ! 553: ! 554: return gmt; ! 555: } ! 556: ! 557: /* ! 558: * to_hfs_time - convert from BSD time (seconds since 1/1/1970) to ! 559: * Mac OS local time (seconds since 1/1/1904) ! 560: */ ! 561: u_int32_t to_hfs_time(u_int32_t bsd_time) ! 562: { ! 563: u_int32_t local = bsd_time; ! 564: ! 565: /* don't adjust zero - treat as uninitialzed */ ! 566: if (local != 0) ! 567: local += MAC_GMT_FACTOR; ! 568: ! 569: return UTCToLocal(local); ! 570: } ! 571: ! 572: ! 573: void BlockMove (const void *srcPtr, void *destPtr, Size byteCount) ! 574: { ! 575: ! 576: bcopy(srcPtr, destPtr, byteCount); ! 577: } ! 578: ! 579: void BlockMoveData (const void *srcPtr, void *destPtr, Size byteCount) ! 580: { ! 581: ! 582: bcopy(srcPtr, destPtr, byteCount); ! 583: } ! 584: ! 585: Ptr NewPtr (Size byteCount) ! 586: { ! 587: Ptr tmptr; ! 588: MALLOC (tmptr, Ptr, byteCount , M_TEMP, M_WAITOK); ! 589: return tmptr; ! 590: } ! 591: ! 592: Ptr NewPtrClear (Size byteCount) ! 593: { ! 594: Ptr tmptr; ! 595: MALLOC (tmptr, Ptr, byteCount, M_TEMP, M_WAITOK); ! 596: if (tmptr) ! 597: bzero(tmptr, byteCount); ! 598: return tmptr; ! 599: } ! 600: ! 601: Ptr NewPtrSys (Size byteCount) ! 602: { ! 603: Ptr tmptr; ! 604: MALLOC (tmptr, Ptr, byteCount , M_TEMP, M_WAITOK); ! 605: return tmptr; ! 606: } ! 607: ! 608: Ptr NewPtrSysClear (Size byteCount) ! 609: { ! 610: Ptr tmptr; ! 611: MALLOC (tmptr, Ptr, byteCount, M_TEMP, M_WAITOK); ! 612: if (tmptr) ! 613: bzero(tmptr, byteCount); ! 614: return tmptr; ! 615: } ! 616: ! 617: void DisposePtr (Ptr p) ! 618: { ! 619: FREE (p, M_TEMP); ! 620: ! 621: } ! 622: ! 623: void DebugStr (ConstStr255Param debuggerMsg) ! 624: { ! 625: kprintf ("*** Mac OS Debugging Message: %s\n", &debuggerMsg[1]); ! 626: DEBUG_BREAK; ! 627: } ! 628: ! 629: OSErr MemError (void) ! 630: { ! 631: return 0; ! 632: } ! 633: ! 634: /* ! 635: * GetDiskBlocks ! 636: * ! 637: * Calculate the total number of 512 byte disk blocks in a volume's ! 638: * partition. Used by caller to find the alternate MDB. ! 639: */ ! 640: OSErr GetDiskBlocks(ExtendedVCB *vcb, unsigned long *numBlocks) ! 641: { ! 642: struct proc * p; ! 643: struct ucred * cred; ! 644: struct vnode * devvp; ! 645: unsigned long blocks; ! 646: unsigned long blksize; ! 647: int retval; ! 648: ! 649: devvp = VCBTOHFS(vcb)->hfs_devvp; ! 650: p = CURRENT_PROC; ! 651: cred = p ? p->p_ucred : NOCRED; ! 652: ! 653: retval = VOP_IOCTL(devvp, DKIOCNUMBLKS, &blocks, 0, cred, p); ! 654: if (retval) return retval; ! 655: ! 656: retval = VOP_IOCTL(devvp, DKIOCBLKSIZE, &blksize, 0, cred, p); ! 657: if (retval) return retval; ! 658: ! 659: if (blksize > 512) { ! 660: blocks *= (blksize / 512); ! 661: } ! 662: ! 663: *numBlocks = blocks; ! 664: ! 665: return noErr; ! 666: } ! 667: ! 668: ! 669: /* ! 670: * RequireFileLock ! 671: * ! 672: * Check to see if a vnode is locked in the current context ! 673: * This is to be used for debugging purposes only!! ! 674: */ ! 675: #if DIAGNOSTIC ! 676: void RequireFileLock(FileReference vp, int shareable) ! 677: { ! 678: struct lock__bsd__ *lkp; ! 679: int locked = false; ! 680: pid_t pid; ! 681: void * self; ! 682: ! 683: pid = CURRENT_PROC->p_pid; ! 684: self = (void *) GET_CURRENT_THREAD; ! 685: lkp = &VTOH(vp)->h_lock; ! 686: ! 687: simple_lock(&lkp->lk_interlock); ! 688: ! 689: if (shareable && (lkp->lk_sharecount > 0) && (lkp->lk_lockholder == LK_NOPROC)) ! 690: locked = true; ! 691: else if ((lkp->lk_exclusivecount > 0) && (lkp->lk_lockholder == pid) && (lkp->lk_lockthread == self)) ! 692: locked = true; ! 693: ! 694: simple_unlock(&lkp->lk_interlock); ! 695: ! 696: if (!locked) { ! 697: DBG_VFS((" # context... self=0x%0X, pid=0x%0X, proc=0x%0X\n", (int)self, pid, (int)CURRENT_PROC)); ! 698: DBG_VFS((" # lock state... thread=0x%0X, holder=0x%0X, ex=%d, sh=%d\n", (int)lkp->lk_lockthread, lkp->lk_lockholder, lkp->lk_exclusivecount, lkp->lk_sharecount)); ! 699: ! 700: switch (H_FILEID(VTOH(vp))) { ! 701: case 3: ! 702: DEBUG_BREAK_MSG((" #\n # RequireFileLock: extent btree vnode not locked! v: 0x%08X\n #\n", (u_int)vp)); ! 703: break; ! 704: ! 705: case 4: ! 706: DEBUG_BREAK_MSG((" #\n # RequireFileLock: catalog btree vnode not locked! v: 0x%08X\n #\n", (u_int)vp)); ! 707: break; ! 708: ! 709: default: ! 710: DEBUG_BREAK_MSG((" #\n # RequireFileLock: file (%d) not locked! v: 0x%08X\n #\n", H_FILEID(VTOH(vp)), (u_int)vp)); ! 711: break; ! 712: } ! 713: } ! 714: } ! 715: #endif ! 716:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.