Annotation of XNU/bsd/hfs/MacOSStubs.c, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.