#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
#include <sys/buf.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/ubc.h>
#include <sys/vm.h>
#include "hfs.h"
#include "hfs_dbg.h"
#include "hfscommon/headers/FileMgrInternal.h"
extern int (**hfs_vnodeop_p)(void *);
struct timezone gTimeZone = {8*60,1};
OSStatus GetInitializedVNode(struct hfsmount *hfsmp, struct vnode **tmpvnode)
{
struct hfsnode *hp;
struct vnode *vp = NULL;
int rtn;
DBG_ASSERT(hfsmp != NULL);
DBG_ASSERT(tmpvnode != NULL);
MALLOC_ZONE(hp, struct hfsnode *, sizeof(struct hfsnode), M_HFSNODE, M_WAITOK);
if(hp == NULL) {
rtn = ENOMEM;
goto Err_Exit;
}
bzero((caddr_t)hp, sizeof(struct hfsnode));
lockinit(&hp->h_lock, PINOD, "hfsnode", 0, 0);
MALLOC_ZONE(hp->h_meta, struct hfsfilemeta *,
sizeof(struct hfsfilemeta), M_HFSFMETA, M_WAITOK);
if ((rtn = getnewvnode(VT_HFS, HFSTOVFS(hfsmp), hfs_vnodeop_p, &vp))) {
FREE_ZONE(hp->h_meta, sizeof(struct hfsfilemeta), M_HFSFMETA);
FREE_ZONE(hp, sizeof(struct hfsnode), M_HFSNODE);
goto Err_Exit;
}
bzero(hp->h_meta, sizeof(struct hfsfilemeta));
hp->h_vp = vp;
hp->h_meta->h_devvp = hfsmp->hfs_devvp;
hp->h_meta->h_dev = hfsmp->hfs_raw_dev;
hp->h_meta->h_usecount++;
hp->h_nodeflags |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
rl_init(&hp->h_invalidranges);
#if HFS_DIAGNOSTIC
hp->h_valid = HFS_VNODE_MAGIC;
#endif
vp->v_data = hp;
vp->v_type = VREG;
vp->v_ubcinfo = UBC_NOINFO;
*tmpvnode = vp;
VREF(hp->h_meta->h_devvp);
return noErr;
Err_Exit:
*tmpvnode = NULL;
return rtn;
}
OSErr C_FlushMDB( ExtendedVCB *volume)
{
short err;
if (volume->vcbSigWord == kHFSPlusSigWord)
err = hfs_flushvolumeheader(VCBTOHFS(volume), 0);
else
err = hfs_flushMDB(VCBTOHFS(volume), 0);
return err;
}
UInt32 GetTimeUTC(void)
{
return (time.tv_sec + MAC_GMT_FACTOR);
}
UInt32 GetTimeLocal(Boolean forHFS)
{
UInt32 localTime;
localTime = UTCToLocal(GetTimeUTC());
if (forHFS && gTimeZone.tz_dsttime)
localTime += 3600;
return localTime;
}
UInt32 LocalToUTC(UInt32 localTime)
{
UInt32 gtime = localTime;
if (gtime != 0) {
gtime += (gTimeZone.tz_minuteswest * 60);
}
return (gtime);
}
UInt32 UTCToLocal(UInt32 utcTime)
{
UInt32 ltime = utcTime;
if (ltime != 0) {
ltime -= (gTimeZone.tz_minuteswest * 60);
}
return (ltime);
}
u_int32_t to_bsd_time(u_int32_t hfs_time)
{
u_int32_t gmt = hfs_time;
if (gmt > MAC_GMT_FACTOR)
gmt -= MAC_GMT_FACTOR;
else
gmt = 0;
return gmt;
}
u_int32_t to_hfs_time(u_int32_t bsd_time)
{
u_int32_t hfs_time = bsd_time;
if (hfs_time != 0)
hfs_time += MAC_GMT_FACTOR;
return (hfs_time);
}
void BlockMoveData (const void *srcPtr, void *destPtr, Size byteCount)
{
bcopy(srcPtr, destPtr, byteCount);
}
Ptr NewPtrSysClear (Size byteCount)
{
Ptr tmptr;
MALLOC (tmptr, Ptr, byteCount, M_TEMP, M_WAITOK);
if (tmptr)
bzero(tmptr, byteCount);
return tmptr;
}
Ptr NewPtr (Size byteCount)
{
Ptr tmptr;
MALLOC (tmptr, Ptr, byteCount, M_TEMP, M_WAITOK);
return tmptr;
}
void DisposePtr (Ptr p)
{
FREE (p, M_TEMP);
}
void DebugStr (ConstStr255Param debuggerMsg)
{
kprintf ("*** Mac OS Debugging Message: %s\n", &debuggerMsg[1]);
DEBUG_BREAK;
}
OSErr MemError (void)
{
return 0;
}
void ClearMemory( void* start, UInt32 length )
{
bzero(start, (size_t)length);
}
#if HFS_DIAGNOSTIC
void RequireFileLock(FileReference vp, int shareable)
{
struct lock__bsd__ *lkp;
int locked = false;
pid_t pid;
void * self;
pid = current_proc()->p_pid;
self = (void *) current_thread();
lkp = &VTOH(vp)->h_lock;
return;
simple_lock(&lkp->lk_interlock);
if (shareable && (lkp->lk_sharecount > 0) && (lkp->lk_lockholder == LK_NOPROC))
locked = true;
else if ((lkp->lk_exclusivecount > 0) && (lkp->lk_lockholder == pid) && (lkp->lk_lockthread == self))
locked = true;
simple_unlock(&lkp->lk_interlock);
if (!locked) {
DBG_VFS((" # context... self=0x%0X, pid=0x%0X, proc=0x%0X\n", (int)self, pid, (int)current_proc()));
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));
switch (H_FILEID(VTOH(vp))) {
case 3:
DEBUG_BREAK_MSG((" #\n # RequireFileLock: extent btree vnode not locked! v: 0x%08X\n #\n", (u_int)vp));
break;
case 4:
DEBUG_BREAK_MSG((" #\n # RequireFileLock: catalog btree vnode not locked! v: 0x%08X\n #\n", (u_int)vp));
break;
default:
DEBUG_BREAK_MSG((" #\n # RequireFileLock: file (%d) not locked! v: 0x%08X\n #\n", H_FILEID(VTOH(vp)), (u_int)vp));
break;
}
}
}
#endif