]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/hfs/hfs_hotfiles.c
xnu-2782.40.9.tar.gz
[apple/xnu.git] / bsd / hfs / hfs_hotfiles.c
index 77d00fc75c9da8b6d2cda6be72254f4e8c0c7e3c..7ba80c737bc31470fd4394d89797d58be24a9c07 100644 (file)
@@ -1,31 +1,29 @@
 /*
- * Copyright (c) 2003-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003-2013 Apple Inc. All rights reserved.
  *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * This file contains Original Code and/or Modifications of Original Code 
- * as defined in and that are subject to the Apple Public Source License 
- * Version 2.0 (the 'License'). You may not use this file except in 
- * compliance with the License.  The rights granted to you under the 
- * License may not be used to create, or enable the creation or 
- * redistribution of, unlawful or unlicensed copies of an Apple operating 
- * system, or to circumvent, violate, or enable the circumvention or 
- * violation of, any terms of an Apple operating system software license 
- * agreement.
- *
- * Please obtain a copy of the License at 
- * http://www.opensource.apple.com/apsl/ and read it before using this 
- * file.
- *
- * The Original Code and all software distributed under the License are 
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
- * Please see the License for the specific language governing rights and 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
  * limitations under the License.
- *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
 #include <sys/param.h>
@@ -34,6 +32,7 @@
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/ubc.h>
+#include <sys/ubc_internal.h>
 #include <sys/vnode.h>
 #include <sys/vnode_internal.h>
 #include <sys/kauth.h>
 #define HFC_VERBOSE 0
 
 
+/*
+ * Minimum post Tiger base time.
+ * Thu Mar 31 17:00:00 2005
+ */
+#define HFC_MIN_BASE_TIME   0x424c8f00L
 
 /*
  * Hot File List (runtime).
@@ -125,7 +129,7 @@ static void  hf_printtree (hotfile_entry_t *);
 static int  hotfiles_collect (struct hfsmount *);
 static int  hotfiles_age (struct hfsmount *);
 static int  hotfiles_adopt (struct hfsmount *);
-static int  hotfiles_evict (struct hfsmount *, struct proc *);
+static int  hotfiles_evict (struct hfsmount *, vfs_context_t);
 static int  hotfiles_refine (struct hfsmount *);
 static int  hotextents(struct hfsmount *, HFSPlusExtentDescriptor *);
 static int  hfs_addhotfile_internal(struct vnode *);
@@ -134,7 +138,7 @@ static int  hfs_addhotfile_internal(struct vnode *);
 /*
  * Hot File Cluster B-tree (on disk) functions.
  */
-static int  hfc_btree_create (struct hfsmount *, int, int);
+static int  hfc_btree_create (struct hfsmount *, unsigned int, unsigned int);
 static int  hfc_btree_open (struct hfsmount *, struct vnode **);
 static int  hfc_btree_close (struct hfsmount *, struct vnode *);
 static int  hfc_comparekeys (HotFileKey *, HotFileKey *);
@@ -142,9 +146,6 @@ static int  hfc_comparekeys (HotFileKey *, HotFileKey *);
 
 char hfc_tag[] = "CLUSTERED HOT FILES B-TREE     ";
 
-extern int  UBCINFOEXISTS(struct vnode * vp);
-extern int  hfs_vnop_write(struct vnop_write_args *ap);
-
 
 /*
  *========================================================================
@@ -191,7 +192,7 @@ hfs_recording_start(struct hfsmount *hfsmp)
                FREE(tmp, M_TEMP);
        }
 
-       microuptime(&tv);
+       microtime(&tv);  /* Times are base on GMT time. */
 
        /*
         * On first startup check for suspended recording.
@@ -206,10 +207,14 @@ hfs_recording_start(struct hfsmount *hfsmp)
                    (SWAP_BE32 (hotfileinfo.timeleft) > 0) &&
                    (SWAP_BE32 (hotfileinfo.timebase) > 0)) {
                        hfsmp->hfc_maxfiles = SWAP_BE32 (hotfileinfo.maxfilecnt);
-                       hfsmp->hfc_timeout = SWAP_BE32 (hotfileinfo.timeleft) + tv.tv_sec ;
                        hfsmp->hfc_timebase = SWAP_BE32 (hotfileinfo.timebase);
+                       hfsmp->hfc_timeout = SWAP_BE32 (hotfileinfo.timeleft) + tv.tv_sec ;
+                       /* Fix up any bogus timebase values. */
+                       if (hfsmp->hfc_timebase < HFC_MIN_BASE_TIME) {
+                               hfsmp->hfc_timebase = hfsmp->hfc_timeout - HFC_DEFAULT_DURATION;
+                       }
 #if HFC_VERBOSE
-                       printf("Resume recording hot files on %s (%d secs left)\n",
+                       printf("hfs: Resume recording hot files on %s (%d secs left)\n",
                                hfsmp->vcbVN, SWAP_BE32 (hotfileinfo.timeleft));
 #endif
                } else {
@@ -235,7 +240,7 @@ hfs_recording_start(struct hfsmount *hfsmp)
                        return (error);
                }
 #if HFC_VERBOSE
-               printf("HFS: begin recording hot files on %s\n", hfsmp->vcbVN);
+               printf("hfs: begin recording hot files on %s\n", hfsmp->vcbVN);
 #endif
                hfsmp->hfc_maxfiles = HFC_DEFAULT_FILE_COUNT;
                hfsmp->hfc_timeout = tv.tv_sec + HFC_DEFAULT_DURATION;
@@ -259,6 +264,13 @@ hfs_recording_start(struct hfsmount *hfsmp)
 
        size = sizeof(hotfile_data_t) + (maxentries * sizeof(hotfile_entry_t));
        MALLOC(hotdata, hotfile_data_t *, size, M_TEMP, M_WAITOK);
+       if (hotdata == NULL) {
+               hfsmp->hfc_recdata = NULL;
+               hfsmp->hfc_stage = HFC_IDLE;
+               wakeup((caddr_t)&hfsmp->hfc_stage);
+               return(ENOMEM);
+       }
+
        bzero(hotdata, size);
 
        for (i = 1; i < maxentries ; i++)
@@ -296,12 +308,10 @@ hfs_recording_stop(struct hfsmount *hfsmp)
        if (hfsmp->hfc_stage != HFC_RECORDING)
                return (EPERM);
 
-       hotfiles_collect(hfsmp);
+       hfsmp->hfc_stage = HFC_BUSY;
 
-       if (hfsmp->hfc_stage != HFC_RECORDING)
-               return (0);
+       hotfiles_collect(hfsmp);
 
-       hfsmp->hfc_stage = HFC_BUSY;
 
        /*
         * Convert hot file data into a simple file id list....
@@ -309,7 +319,7 @@ hfs_recording_stop(struct hfsmount *hfsmp)
         * then dump the sample data
         */
 #if HFC_VERBOSE
