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