]> git.saurik.com Git - apple/xnu.git/blob - bsd/hfs/MacOSStubs.c
e3ad046157a52436cf38361dd07f7fb8e2c78bf9
[apple/xnu.git] / bsd / hfs / MacOSStubs.c
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /* @(#)MacOSStubs.c 4.0
23 *
24 * (c) 1997-1999 Apple Computer, Inc. All Rights Reserved
25 *
26 * MacOSStubs.c -- Contains routines called by MacOS code, that is not defined.
27 *
28 * HISTORY
29 * 9-9-99 Don Brady Don't use MNT_WAIT in C_FlushMDB.
30 * 9-Mar-1999 Don Brady Remove more obsolete routines, add ClearMemory(bzero).
31 * 20-Nov-1998 Don Brady Remove UFSToHFSStr and HFSToUFSStr routines (obsolete).
32 * 31-Aug-1998 Don Brady Move DST adjustments to GetTimeLocal (radar #2265075).
33 * 28-Jul-1998 Don Brady Add GetDiskBlocks routine (radar #2258148).
34 * 23-Jul-1998 Don Brady Use bdwrite instead of bwrite for default in RelBlock_glue (radar #2257225).
35 * 7-Jul-1998 Don Brady Remove character mappings from/to hfs (ufs_hfs and hfs_ufs tables).
36 * 22-Jun-1998 Pat Dirks Added the vice versa mappings in ufs_hfs and hfs_ufs to more
37 * thoroughly interchange ":" and "/" in name strings.
38 * 4-Jun-1998 Pat Dirks Changed to do all B*-Tree writes synchronously (FORCESYNCBTREEWRITES = 1)
39 * 4-jun-1998 Don Brady Use VPUT macro instead of vput.
40 * 6-may-1998 Don Brady Bump h_devvp refcount in GetInitializedVNode (radar #2232480).
41 * 27-apr-1998 Don Brady Change printf to kprintf.
42 * 23-Apr-1998 Pat Dirks Cleaned up GetBlock_glue to add brelse on I/O errors from bread.
43 * 23-apr-1998 Don Brady Add '/' to ':' mapping and vice versa to mapping tables.
44 * 21-apr-1998 Don Brady Clean up time/date conversion routines.
45 * 11-apr-1998 Don Brady Add RequireFileLock routine.
46 * 8-apr-1998 Don Brady C_FlushMDB now calls hfs_flushvolumeheader and hfs_flushMDB.
47 * 12-nov-1997 Scott Roberts
48 * Initially created file.
49 *
50 */
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/kernel.h>
54 #include <sys/vnode.h>
55 #include <sys/buf.h>
56 #include <sys/malloc.h>
57 #include <sys/mount.h>
58 #include <sys/types.h>
59 #include <sys/ubc.h>
60 #include <sys/vm.h>
61 #include "hfs.h"
62 #include "hfs_dbg.h"
63
64
65 #include "hfscommon/headers/FileMgrInternal.h"
66
67 extern int (**hfs_vnodeop_p)(void *);
68
69
70 /*
71 * gTimeZone should only be used for HFS volumes!
72 * It is initialized when an HFS volume is mounted.
73 */
74 struct timezone gTimeZone = {8*60,1};
75
76
77 /* */
78 /* Creates a new vnode to hold a psuedo file like an extents tree file */
79 /* */
80
81 OSStatus GetInitializedVNode(struct hfsmount *hfsmp, struct vnode **tmpvnode)
82 {
83
84 struct hfsnode *hp;
85 struct vnode *vp = NULL;
86 int rtn;
87
88 DBG_ASSERT(hfsmp != NULL);
89 DBG_ASSERT(tmpvnode != NULL);
90
91 /* Allocate a new hfsnode. */
92 /*
93 * Must do malloc() before getnewvnode(), since malloc() can block
94 * and could cause other part of the system to access v_data
95 * which has not been initialized yet
96 */
97 MALLOC_ZONE(hp, struct hfsnode *, sizeof(struct hfsnode), M_HFSNODE, M_WAITOK);
98 if(hp == NULL) {
99 rtn = ENOMEM;
100 goto Err_Exit;
101 }
102 bzero((caddr_t)hp, sizeof(struct hfsnode));
103 lockinit(&hp->h_lock, PINOD, "hfsnode", 0, 0);
104
105 MALLOC_ZONE(hp->h_meta, struct hfsfilemeta *,
106 sizeof(struct hfsfilemeta), M_HFSFMETA, M_WAITOK);
107 /* Allocate a new vnode. */
108 if ((rtn = getnewvnode(VT_HFS, HFSTOVFS(hfsmp), hfs_vnodeop_p, &vp))) {
109 FREE_ZONE(hp->h_meta, sizeof(struct hfsfilemeta), M_HFSFMETA);
110 FREE_ZONE(hp, sizeof(struct hfsnode), M_HFSNODE);
111 goto Err_Exit;
112 }
113
114 /* Init the structure */
115 bzero(hp->h_meta, sizeof(struct hfsfilemeta));
116
117 hp->h_vp = vp; /* Make HFSTOV work */
118 hp->h_meta->h_devvp = hfsmp->hfs_devvp;
119 hp->h_meta->h_dev = hfsmp->hfs_raw_dev;
120 hp->h_meta->h_usecount++;
121 hp->h_nodeflags |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
122 rl_init(&hp->h_invalidranges);
123 #if HFS_DIAGNOSTIC
124 hp->h_valid = HFS_VNODE_MAGIC;
125 #endif
126 vp->v_data = hp; /* Make VTOH work */
127 vp->v_type = VREG;
128 /*
129 * Metadata files are VREG but not available for IO
130 * through mapped IO as will as POSIX IO APIs.
131 * Hence we do not initialize UBC for those files
132 */
133 vp->v_ubcinfo = UBC_NOINFO;
134
135 *tmpvnode = vp;
136
137 VREF(hp->h_meta->h_devvp);
138
139 return noErr;
140
141 Err_Exit:
142
143 *tmpvnode = NULL;
144
145 return rtn;
146 }
147
148 OSErr C_FlushMDB( ExtendedVCB *volume)
149 {
150 short err;
151
152 if (volume->vcbSigWord == kHFSPlusSigWord)
153 err = hfs_flushvolumeheader(VCBTOHFS(volume), 0);
154 else
155 err = hfs_flushMDB(VCBTOHFS(volume), 0);
156
157 return err;
158 }
159
160
161 /*
162 * GetTimeUTC - get the GMT Mac OS time (in seconds since 1/1/1904)
163 *
164 * called by the Catalog Manager when creating/updating HFS Plus records
165 */
166 UInt32 GetTimeUTC(void)
167 {
168 return (time.tv_sec + MAC_GMT_FACTOR);
169 }
170
171 /*
172 * GetTimeLocal - get the local Mac OS time (in seconds since 1/1/1904)
173 *
174 * called by the Catalog Manager when creating/updating HFS records
175 */
176 UInt32 GetTimeLocal(Boolean forHFS)
177 {
178 UInt32 localTime;
179
180 localTime = UTCToLocal(GetTimeUTC());
181
182 if (forHFS && gTimeZone.tz_dsttime)
183 localTime += 3600;
184
185 return localTime;
186 }
187
188 /*
189 * LocalToUTC - convert from Mac OS local time to Mac OS GMT time.
190 * This should only be called for HFS volumes (not for HFS Plus).
191 */
192 UInt32 LocalToUTC(UInt32 localTime)
193 {
194 UInt32 gtime = localTime;
195
196 if (gtime != 0) {
197 gtime += (gTimeZone.tz_minuteswest * 60);
198 /*
199 * We no longer do DST adjustments here since we don't
200 * know if time supplied needs adjustment!
201 *
202 * if (gTimeZone.tz_dsttime)
203 * gtime -= 3600;
204 */
205 }
206 return (gtime);
207 }
208
209 /*
210 * UTCToLocal - convert from Mac OS GMT time to Mac OS local time.
211 * This should only be called for HFS volumes (not for HFS Plus).
212 */
213 UInt32 UTCToLocal(UInt32 utcTime)
214 {
215 UInt32 ltime = utcTime;
216
217 if (ltime != 0) {
218 ltime -= (gTimeZone.tz_minuteswest * 60);
219 /*
220 * We no longer do DST adjustments here since we don't
221 * know if time supplied needs adjustment!
222 *
223 * if (gTimeZone.tz_dsttime)
224 * ltime += 3600;
225 */
226 }
227 return (ltime);
228 }
229
230 /*
231 * to_bsd_time - convert from Mac OS time (seconds since 1/1/1904)
232 * to BSD time (seconds since 1/1/1970)
233 */
234 u_int32_t to_bsd_time(u_int32_t hfs_time)
235 {
236 u_int32_t gmt = hfs_time;
237
238 if (gmt > MAC_GMT_FACTOR)
239 gmt -= MAC_GMT_FACTOR;
240 else
241 gmt = 0; /* don't let date go negative! */
242
243 return gmt;
244 }
245
246 /*
247 * to_hfs_time - convert from BSD time (seconds since 1/1/1970)
248 * to Mac OS time (seconds since 1/1/1904)
249 */
250 u_int32_t to_hfs_time(u_int32_t bsd_time)
251 {
252 u_int32_t hfs_time = bsd_time;
253
254 /* don't adjust zero - treat as uninitialzed */
255 if (hfs_time != 0)
256 hfs_time += MAC_GMT_FACTOR;
257
258 return (hfs_time);
259 }
260
261
262 void BlockMoveData (const void *srcPtr, void *destPtr, Size byteCount)
263 {
264 bcopy(srcPtr, destPtr, byteCount);
265 }
266
267
268 Ptr NewPtrSysClear (Size byteCount)
269 {
270 Ptr tmptr;
271 MALLOC (tmptr, Ptr, byteCount, M_TEMP, M_WAITOK);
272 if (tmptr)
273 bzero(tmptr, byteCount);
274 return tmptr;
275 }
276
277
278
279 Ptr NewPtr (Size byteCount)
280 {
281 Ptr tmptr;
282 MALLOC (tmptr, Ptr, byteCount, M_TEMP, M_WAITOK);
283 return tmptr;
284 }
285
286
287 void DisposePtr (Ptr p)
288 {
289 FREE (p, M_TEMP);
290 }
291
292
293 void DebugStr (ConstStr255Param debuggerMsg)
294 {
295 kprintf ("*** Mac OS Debugging Message: %s\n", &debuggerMsg[1]);
296 DEBUG_BREAK;
297 }
298
299 OSErr MemError (void)
300 {
301 return 0;
302 }
303
304
305 void ClearMemory( void* start, UInt32 length )
306 {
307 bzero(start, (size_t)length);
308 }
309
310
311 /*
312 * RequireFileLock
313 *
314 * Check to see if a vnode is locked in the current context
315 * This is to be used for debugging purposes only!!
316 */
317 #if HFS_DIAGNOSTIC
318 void RequireFileLock(FileReference vp, int shareable)
319 {
320 struct lock__bsd__ *lkp;
321 int locked = false;
322 pid_t pid;
323 void * self;
324
325 pid = current_proc()->p_pid;
326 self = (void *) current_thread();
327 lkp = &VTOH(vp)->h_lock;
328
329 return;
330
331 simple_lock(&lkp->lk_interlock);
332
333 if (shareable && (lkp->lk_sharecount > 0) && (lkp->lk_lockholder == LK_NOPROC))
334 locked = true;
335 else if ((lkp->lk_exclusivecount > 0) && (lkp->lk_lockholder == pid) && (lkp->lk_lockthread == self))
336 locked = true;
337
338 simple_unlock(&lkp->lk_interlock);
339
340 if (!locked) {
341 DBG_VFS((" # context... self=0x%0X, pid=0x%0X, proc=0x%0X\n", (int)self, pid, (int)current_proc()));
342 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));
343
344 switch (H_FILEID(VTOH(vp))) {
345 case 3:
346 DEBUG_BREAK_MSG((" #\n # RequireFileLock: extent btree vnode not locked! v: 0x%08X\n #\n", (u_int)vp));
347 break;
348
349 case 4:
350 DEBUG_BREAK_MSG((" #\n # RequireFileLock: catalog btree vnode not locked! v: 0x%08X\n #\n", (u_int)vp));
351 break;
352
353 default:
354 DEBUG_BREAK_MSG((" #\n # RequireFileLock: file (%d) not locked! v: 0x%08X\n #\n", H_FILEID(VTOH(vp)), (u_int)vp));
355 break;
356 }
357 }
358 }
359 #endif
360