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

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: 

unix.superglobalmegacorp.com

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