]> 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 4b23e1b566c84a1c7058bca1c3858da1c498b985..7ba80c737bc31470fd4394d89797d58be24a9c07 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2003-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -207,14 +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 {
@@ -240,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;
@@ -264,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++)
@@ -312,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)
@@ -322,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.
@@ -407,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);
 
@@ -421,7 +428,6 @@ out:
 /*
  * Suspend recording the hotest files on a file system.
  */
-__private_extern__
 int
 hfs_recording_suspend(struct hfsmount *hfsmp)
 {
@@ -450,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) {
@@ -462,7 +468,7 @@ 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 end_transaction;
        }
@@ -504,7 +510,6 @@ out:
 /*
  *
  */
-__private_extern__
 int
 hfs_recording_init(struct hfsmount *hfsmp)
 {
@@ -513,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;
@@ -552,12 +557,17 @@ 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.
@@ -567,11 +577,17 @@ hfs_recording_init(struct hfsmount *hfsmp)
        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;
@@ -580,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.
@@ -599,7 +615,7 @@ 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 out0;
        }
@@ -678,13 +694,15 @@ hfs_recording_init(struct hfsmount *hfsmp)
 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;
@@ -698,7 +716,6 @@ out2:
 /*
  * Use sync to perform ocassional background work.
  */
-__private_extern__
 int
 hfs_hotfilesync(struct hfsmount *hfsmp, vfs_context_t ctx)
 {
@@ -745,7 +762,6 @@ hfs_hotfilesync(struct hfsmount *hfsmp, vfs_context_t ctx)
  *
  * Note: the cnode is locked on entry.
  */
-__private_extern__
 int
 hfs_addhotfile(struct vnode *vp)
 {
@@ -776,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);
@@ -794,7 +818,7 @@ hfs_addhotfile_internal(struct vnode *vp)
            (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);
        }
@@ -833,7 +857,6 @@ hfs_addhotfile_internal(struct vnode *vp)
  *
  * Note: the cnode is locked on entry.
  */
-__private_extern__
 int
 hfs_removehotfile(struct vnode *vp)
 {
@@ -847,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);
        }
 
@@ -889,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);
@@ -938,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;
@@ -955,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;
 
@@ -966,7 +993,7 @@ 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 out1;
        }
@@ -992,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;
                }
@@ -1008,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;
                }
@@ -1018,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;
                }
@@ -1037,7 +1064,8 @@ hotfiles_refine(struct hfsmount *hfsmp)
 out1:
        hfs_end_transaction(hfsmp);
 out:
-       FREE(iterator, M_TEMP); 
+       if (iterator)
+               FREE(iterator, M_TEMP); 
        return (error);
 }
 
@@ -1049,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;
@@ -1070,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;
 
@@ -1082,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;
@@ -1104,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;
@@ -1113,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;
@@ -1176,7 +1210,7 @@ hotfiles_adopt(struct hfsmount *hfsmp)
 
                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;
@@ -1190,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;
@@ -1210,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) {
@@ -1229,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;
        }
@@ -1253,7 +1287,7 @@ hotfiles_adopt(struct hfsmount *hfsmp)
 static int
 hotfiles_evict(struct hfsmount *hfsmp, vfs_context_t ctx)
 {
-       BTreeIterator * iterator;
+       BTreeIterator * iterator = NULL;
        struct vnode *vp;
        HotFileKey * key;
        filefork_t * filefork;
@@ -1274,17 +1308,22 @@ hotfiles_evict(struct hfsmount *hfsmp, vfs_context_t ctx)
        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;
 
@@ -1299,20 +1338,20 @@ hotfiles_evict(struct hfsmount *hfsmp, vfs_context_t ctx)
                 */
                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;
@@ -1321,22 +1360,28 @@ hotfiles_evict(struct hfsmount *hfsmp, vfs_context_t ctx)
                /*
                 * Aquire the vnode for this file.
                 */
-               error = hfs_vget(hfsmp, key->fileID, &vp, 0);
+               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) {
@@ -1349,7 +1394,7 @@ hotfiles_evict(struct hfsmount *hfsmp, vfs_context_t ctx)
                 */
                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);
@@ -1361,7 +1406,7 @@ hotfiles_evict(struct hfsmount *hfsmp, vfs_context_t ctx)
                 */
                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;
@@ -1417,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) {
@@ -1433,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); 
@@ -1449,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;
@@ -1467,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;
 
@@ -1487,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;
        }
@@ -1595,7 +1644,8 @@ out:
 out1:
        hfs_end_transaction(hfsmp);
 out2:
-       FREE(iterator, M_TEMP); 
+       if (iterator)
+               FREE(iterator, M_TEMP); 
        return (error);
 }
 
@@ -1650,6 +1700,7 @@ 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();
@@ -1661,25 +1712,26 @@ hfc_btree_open(struct hfsmount *hfsmp, struct vnode **vpp)
 
        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);
@@ -1693,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);
        }
 
@@ -1705,7 +1757,7 @@ again:
        vnode_put(vp);
 
        if (!vnode_issystem(vp))
-               panic("hfc_btree_open: not a system file (vp = %p)", vp);
+               panic("hfs: hfc_btree_open: not a system file (vp = %p)", vp);
 
        return (error);
 }
@@ -1723,11 +1775,11 @@ hfc_btree_close(struct hfsmount *hfsmp, struct vnode *vp)
 
 
        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));
@@ -1758,7 +1810,7 @@ hfc_btree_create(struct hfsmount *hfsmp, unsigned int nodesize, unsigned int ent
        int  error;
 
        if (hfsmp->hfc_filevp)
-               panic("hfc_btree_create: hfc_filevp exists (vp = %p)", hfsmp->hfc_filevp);
+               panic("hfs: hfc_btree_create: hfc_filevp exists (vp = %p)", hfsmp->hfc_filevp);
 
        error = VFS_ROOT(HFSTOVFS(hfsmp), &dvp, ctx);
        if (error) {
@@ -1780,17 +1832,22 @@ hfc_btree_create(struct hfsmount *hfsmp, unsigned int nodesize, unsigned int ent
        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, 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);
@@ -1801,7 +1858,7 @@ hfc_btree_create(struct hfsmount *hfsmp, unsigned int nodesize, unsigned int ent
                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 < nodesize) {
                caddr_t  buffer;
@@ -1876,7 +1933,7 @@ hfc_btree_create(struct hfsmount *hfsmp, unsigned int nodesize, unsigned int ent
                vnode_setnoflush(vp);
                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;
@@ -1886,7 +1943,7 @@ hfc_btree_create(struct hfsmount *hfsmp, unsigned int nodesize, unsigned int ent
                        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;
@@ -1900,13 +1957,14 @@ hfc_btree_create(struct hfsmount *hfsmp, unsigned int nodesize, unsigned int ent
 
                        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);
        }
@@ -2196,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
 }
 
@@ -2219,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);
        }
 }