/*
- * Copyright (c) 2003-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2013 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
(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;
/*
* Suspend recording the hotest files on a file system.
*/
-__private_extern__
int
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;
}
/*
*
*/
-__private_extern__
int
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("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 HFC_VERBOSE
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 = 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;
}
out1:
(void) BTScanTerminate(&scanstate, &data, &data, &data);
out2:
+ hfs_end_transaction(hfsmp);
if (iterator)
FREE(iterator, M_TEMP);
if (hfsmp->hfc_filevp) {
/*
* Use sync to perform ocassional background work.
*/
-__private_extern__
int
hfs_hotfilesync(struct hfsmount *hfsmp, vfs_context_t ctx)
{
*
* Note: the cnode is locked on entry.
*/
-__private_extern__
int
hfs_addhotfile(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);
(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);
}
*
* Note: the cnode is locked on entry.
*/
-__private_extern__
int
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);
}
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);
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;
}
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);
}
/*
* 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;
}
break;
}
- if (!vnode_isreg(vp) && !vnode_islnk(vp)) {
+ 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);
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);
}
/*
* 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 */
}
break;
}
- if (!vnode_isreg(vp) && !vnode_islnk(vp)) {
+
+ /*
+ * 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) {
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;
}
int error;
int retry = 0;
int lockflags;
+ int newvnode_flags = 0;
*vpp = NULL;
p = current_proc();
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);
}
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("hfs: hfc_btree_open: hfs_getnewvnode error %d\n", error);
cat_releasedesc(&cdesc);
if (hfsmp->jnl) {
- hfs_journal_flush(hfsmp);
+ 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));
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) {
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);
index[(nodesize / 2) - 4] = SWAP_BE16 (offset);
vnode_setnoflush(vp);
- error = hfs_truncate(vp, (off_t)filesize, IO_NDELAY, 0, 0, ctx);
+ 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);
goto out;
kmem_free(kernel_map, (vm_offset_t)buffer, nodesize);
}
out:
+ hfs_end_transaction(hfsmp);
if (dvp) {
vnode_put(dvp);
}