X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/2d21ac55c334faf3a56e5634905ed6987fc787d4..c18c124eaa464aaaa5549e99e5a70fc9cbb50944:/bsd/hfs/hfs_hotfiles.c diff --git a/bsd/hfs/hfs_hotfiles.c b/bsd/hfs/hfs_hotfiles.c index 4b23e1b56..7ba80c737 100644 --- a/bsd/hfs/hfs_hotfiles.c +++ b/bsd/hfs/hfs_hotfiles.c @@ -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); } }