-       printf("HFS: end of hot file recording on %s\n", hfsmp->vcbVN);
+       printf("hfs: end of hot file recording on %s\n", hfsmp->vcbVN);
 #endif
        hotdata = (hotfile_data_t *)hfsmp->hfc_recdata;
        if (hotdata == NULL)
@@ -319,7 +329,7 @@ hfs_recording_stop(struct hfsmount *hfsmp)
        wakeup((caddr_t)&hfsmp->hfc_stage);
 
 #if HFC_VERBOSE
-       printf("  curentries: %d\n", hotdata->activefiles);
+       printf("hfs:   curentries: %d\n", hotdata->activefiles);
 #endif
        /*
         * If no hot files recorded then we're done.
@@ -331,7 +341,7 @@ hfs_recording_stop(struct hfsmount *hfsmp)
 
        /* Open the B-tree file for writing... */
        if (hfsmp->hfc_filevp)
-               panic("hfs_recording_stop: hfc_filevp exists (vp = 0x%08x)", hfsmp->hfc_filevp);
+               panic("hfs_recording_stop: hfc_filevp exists (vp = %p)", hfsmp->hfc_filevp);
 
        error = hfc_btree_open(hfsmp, &hfsmp->hfc_filevp);
        if (error) {
@@ -354,10 +364,17 @@ hfs_recording_stop(struct hfsmount *hfsmp)
        size = sizeof(hotfilelist_t);
        size += sizeof(hotfileinfo_t) * (hotdata->activefiles - 1);
        MALLOC(listp, hotfilelist_t *, size, M_TEMP, M_WAITOK);
+       if (listp == NULL) {
+               error = ENOMEM;
+               (void) hfc_btree_close(hfsmp, hfsmp->hfc_filevp);
+               hfsmp->hfc_filevp = NULL;
+               goto out;
+       }
+
        bzero(listp, size);
 
        hf_getsortedlist(hotdata, listp);       /* NOTE: destroys hot file tree! */
-       microuptime(&tv);
+       microtime(&tv);
        listp->hfl_duration = tv.tv_sec - hfsmp->hfc_timebase;
        hfsmp->hfc_recdata = listp;
 
@@ -397,9 +414,9 @@ hfs_recording_stop(struct hfsmount *hfsmp)
 out:
 #if HFC_VERBOSE
        if (newstage == HFC_EVICTION)
-               printf("HFS: evicting coldest files\n");
+               printf("hfs: evicting coldest files\n");
        else if (newstage == HFC_ADOPTION)
-               printf("HFS: adopting hotest files\n");
+               printf("hfs: adopting hotest files\n");
 #endif
        FREE(hotdata, M_TEMP);
 
@@ -411,7 +428,6 @@ out:
 /*
  * Suspend recording the hotest files on a file system.
  */
-__private_extern__
 int
 hfs_recording_suspend(struct hfsmount *hfsmp)
 {
@@ -440,7 +456,7 @@ hfs_recording_suspend(struct hfsmount *hfsmp)
        hfsmp->hfc_stage = HFC_BUSY;
 
 #if HFC_VERBOSE
-       printf("HFS: suspend hot file recording on %s\n", hfsmp->vcbVN);
+       printf("hfs: suspend hot file recording on %s\n", hfsmp->vcbVN);
 #endif
        error = hfc_btree_open(hfsmp, &hfsmp->hfc_filevp);
        if (error) {
@@ -452,12 +468,12 @@ hfs_recording_suspend(struct hfsmount *hfsmp)
            error = EINVAL;
            goto out;
        }
-       if (hfs_lock(VTOC(hfsmp->hfc_filevp), HFS_EXCLUSIVE_LOCK) != 0) {
+       if (hfs_lock(VTOC(hfsmp->hfc_filevp), HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT) != 0) {
                error = EPERM;
-               goto out;
+               goto end_transaction;
        }
 
-       microuptime(&tv);
+       microtime(&tv);
        hotfileinfo.magic       = SWAP_BE32 (HFC_MAGIC);
        hotfileinfo.version     = SWAP_BE32 (HFC_VERSION);
        hotfileinfo.duration    = SWAP_BE32 (HFC_DEFAULT_DURATION);
@@ -466,11 +482,14 @@ hfs_recording_suspend(struct hfsmount *hfsmp)
        hotfileinfo.threshold   = SWAP_BE32 (hotdata->threshold);
        hotfileinfo.maxfileblks = SWAP_BE32 (hotdata->maxblocks);
        hotfileinfo.maxfilecnt  = SWAP_BE32 (HFC_DEFAULT_FILE_COUNT);
-       strcpy(hotfileinfo.tag, hfc_tag);
+       strlcpy((char *)hotfileinfo.tag, hfc_tag, sizeof hotfileinfo.tag);
        (void) BTSetUserData(VTOF(hfsmp->hfc_filevp), &hotfileinfo, sizeof(hotfileinfo));
 
        hfs_unlock(VTOC(hfsmp->hfc_filevp));
+
+end_transaction:
        hfs_end_transaction(hfsmp);
+
 out:
        if (hfsmp->hfc_filevp) {
                (void) hfc_btree_close(hfsmp, hfsmp->hfc_filevp);
@@ -482,7 +501,7 @@ out:
        }
        hfsmp->hfc_stage = HFC_DISABLED;
        wakeup((caddr_t)&hfsmp->hfc_stage);
-exit:
+
        lck_mtx_unlock(&hfsmp->hfc_mutex);
        return (error);
 }
@@ -491,7 +510,6 @@ exit:
 /*
  *
  */
-__private_extern__
 int
 hfs_recording_init(struct hfsmount *hfsmp)
 {
@@ -500,7 +518,7 @@ hfs_recording_init(struct hfsmount *hfsmp)
        u_int32_t  dataSize;
        HFSPlusCatalogFile *filep;
        BTScanState scanstate;
-       BTreeIterator * iterator;
+       BTreeIterator * iterator = NULL;
        FSBufferDescriptor  record;
        HotFileKey * key;
        filefork_t * filefork;
@@ -520,6 +538,16 @@ hfs_recording_init(struct hfsmount *hfsmp)
                return (EPERM);
        }
 
+       /*
+        * Tracking of hot files requires up-to-date access times.
+        * So if access time updates are disabled, then we disable
+        * hot files, too.
+        */
+       if (vfs_flags(HFSTOVFS(hfsmp)) & MNT_NOATIME) {
+               hfsmp->hfc_stage = HFC_DISABLED;
+               return EPERM;
+       }
+       
        /*
         * If the Hot File btree exists then metadata zone is ready.
         */
@@ -529,26 +557,37 @@ hfs_recording_init(struct hfsmount *hfsmp)
                        hfsmp->hfc_stage = HFC_IDLE;
                return (0);
        }
+
+       if (hfs_start_transaction(hfsmp) != 0) {
+               return EINVAL;
+       }
+
        error = hfc_btree_create(hfsmp, HFSTOVCB(hfsmp)->blockSize, HFC_DEFAULT_FILE_COUNT);
        if (error) {
 #if HFC_VERBOSE
-               printf("Error %d creating hot file b-tree on %s \n", error, hfsmp->vcbVN);
+               printf("hfs: Error %d creating hot file b-tree on %s \n", error, hfsmp->vcbVN);
 #endif
-               return (error);
+               goto out2;
        }
        /*
         * Open the Hot File B-tree file for writing.
         */
        if (hfsmp->hfc_filevp)
-               panic("hfs_recording_init: hfc_filevp exists (vp = 0x%08x)", hfsmp->hfc_filevp);
+               panic("hfs_recording_init: hfc_filevp exists (vp = %p)", hfsmp->hfc_filevp);
        error = hfc_btree_open(hfsmp, &hfsmp->hfc_filevp);
        if (error) {
 #if HFC_VERBOSE
-               printf("Error %d opening hot file b-tree on %s \n", error, hfsmp->vcbVN);
+               printf("hfs: Error %d opening hot file b-tree on %s \n", error, hfsmp->vcbVN);
 #endif
-               return (error);
+               goto out2;
        }
        MALLOC(iterator, BTreeIterator *, sizeof(*iterator), M_TEMP, M_WAITOK);
+       if (iterator == NULL) {
+               error = ENOMEM;
+               (void) hfc_btree_close(hfsmp, hfsmp->hfc_filevp);
+               hfsmp->hfc_filevp = NULL;
+               goto out2;
+       }
        bzero(iterator, sizeof(*iterator));
        key = (HotFileKey*) &iterator->key;
        key->keyLength = HFC_KEYLENGTH;
@@ -557,7 +596,7 @@ hfs_recording_init(struct hfsmount *hfsmp)
        record.itemSize = sizeof(u_int32_t);
        record.itemCount = 1;
 #if HFC_VERBOSE
-       printf("Evaluating space for \"%s\" metadata zone...\n", HFSTOVCB(hfsmp)->vcbVN);
+       printf("hfs: Evaluating space for \"%s\" metadata zone...\n", HFSTOVCB(hfsmp)->vcbVN);
 #endif
        /*
         * Get ready to scan the Catalog file.
@@ -576,9 +615,9 @@ hfs_recording_init(struct hfsmount *hfsmp)
            error = EINVAL;
            goto out1;
        } 
-       if (hfs_lock(VTOC(hfsmp->hfc_filevp), HFS_EXCLUSIVE_LOCK) != 0) {
+       if (hfs_lock(VTOC(hfsmp->hfc_filevp), HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT) != 0) {
                error = EPERM;
-               goto out1;
+               goto out0;
        }
        filefork = VTOF(hfsmp->hfc_filevp);
 
@@ -652,15 +691,18 @@ hfs_recording_init(struct hfsmount *hfsmp)
        (void) BTFlushPath(filefork);
        hfs_unlock(VTOC(hfsmp->hfc_filevp));
 
+out0:
        hfs_end_transaction(hfsmp);
 #if HFC_VERBOSE
-       printf("%d files identified out of %d\n", inserted, filecount);
+       printf("hfs: %d files identified out of %d\n", inserted, filecount);
 #endif
        
 out1:
        (void) BTScanTerminate(&scanstate, &data, &data, &data);
 out2:  
-       FREE(iterator, M_TEMP);
+       hfs_end_transaction(hfsmp);
+       if (iterator)
+               FREE(iterator, M_TEMP);
        if (hfsmp->hfc_filevp) {
                (void) hfc_btree_close(hfsmp, hfsmp->hfc_filevp);
                hfsmp->hfc_filevp = NULL;
@@ -674,9 +716,8 @@ out2:
 /*
  * Use sync to perform ocassional background work.
  */
-__private_extern__
 int
-hfs_hotfilesync(struct hfsmount *hfsmp, struct proc *p)
+hfs_hotfilesync(struct hfsmount *hfsmp, vfs_context_t ctx)
 {
        if (hfsmp->hfc_stage) {
                struct timeval tv;
@@ -689,13 +730,13 @@ hfs_hotfilesync(struct hfsmount *hfsmp, struct proc *p)
                        break;
        
                case HFC_RECORDING:
-                       microuptime(&tv);
+                       microtime(&tv);
                        if (tv.tv_sec > hfsmp->hfc_timeout)
                                (void) hfs_recording_stop(hfsmp);
                        break;
        
                case HFC_EVICTION:
-                       (void) hotfiles_evict(hfsmp, p);
+                       (void) hotfiles_evict(hfsmp, ctx);
                        break;
        
                case HFC_ADOPTION:
@@ -721,7 +762,6 @@ hfs_hotfilesync(struct hfsmount *hfsmp, struct proc *p)
  *
  * Note: the cnode is locked on entry.
  */
-__private_extern__
 int
 hfs_addhotfile(struct vnode *vp)
 {
@@ -752,9 +792,17 @@ hfs_addhotfile_internal(struct vnode *vp)
        if (hfsmp->hfc_stage != HFC_RECORDING)
                return (0);
 
-       if ((!vnode_isreg(vp) && !vnode_islnk(vp)) || vnode_issystem(vp)) {
+       /* 
+        * Only regular files are eligible for hotfiles addition. 
+        * 
+        * Symlinks were previously added to the list and may exist in 
+        * extant hotfiles regions, but no new ones will be added, and no
+        * symlinks will now be relocated/evicted from the hotfiles region.
+        */
+       if (!vnode_isreg(vp) || vnode_issystem(vp)) {
                return (0);
        }
+
        /* Skip resource forks for now. */
        if (VNODE_IS_RSRC(vp)) {
                return (0);
@@ -767,9 +815,10 @@ hfs_addhotfile_internal(struct vnode *vp)
 
        if ((ffp->ff_bytesread == 0) ||
            (ffp->ff_blocks == 0) ||
+           (ffp->ff_size == 0) ||
            (ffp->ff_blocks > hotdata->maxblocks) ||
            (cp->c_flag & (C_DELETED | C_NOEXISTS)) ||
-           (cp->c_flags & UF_NODUMP) ||
+           (cp->c_bsdflags & UF_NODUMP) ||
            (cp->c_atime < hfsmp->hfc_timebase)) {
                return (0);
        }
@@ -808,7 +857,6 @@ hfs_addhotfile_internal(struct vnode *vp)
  *
  * Note: the cnode is locked on entry.
  */
-__private_extern__
 int
 hfs_removehotfile(struct vnode *vp)
 {
@@ -822,7 +870,7 @@ hfs_removehotfile(struct vnode *vp)
        if (hfsmp->hfc_stage != HFC_RECORDING)
                return (0);
 
-       if ((!vnode_isreg(vp) && !vnode_islnk(vp)) || vnode_issystem(vp)) {
+       if ((!vnode_isreg(vp)) || vnode_issystem(vp)) {
                return (0);
        }
 
@@ -830,7 +878,7 @@ hfs_removehotfile(struct vnode *vp)
        cp = VTOC(vp);
 
        if ((ffp->ff_bytesread == 0) || (ffp->ff_blocks == 0) ||
-           (cp->c_atime < hfsmp->hfc_timebase)) {
+           (ffp->ff_size == 0) || (cp->c_atime < hfsmp->hfc_timebase)) {
                return (0);
        }
 
@@ -864,7 +912,7 @@ out:
 static int
 hotfiles_collect_callback(struct vnode *vp, __unused void *cargs)
 {
-        if ((vnode_isreg(vp) || vnode_islnk(vp)) && !vnode_issystem(vp))
+        if ((vnode_isreg(vp)) && !vnode_issystem(vp))
                (void) hfs_addhotfile_internal(vp);
 
        return (VNODE_RETURNED);
@@ -913,7 +961,7 @@ update_callback(const HotFileKey *key, u_int32_t *data, u_int32_t *state)
 static int
 hotfiles_refine(struct hfsmount *hfsmp)
 {
-       BTreeIterator * iterator;
+       BTreeIterator * iterator = NULL;
        struct mount *mp;
        filefork_t * filefork;
        hotfilelist_t  *listp;
@@ -930,6 +978,10 @@ hotfiles_refine(struct hfsmount *hfsmp)
        mp = HFSTOVFS(hfsmp);
 
        MALLOC(iterator, BTreeIterator *, sizeof(*iterator), M_TEMP, M_WAITOK);
+       if (iterator == NULL) {
+               error = ENOMEM;
+               goto out;
+       }
        bzero(iterator, sizeof(*iterator));
        key = (HotFileKey*) &iterator->key;
 
@@ -941,9 +993,9 @@ hotfiles_refine(struct hfsmount *hfsmp)
            error = EINVAL;
            goto out;
        } 
-       if (hfs_lock(VTOC(hfsmp->hfc_filevp), HFS_EXCLUSIVE_LOCK) != 0) {
+       if (hfs_lock(VTOC(hfsmp->hfc_filevp), HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT) != 0) {
                error = EPERM;
-               goto out;
+               goto out1;
        }
        filefork = VTOF(hfsmp->hfc_filevp);
 
@@ -967,7 +1019,7 @@ hotfiles_refine(struct hfsmount *hfsmp)
                                (IterateCallBackProcPtr)update_callback,
                                &listp->hfl_hotfile[i].hf_temperature);
                if (error) {
-                       printf("hotfiles_refine: BTUpdateRecord failed %d (file %d)\n", error, key->fileID);
+                       printf("hfs: hotfiles_refine: BTUpdateRecord failed %d (file %d)\n", error, key->fileID);
                        error = MacToVFSError(error);
                //      break;
                }
@@ -983,7 +1035,7 @@ hotfiles_refine(struct hfsmount *hfsmp)
                (void) BTSearchRecord(filefork, iterator, &record, NULL, iterator);
                error = BTDeleteRecord(filefork, iterator);
                if (error) {
-                       printf("hotfiles_refine: BTDeleteRecord failed %d (file %d)\n", error, key->fileID);
+                       printf("hfs: hotfiles_refine: BTDeleteRecord failed %d (file %d)\n", error, key->fileID);
                        error = MacToVFSError(error);
                        break;
                }
@@ -993,7 +1045,7 @@ hotfiles_refine(struct hfsmount *hfsmp)
                key->forkType = 0;
                error = BTInsertRecord(filefork, iterator, &record, record.itemSize);
                if (error) {
-                       printf("hotfiles_refine: BTInsertRecord failed %d (file %d)\n", error, key->fileID);
+                       printf("hfs: hotfiles_refine: BTInsertRecord failed %d (file %d)\n", error, key->fileID);
                        error = MacToVFSError(error);
                        break;
                }
@@ -1009,9 +1061,11 @@ hotfiles_refine(struct hfsmount *hfsmp)
        (void) BTFlushPath(filefork);
        hfs_unlock(VTOC(hfsmp->hfc_filevp));
 
+out1:
        hfs_end_transaction(hfsmp);
 out:
-       FREE(iterator, M_TEMP); 
+       if (iterator)
+               FREE(iterator, M_TEMP); 
        return (error);
 }
 
@@ -1023,7 +1077,7 @@ out:
 static int
 hotfiles_adopt(struct hfsmount *hfsmp)
 {
-       BTreeIterator * iterator;
+       BTreeIterator * iterator = NULL;
        struct vnode *vp;
        filefork_t * filefork;
        hotfilelist_t  *listp;
@@ -1044,10 +1098,16 @@ hotfiles_adopt(struct hfsmount *hfsmp)
        if (hfsmp->hfc_stage != HFC_ADOPTION) {
                return (EBUSY);
        }
-       if (hfs_lock(VTOC(hfsmp->hfc_filevp), HFS_EXCLUSIVE_LOCK) != 0) {
+       if (hfs_lock(VTOC(hfsmp->hfc_filevp), HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT) != 0) {
                return (EPERM);
        }
 
+       MALLOC(iterator, BTreeIterator *, sizeof(*iterator), M_TEMP, M_WAITOK);
+       if (iterator == NULL) {
+               hfs_unlock(VTOC(hfsmp->hfc_filevp));
+               return (ENOMEM);
+       }
+
        stage = hfsmp->hfc_stage;
        hfsmp->hfc_stage = HFC_BUSY;
 
@@ -1056,7 +1116,6 @@ hotfiles_adopt(struct hfsmount *hfsmp)
        if (last > listp->hfl_count)
                last = listp->hfl_count;
 
-       MALLOC(iterator, BTreeIterator *, sizeof(*iterator), M_TEMP, M_WAITOK);
        bzero(iterator, sizeof(*iterator));
        key = (HotFileKey*) &iterator->key;
        key->keyLength = HFC_KEYLENGTH;
@@ -1078,7 +1137,7 @@ hotfiles_adopt(struct hfsmount *hfsmp)
                /*
                 * Acquire a vnode for this file.
                 */
-               error = hfs_vget(hfsmp, listp->hfl_hotfile[i].hf_fileid, &vp, 0);
+               error = hfs_vget(hfsmp, listp->hfl_hotfile[i].hf_fileid, &vp, 0, 0);
                if (error) {
                        if (error == ENOENT) {
                                error = 0;
@@ -1087,8 +1146,9 @@ hotfiles_adopt(struct hfsmount *hfsmp)
                        }
                        break;
                }
-               if (!vnode_isreg(vp) && !vnode_islnk(vp)) {
-                       printf("hotfiles_adopt: huh, not a file %d (%d)\n", listp->hfl_hotfile[i].hf_fileid, VTOC(vp)->c_cnid);
+               if (!vnode_isreg(vp)) {
+                       /* Symlinks are ineligible for adoption into the hotfile zone.  */
+                       printf("hfs: hotfiles_adopt: huh, not a file %d (%d)\n", listp->hfl_hotfile[i].hf_fileid, VTOC(vp)->c_cnid);
                        hfs_unlock(VTOC(vp));
                        vnode_put(vp);
                        listp->hfl_hotfile[i].hf_temperature = 0;
@@ -1118,26 +1178,19 @@ hotfiles_adopt(struct hfsmount *hfsmp)
                        vnode_put(vp);
                        break;  /* adopt this entry the next time around */
                }
-               /* Start a new transaction. */
-               if (hfs_start_transaction(hfsmp) != 0) {
-                   error = EINVAL;
-                   hfs_unlock(VTOC(vp));
-                   vnode_put(vp);
-                   break;
-               }
-               startedtrans = 1;
-
                if (VTOC(vp)->c_desc.cd_nameptr)
-                       data = *(u_int32_t *)(VTOC(vp)->c_desc.cd_nameptr);
+                       data = *(const u_int32_t *)(VTOC(vp)->c_desc.cd_nameptr);
                else
                        data = 0x3f3f3f3f;
 
                error = hfs_relocate(vp, hfsmp->hfs_hotfile_start, kauth_cred_get(), current_proc());
                hfs_unlock(VTOC(vp));
                vnode_put(vp);
-               if (error)
-                       break;
-               
+               if (error) {
+                       /* Move on to next item. */
+                       listp->hfl_next++;
+                       continue;
+               }
                /* Keep hot file free space current. */
                hfsmp->hfs_hotfile_freeblks -= fileblocks;
                listp->hfl_totalblocks -= fileblocks;
@@ -1148,9 +1201,16 @@ hotfiles_adopt(struct hfsmount *hfsmp)
                key->fileID      = listp->hfl_hotfile[i].hf_fileid;
                key->forkType    = 0;
 
+               /* Start a new transaction before calling BTree code. */
+               if (hfs_start_transaction(hfsmp) != 0) {
+                   error = EINVAL;
+                   break;
+               }
+               startedtrans = 1;
+
                error = BTInsertRecord(filefork, iterator, &record, record.itemSize);
                if (error) {
-                       printf("hotfiles_adopt: BTInsertRecord failed %d (fileid %d)\n", error, key->fileID);
+                       printf("hfs: hotfiles_adopt: BTInsertRecord failed %d (fileid %d)\n", error, key->fileID);
                        error = MacToVFSError(error);
                        stage = HFC_IDLE;
                        break;
@@ -1164,7 +1224,7 @@ hotfiles_adopt(struct hfsmount *hfsmp)
                data = listp->hfl_hotfile[i].hf_temperature;
                error = BTInsertRecord(filefork, iterator, &record, record.itemSize);
                if (error) {
-                       printf("hotfiles_adopt: BTInsertRecord failed %d (fileid %d)\n", error, key->fileID);
+                       printf("hfs: hotfiles_adopt: BTInsertRecord failed %d (fileid %d)\n", error, key->fileID);
                        error = MacToVFSError(error);
                        stage = HFC_IDLE;
                        break;
@@ -1184,14 +1244,14 @@ hotfiles_adopt(struct hfsmount *hfsmp)
                }
                if (hfsmp->hfs_hotfile_freeblks <= 0) {
 #if HFC_VERBOSE
-                       printf("hotfiles_adopt: free space exhausted (%d)\n", hfsmp->hfs_hotfile_freeblks);
+                       printf("hfs: hotfiles_adopt: free space exhausted (%d)\n", hfsmp->hfs_hotfile_freeblks);
 #endif
                        break;
                }
        } /* end for */
 
 #if HFC_VERBOSE
-       printf("hotfiles_adopt: [%d] adopted %d blocks (%d left)\n", listp->hfl_next, blksmoved, listp->hfl_totalblocks);
+       printf("hfs: hotfiles_adopt: [%d] adopted %d blocks (%d left)\n", listp->hfl_next, blksmoved, listp->hfl_totalblocks);
 #endif
        /* Finish any outstanding transactions. */
        if (startedtrans) {
@@ -1203,8 +1263,8 @@ hotfiles_adopt(struct hfsmount *hfsmp)
 
        if ((listp->hfl_next >= listp->hfl_count) || (hfsmp->hfs_hotfile_freeblks <= 0)) {
 #if HFC_VERBOSE
-               printf("hotfiles_adopt: all done relocating %d files\n", listp->hfl_count);
-               printf("hotfiles_adopt: %d blocks free in hot file band\n", hfsmp->hfs_hotfile_freeblks);
+               printf("hfs: hotfiles_adopt: all done relocating %d files\n", listp->hfl_count);
+               printf("hfs: hotfiles_adopt: %d blocks free in hot file band\n", hfsmp->hfs_hotfile_freeblks);
 #endif
                stage = HFC_IDLE;
        }
@@ -1225,9 +1285,9 @@ hotfiles_adopt(struct hfsmount *hfsmp)
  * Requires that the hfc_mutex be held.
  */
 static int
-hotfiles_evict(struct hfsmount *hfsmp, struct proc *p)
+hotfiles_evict(struct hfsmount *hfsmp, vfs_context_t ctx)
 {
-       BTreeIterator * iterator;
+       BTreeIterator * iterator = NULL;
        struct vnode *vp;
        HotFileKey * key;
        filefork_t * filefork;
@@ -1248,17 +1308,22 @@ hotfiles_evict(struct hfsmount *hfsmp, struct proc *p)
        if ((listp = (hotfilelist_t  *)hfsmp->hfc_recdata) == NULL)
                return (0);     
 
-       if (hfs_lock(VTOC(hfsmp->hfc_filevp), HFS_EXCLUSIVE_LOCK) != 0) {
+       if (hfs_lock(VTOC(hfsmp->hfc_filevp), HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT) != 0) {
                return (EPERM);
        }
 
+       MALLOC(iterator, BTreeIterator *, sizeof(*iterator), M_TEMP, M_WAITOK);
+       if (iterator == NULL) {
+               hfs_unlock(VTOC(hfsmp->hfc_filevp));
+               return (ENOMEM);
+       }
+
        stage = hfsmp->hfc_stage;
        hfsmp->hfc_stage = HFC_BUSY;
 
        filesmoved = blksmoved = 0;
        bt_op = kBTreeFirstRecord;
 
-       MALLOC(iterator, BTreeIterator *, sizeof(*iterator), M_TEMP, M_WAITOK);
        bzero(iterator, sizeof(*iterator));
        key = (HotFileKey*) &iterator->key;
 
@@ -1273,20 +1338,20 @@ hotfiles_evict(struct hfsmount *hfsmp, struct proc *p)
                 */
                if (BTIterateRecord(filefork, bt_op, iterator, NULL, NULL) != 0) {
 #if HFC_VERBOSE
-                       printf("hotfiles_evict: no more records\n");
+                       printf("hfs: hotfiles_evict: no more records\n");
 #endif
                        error = 0;
                        stage = HFC_ADOPTION;
                        break;
                }
                if (key->keyLength != HFC_KEYLENGTH) {
-                       printf("hotfiles_evict: invalid key length %d\n", key->keyLength);
+                       printf("hfs: hotfiles_evict: invalid key length %d\n", key->keyLength);
                        error = EFTYPE;
                        break;
                }               
                if (key->temperature == HFC_LOOKUPTAG) {
 #if HFC_VERBOSE
-                       printf("hotfiles_evict: ran into thread records\n");
+                       printf("hfs: hotfiles_evict: ran into thread records\n");
 #endif
                        error = 0;
                        stage = HFC_ADOPTION;
@@ -1295,34 +1360,28 @@ hotfiles_evict(struct hfsmount *hfsmp, struct proc *p)
                /*
                 * Aquire the vnode for this file.
                 */
-               error = hfs_vget(hfsmp, key->fileID, &vp, 0);
-
-               /* Start a new transaction. */
-               if (hfs_start_transaction(hfsmp) != 0) {
-                   if (error == 0) {
-                       hfs_unlock(VTOC(vp));
-                       vnode_put(vp);
-                   }
-                   error = EINVAL;
-                   break;
-               }
-               startedtrans = 1;
-
+               error = hfs_vget(hfsmp, key->fileID, &vp, 0, 0);
                if (error) {
                        if (error == ENOENT) {
                                goto delete;  /* stale entry, go to next */
                        } else {
-                               printf("hotfiles_evict: err %d getting file %d\n",
+                               printf("hfs: hotfiles_evict: err %d getting file %d\n",
                                       error, key->fileID);
                        }
                        break;
                }
-               if (!vnode_isreg(vp) && !vnode_islnk(vp)) {
-                       printf("hotfiles_evict: huh, not a file %d\n", key->fileID);
+
+               /* 
+                * Symlinks that may have been inserted into the hotfile zone during a previous OS are now stuck 
+                * here.  We do not want to move them. 
+                */
+               if (!vnode_isreg(vp)) {
+                       printf("hfs: hotfiles_evict: huh, not a file %d\n", key->fileID);
                        hfs_unlock(VTOC(vp));
                        vnode_put(vp);
                        goto delete;  /* invalid entry, go to next */
                }
+
                fileblocks = VTOF(vp)->ff_blocks;
                if ((blksmoved > 0) &&
                    (blksmoved + fileblocks) > HFC_BLKSPERSYNC) {
@@ -1335,7 +1394,7 @@ hotfiles_evict(struct hfsmount *hfsmp, struct proc *p)
                 */
                if (!hotextents(hfsmp, &VTOF(vp)->ff_extents[0])) {
 #if HFC_VERBOSE
-                       printf("hotfiles_evict: file %d isn't hot!\n", key->fileID);
+                       printf("hfs: hotfiles_evict: file %d isn't hot!\n", key->fileID);
 #endif
                        hfs_unlock(VTOC(vp));
                        vnode_put(vp);
@@ -1345,9 +1404,9 @@ hotfiles_evict(struct hfsmount *hfsmp, struct proc *p)
                /*
                 * Relocate file out of hot area.
                 */
-               error = hfs_relocate(vp, HFSTOVCB(hfsmp)->nextAllocation, proc_ucred(p), p);
+               error = hfs_relocate(vp, HFSTOVCB(hfsmp)->nextAllocation, vfs_context_ucred(ctx), vfs_context_proc(ctx));
                if (error) {
-                       printf("hotfiles_evict: err %d relocating file %d\n", error, key->fileID);
+                       printf("hfs: hotfiles_evict: err %d relocating file %d\n", error, key->fileID);
                        hfs_unlock(VTOC(vp));
                        vnode_put(vp);
                        bt_op = kBTreeNextRecord;
@@ -1371,6 +1430,13 @@ hotfiles_evict(struct hfsmount *hfsmp, struct proc *p)
                blksmoved += fileblocks;
                filesmoved++;
 delete:
+               /* Start a new transaction before calling BTree code. */
+               if (hfs_start_transaction(hfsmp) != 0) {
+                   error = EINVAL;
+                   break;
+               }
+               startedtrans = 1;
+
                error = BTDeleteRecord(filefork, iterator);
                if (error) {
                        error = MacToVFSError(error);
@@ -1396,7 +1462,7 @@ next:
        } /* end while */
 
 #if HFC_VERBOSE
-       printf("hotfiles_evict: moved %d files (%d blks, %d to go)\n", filesmoved, blksmoved, listp->hfl_reclaimblks);
+       printf("hfs: hotfiles_evict: moved %d files (%d blks, %d to go)\n", filesmoved, blksmoved, listp->hfl_reclaimblks);
 #endif
        /* Finish any outstanding transactions. */
        if (startedtrans) {
@@ -1412,7 +1478,7 @@ next:
        if (listp->hfl_reclaimblks <= 0) {
                stage = HFC_ADOPTION;
 #if HFC_VERBOSE
-               printf("hotfiles_evict: %d blocks free in hot file band\n", hfsmp->hfs_hotfile_freeblks);
+               printf("hfs: hotfiles_evict: %d blocks free in hot file band\n", hfsmp->hfs_hotfile_freeblks);
 #endif
        }
        FREE(iterator, M_TEMP); 
@@ -1428,7 +1494,7 @@ static int
 hotfiles_age(struct hfsmount *hfsmp)
 {
        BTreeInfoRec  btinfo;
-       BTreeIterator * iterator;
+       BTreeIterator * iterator = NULL;
        BTreeIterator * prev_iterator;
        FSBufferDescriptor  record;
        FSBufferDescriptor  prev_record;
@@ -1446,6 +1512,10 @@ hotfiles_age(struct hfsmount *hfsmp)
 
 
        MALLOC(iterator, BTreeIterator *, 2 * sizeof(*iterator), M_TEMP, M_WAITOK);
+       if (iterator == NULL) {
+               error = ENOMEM;
+               goto out2;
+       }
        bzero(iterator, 2 * sizeof(*iterator));
        key = (HotFileKey*) &iterator->key;
 
@@ -1466,7 +1536,7 @@ hotfiles_age(struct hfsmount *hfsmp)
            error = EINVAL;
            goto out2;
        } 
-       if (hfs_lock(VTOC(hfsmp->hfc_filevp), HFS_EXCLUSIVE_LOCK) != 0) {
+       if (hfs_lock(VTOC(hfsmp->hfc_filevp), HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT) != 0) {
                error = EPERM;
                goto out1;
        }
@@ -1574,7 +1644,8 @@ out:
 out1:
        hfs_end_transaction(hfsmp);
 out2:
-       FREE(iterator, M_TEMP); 
+       if (iterator)
+               FREE(iterator, M_TEMP); 
        return (error);
 }
 
@@ -1620,7 +1691,7 @@ hotextents(struct hfsmount *hfsmp, HFSPlusExtentDescriptor * extents)
 static int
 hfc_btree_open(struct hfsmount *hfsmp, struct vnode **vpp)
 {
-       struct proc *p;
+       proc_t p;
        struct vnode *vp;
        struct cat_desc  cdesc;
        struct cat_attr  cattr;
@@ -1629,36 +1700,38 @@ hfc_btree_open(struct hfsmount *hfsmp, struct vnode **vpp)
        int  error;
        int  retry = 0;
        int lockflags;
+       int newvnode_flags = 0;
 
        *vpp = NULL;
        p = current_proc();
 
        bzero(&cdesc, sizeof(cdesc));
        cdesc.cd_parentcnid = kRootDirID;
-       cdesc.cd_nameptr = filename;
+       cdesc.cd_nameptr = (const u_int8_t *)filename;
        cdesc.cd_namelen = strlen(filename);
 
        lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG, HFS_SHARED_LOCK);
 
-       error = cat_lookup(hfsmp, &cdesc, 0, &cdesc, &cattr, &cfork, NULL);
+       error = cat_lookup(hfsmp, &cdesc, 0, 0, &cdesc, &cattr, &cfork, NULL);
 
        hfs_systemfile_unlock(hfsmp, lockflags);
 
        if (error) {
-               printf("hfc_btree_open: cat_lookup error %d\n", error);
+               printf("hfs: hfc_btree_open: cat_lookup error %d\n", error);
                return (error);
        }
 again:
        cdesc.cd_flags |= CD_ISMETA;
-       error = hfs_getnewvnode(hfsmp, NULL, NULL, &cdesc, 0, &cattr, &cfork, &vp);
+       error = hfs_getnewvnode(hfsmp, NULL, NULL, &cdesc, 0, &cattr, 
+                                                       &cfork, &vp, &newvnode_flags);
        if (error) {
-               printf("hfc_btree_open: hfs_getnewvnode error %d\n", error);
+               printf("hfs: hfc_btree_open: hfs_getnewvnode error %d\n", error);
                cat_releasedesc(&cdesc);
                return (error);
        }
        if (!vnode_issystem(vp)) {
 #if HFC_VERBOSE
-               printf("hfc_btree_open: file has UBC, try again\n");
+               printf("hfs: hfc_btree_open: file has UBC, try again\n");
 #endif
                hfs_unlock(VTOC(vp));
                vnode_recycle(vp);
@@ -1672,7 +1745,7 @@ again:
        /* Open the B-tree file for writing... */
        error = BTOpenPath(VTOF(vp), (KeyCompareProcPtr) hfc_comparekeys);      
        if (error) {
-               printf("hfc_btree_open: BTOpenPath error %d\n", error);
+               printf("hfs: hfc_btree_open: BTOpenPath error %d\n", error);
                error = MacToVFSError(error);
        }
 
@@ -1684,10 +1757,7 @@ again:
        vnode_put(vp);
 
        if (!vnode_issystem(vp))
-               panic("hfc_btree_open: not a system file (vp = 0x%08x)", vp);
-
-       if (UBCINFOEXISTS(vp))
-               panic("hfc_btree_open: has UBCInfo (vp = 0x%08x)", vp);
+               panic("hfs: hfc_btree_open: not a system file (vp = %p)", vp);
 
        return (error);
 }
@@ -1700,16 +1770,16 @@ again:
 static int
 hfc_btree_close(struct hfsmount *hfsmp, struct vnode *vp)
 {
-       struct proc *p = current_proc();
+       proc_t p = current_proc();
        int  error = 0;
 
 
        if (hfsmp->jnl) {
-           journal_flush(hfsmp->jnl);
+           hfs_journal_flush(hfsmp, FALSE);
        }
 
        if (vnode_get(vp) == 0) {
-               error = hfs_lock(VTOC(vp), HFS_EXCLUSIVE_LOCK);
+               error = hfs_lock(VTOC(vp), HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT);
                if (error == 0) {
                        (void) hfs_fsync(vp, MNT_WAIT, 0, p);
                        error = BTClosePath(VTOF(vp));
@@ -1728,30 +1798,27 @@ hfc_btree_close(struct hfsmount *hfsmp, struct vnode *vp)
  *
  */
 static int
-hfc_btree_create(struct hfsmount *hfsmp, int nodesize, int entries)
+hfc_btree_create(struct hfsmount *hfsmp, unsigned int nodesize, unsigned int entries)
 {
        struct vnode *dvp = NULL;
        struct vnode *vp = NULL;
        struct cnode *cp = NULL;
-       struct vfs_context context;
+       vfs_context_t ctx = vfs_context_current();
        struct vnode_attr va;
        struct componentname cname;
        static char filename[] = HFC_FILENAME;
        int  error;
 
-       context.vc_proc = current_proc();
-       context.vc_ucred = kauth_cred_get();
-
        if (hfsmp->hfc_filevp)
-               panic("hfc_btree_create: hfc_filevp exists (vp = 0x%08x)", hfsmp->hfc_filevp);
+               panic("hfs: hfc_btree_create: hfc_filevp exists (vp = %p)", hfsmp->hfc_filevp);
 
-       error = VFS_ROOT(HFSTOVFS(hfsmp), &dvp, &context);
+       error = VFS_ROOT(HFSTOVFS(hfsmp), &dvp, ctx);
        if (error) {
                return (error);
        }
        cname.cn_nameiop = CREATE;
        cname.cn_flags = ISLASTCN;
-       cname.cn_context = &context;
+       cname.cn_context = ctx;
        cname.cn_pnbuf = filename;
        cname.cn_pnlen = sizeof(filename);
        cname.cn_nameptr = filename;
@@ -1765,30 +1832,35 @@ hfc_btree_create(struct hfsmount *hfsmp, int nodesize, int entries)
        VATTR_SET(&va, va_uid, 0);
        VATTR_SET(&va, va_gid, 0);
 
+       if (hfs_start_transaction(hfsmp) != 0) {
+           error = EINVAL;
+           goto out;
+       } 
+
        /* call ourselves directly, ignore the higher-level VFS file creation code */
-       error = VNOP_CREATE(dvp, &vp, &cname, &va, &context);
+       error = VNOP_CREATE(dvp, &vp, &cname, &va, ctx);
        if (error) {
-               printf("HFS: error %d creating HFBT on %s\n", error, HFSTOVCB(hfsmp)->vcbVN);
+               printf("hfs: error %d creating HFBT on %s\n", error, HFSTOVCB(hfsmp)->vcbVN);
                goto out;
        }
        if (dvp) {
                vnode_put(dvp);
                dvp = NULL;
        }
-       if ((error = hfs_lock(VTOC(vp), HFS_EXCLUSIVE_LOCK))) {
+       if ((error = hfs_lock(VTOC(vp), HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT))) {
                goto out;
        }
        cp = VTOC(vp);
 
        /* Don't use non-regular files or files with links. */
-       if (!vnode_isreg(vp) || cp->c_nlink != 1) {
+       if (!vnode_isreg(vp) || cp->c_linkcount != 1) {
                error = EFTYPE;
                goto out;
        }
 
-       printf("HFS: created HFBT on %s\n", HFSTOVCB(hfsmp)->vcbVN);
+       printf("hfs: created HFBT on %s\n", HFSTOVCB(hfsmp)->vcbVN);
 
-       if (VTOF(vp)->ff_size < (u_int64_t)nodesize) {
+       if (VTOF(vp)->ff_size < nodesize) {
                caddr_t  buffer;
                u_int16_t *index;
                u_int16_t  offset;
@@ -1810,7 +1882,7 @@ hfc_btree_create(struct hfsmount *hfsmp, int nodesize, int entries)
                        goto out;
                }       
                bzero(buffer, nodesize);
-               index = (int16_t *)buffer;
+               index = (u_int16_t *)buffer;
        
                entirespernode = (nodesize - sizeof(BTNodeDescriptor) - 2) /
                                 (sizeof(HotFileKey) + 6);
@@ -1826,7 +1898,7 @@ hfc_btree_create(struct hfsmount *hfsmp, int nodesize, int entries)
                index[(nodesize / 2) - 1] = SWAP_BE16 (offset);
        
                /* FILL IN THE HEADER RECORD:  */
-               bthp = (BTHeaderRec *)((UInt8 *)buffer + offset);
+               bthp = (BTHeaderRec *)((u_int8_t *)buffer + offset);
                bthp->nodeSize     = SWAP_BE16 (nodesize);
                bthp->totalNodes   = SWAP_BE32 (filesize / nodesize);
                bthp->freeNodes    = SWAP_BE32 (nodecnt - 1);
@@ -1838,7 +1910,7 @@ hfc_btree_create(struct hfsmount *hfsmp, int nodesize, int entries)
                index[(nodesize / 2) - 2] = SWAP_BE16 (offset);
        
                /* FILL IN THE USER RECORD:  */
-               hotfileinfo = (HotFilesInfo *)((UInt8 *)buffer + offset);
+               hotfileinfo = (HotFilesInfo *)((u_int8_t *)buffer + offset);
                hotfileinfo->magic       = SWAP_BE32 (HFC_MAGIC);
                hotfileinfo->version     = SWAP_BE32 (HFC_VERSION);
                hotfileinfo->duration    = SWAP_BE32 (HFC_DEFAULT_DURATION);
@@ -1847,7 +1919,8 @@ hfc_btree_create(struct hfsmount *hfsmp, int nodesize, int entries)
                hotfileinfo->threshold   = SWAP_BE32 (HFC_MINIMUM_TEMPERATURE);
                hotfileinfo->maxfileblks = SWAP_BE32 (HFC_MAXIMUM_FILESIZE / HFSTOVCB(hfsmp)->blockSize);
                hotfileinfo->maxfilecnt  = SWAP_BE32 (HFC_DEFAULT_FILE_COUNT);
-               strcpy(hotfileinfo->tag, hfc_tag);
+               strlcpy((char *)hotfileinfo->tag, hfc_tag,
+                       sizeof hotfileinfo->tag);
                offset += kBTreeHeaderUserBytes;
                index[(nodesize / 2) - 3] = SWAP_BE16 (offset);
        
@@ -1858,9 +1931,9 @@ hfc_btree_create(struct hfsmount *hfsmp, int nodesize, int entries)
                index[(nodesize / 2) - 4] = SWAP_BE16 (offset);
 
                vnode_setnoflush(vp);
-               error = hfs_truncate(vp, (off_t)filesize, IO_NDELAY, 0, &context);
+               error = hfs_truncate(vp, (off_t)filesize, IO_NDELAY, 0, ctx);
                if (error) {
-                       printf("HFS: error %d growing HFBT on %s\n", error, HFSTOVCB(hfsmp)->vcbVN);
+                       printf("hfs: error %d growing HFBT on %s\n", error, HFSTOVCB(hfsmp)->vcbVN);
                        goto out;
                }
                cp->c_flag |= C_ZFWANTSYNC;
@@ -1870,27 +1943,28 @@ hfc_btree_create(struct hfsmount *hfsmp, int nodesize, int entries)
                        struct vnop_write_args args;
                        uio_t auio;
 
-                       auio = uio_create(1, 0, UIO_SYSSPACE32, UIO_WRITE);
+                       auio = uio_create(1, 0, UIO_SYSSPACE, UIO_WRITE);
                        uio_addiov(auio, (uintptr_t)buffer, nodesize);
 
                        args.a_desc = &vnop_write_desc;
                        args.a_vp = vp;
                        args.a_uio = auio;
                        args.a_ioflag = 0;
-                       args.a_context = &context;
+                       args.a_context = ctx;
 
                        hfs_unlock(cp);
                        cp = NULL;
 
                        error = hfs_vnop_write(&args);
                        if (error)
-                               printf("HFS: error %d writing HFBT on %s\n", error, HFSTOVCB(hfsmp)->vcbVN);
+                               printf("hfs: error %d writing HFBT on %s\n", error, HFSTOVCB(hfsmp)->vcbVN);
 
                        uio_free(auio);
                }
                kmem_free(kernel_map, (vm_offset_t)buffer, nodesize);
        }
 out:
+       hfs_end_transaction(hfsmp);
        if (dvp) {
                vnode_put(dvp);
        }
@@ -2180,7 +2254,7 @@ hf_getsortedlist(hotfile_data_t * hotdata, hotfilelist_t *sortedlist)
        sortedlist->hfl_count = i;
        
 #if HFC_VERBOSE
-       printf("HFS: hf_getsortedlist returned %d entries\n", i);
+       printf("hfs: hf_getsortedlist returned %d entries\n", i);
 #endif
 }
 
@@ -2203,7 +2277,7 @@ hf_printtree(hotfile_entry_t * root)
 {
        if (root) {
                hf_printtree(root->left);
-               printf("temperature: % 8d, fileid %d\n", root->temperature, root->fileid);
+               printf("hfs: temperature: % 8d, fileid %d\n", root->temperature, root->fileid);
                hf_printtree(root->right);
        }
 }