Annotation of kernel/bsd/hfs/MacOSStubs.c, revision 1.1.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.