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