Skip to content

Commit

Permalink
xnu-792.6.70
Browse files Browse the repository at this point in the history
  • Loading branch information
Darwin authored and das committed Jun 4, 2017
1 parent 7764fae commit ab636a6
Show file tree
Hide file tree
Showing 28 changed files with 397 additions and 96 deletions.
2 changes: 1 addition & 1 deletion bsd/dev/ppc/munge.s
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_EN
* @APPLE_LICENSE_HEADER_END@
*/

/*
Expand Down
1 change: 1 addition & 0 deletions bsd/hfs/hfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ typedef struct filefork FCB;
#define MAKE_INODE_NAME(name,linkno) \
(void) sprintf((name), "%s%d", HFS_INODE_PREFIX, (linkno))

#define HFS_INODE_PREFIX_LEN 5


#define HFS_AVERAGE_NAME_SIZE 22
Expand Down
18 changes: 14 additions & 4 deletions bsd/hfs/hfs_attrlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ hfs_vnop_readdirattr(ap)
}

dir_entries = dcp->c_entries;
if (dcp->c_attr.ca_fileid == kHFSRootFolderID && hfsmp->jnl) {
if (dcp->c_attr.ca_fileid == kHFSRootFolderID && (hfsmp->jnl || ((HFSTOVCB(hfsmp)->vcbAtrb & kHFSVolumeJournaledMask) && (hfsmp->hfs_flags & HFS_READ_ONLY)))) {
dir_entries -= 3;
}

Expand Down Expand Up @@ -887,7 +887,12 @@ hfs_vnop_readdirattr(ap)

/* Make sure dcp is locked exclusive before changing c_dirhinttag. */
if (shared_cnode_lock) {
lck_rw_lock_shared_to_exclusive(&dcp->c_rwlock);
/*
* If the upgrade fails we loose the lock and
* have to take the exclusive lock on our own.
*/
if (lck_rw_lock_shared_to_exclusive(&dcp->c_rwlock) != 0)
lck_rw_lock_exclusive(&dcp->c_rwlock);
dcp->c_lockowner = current_thread();
shared_cnode_lock = 0;
}
Expand All @@ -901,7 +906,12 @@ hfs_vnop_readdirattr(ap)
/* Drop directory hint on error or if there are no more entries */
if (dirhint && (error || index >= dir_entries)) {
if (shared_cnode_lock) {
lck_rw_lock_shared_to_exclusive(&dcp->c_rwlock);
/*
* If the upgrade fails we loose the lock and
* have to take the exclusive lock on our own.
*/
if (lck_rw_lock_shared_to_exclusive(&dcp->c_rwlock) != 0)
lck_rw_lock_exclusive(&dcp->c_rwlock);
dcp->c_lockowner = current_thread();
}
hfs_reldirhint(dcp, dirhint);
Expand Down Expand Up @@ -1614,7 +1624,7 @@ packdirattr(
if (descp->cd_parentcnid == kHFSRootParentID) {
if (hfsmp->hfs_privdir_desc.cd_cnid != 0)
--entries; /* hide private dir */
if (hfsmp->jnl)
if (hfsmp->jnl || ((HFSTOVCB(hfsmp)->vcbAtrb & kHFSVolumeJournaledMask) && (hfsmp->hfs_flags & HFS_READ_ONLY)))
entries -= 2; /* hide the journal files */
}

Expand Down
13 changes: 8 additions & 5 deletions bsd/hfs/hfs_catalog.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ cat_lookupbykey(struct hfsmount *hfsmp, CatalogKey *keyp, u_long hint, int wantr
hint = iterator->hint.nodeNum;

/* Hide the journal files (if any) */
if (hfsmp->jnl &&
if ((hfsmp->jnl || ((HFSTOVCB(hfsmp)->vcbAtrb & kHFSVolumeJournaledMask) && (hfsmp->hfs_flags & HFS_READ_ONLY))) &&
((cnid == hfsmp->hfs_jnlfileid) ||
(cnid == hfsmp->hfs_jnlinfoblkid))) {

Expand Down Expand Up @@ -1022,11 +1022,14 @@ cat_rename (

/* Find cnode data at new location */
result = BTSearchRecord(fcb, to_iterator, &btdata, &datasize, NULL);
if (result)
goto exit;

if ((fromtype != recp->recordType) ||
(from_cdp->cd_cnid != getcnid(recp)))
(from_cdp->cd_cnid != getcnid(recp))) {
result = EEXIST;
goto exit; /* EEXIST */

}
/* The old name is a case variant and must be removed */
result = BTDeleteRecord(fcb, from_iterator);
if (result)
Expand Down Expand Up @@ -1563,7 +1566,7 @@ cat_readattr(const CatalogKey *key, const CatalogRecord *rec,
(rec->hfsPlusFolder.folderID == hfsmp->hfs_privdir_desc.cd_cnid)) {
return (1); /* continue */
}
if (hfsmp->jnl &&
if ((hfsmp->jnl || ((HFSTOVCB(hfsmp)->vcbAtrb & kHFSVolumeJournaledMask) && (hfsmp->hfs_flags & HFS_READ_ONLY))) &&
(rec->recordType == kHFSPlusFileRecord) &&
((rec->hfsPlusFile.fileID == hfsmp->hfs_jnlfileid) ||
(rec->hfsPlusFile.fileID == hfsmp->hfs_jnlinfoblkid))) {
Expand Down Expand Up @@ -1879,7 +1882,7 @@ cat_packdirentry(const CatalogKey *ckp, const CatalogRecord *crp,
cnid = crp->hfsPlusFile.fileID;
/* Hide the journal files */
if ((curID == kHFSRootFolderID) &&
(hfsmp->jnl) &&
((hfsmp->jnl || ((HFSTOVCB(hfsmp)->vcbAtrb & kHFSVolumeJournaledMask) && (hfsmp->hfs_flags & HFS_READ_ONLY)))) &&
((cnid == hfsmp->hfs_jnlfileid) ||
(cnid == hfsmp->hfs_jnlinfoblkid))) {
hide = 1;
Expand Down
1 change: 1 addition & 0 deletions bsd/hfs/hfs_readwrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -1158,6 +1158,7 @@ hfs_vnop_ioctl( struct vnop_ioctl_args /* {
goto err_exit_bulk_access;
}
myucred.cr_rgid = myucred.cr_svgid = myucred.cr_groups[0];
myucred.cr_gmuid = myucred.cr_uid;

my_context.vc_proc = p;
my_context.vc_ucred = &myucred;
Expand Down
40 changes: 21 additions & 19 deletions bsd/hfs/hfs_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ hfs_reload_callback(struct vnode *vp, void *cargs)
/*
* Re-read cnode data for all active vnodes (non-metadata files).
*/
if (!VNODE_IS_RSRC(vp)) {
if (!vnode_issystem(vp) && !VNODE_IS_RSRC(vp)) {
struct cat_fork *datafork;
struct cat_desc desc;

Expand Down Expand Up @@ -591,7 +591,6 @@ hfs_reload(struct mount *mountp, kauth_cred_t cred, struct proc *p)
struct filefork *forkp;
struct cat_desc cndesc;
struct hfs_reload_cargs args;
int lockflags;

hfsmp = VFSTOHFS(mountp);
vcb = HFSTOVCB(hfsmp);
Expand All @@ -617,9 +616,7 @@ hfs_reload(struct mount *mountp, kauth_cred_t cred, struct proc *p)
* the vnode will be in an 'unbusy' state (VNODE_WAIT) and
* properly referenced and unreferenced around the callback
*/
lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG, HFS_EXCLUSIVE_LOCK);
vnode_iterate(mountp, VNODE_RELOAD | VNODE_WAIT, hfs_reload_callback, (void *)&args);
hfs_systemfile_unlock(hfsmp, lockflags);

if (args.error)
return (args.error);
Expand Down Expand Up @@ -2163,6 +2160,7 @@ hfs_vget(struct hfsmount *hfsmp, cnid_t cnid, struct vnode **vpp, int skiplock)
struct cat_attr cnattr;
struct cat_fork cnfork;
struct componentname cn;
u_int32_t linkref = 0;
int error;

/* Check for cnids that should't be exported. */
Expand Down Expand Up @@ -2215,18 +2213,19 @@ hfs_vget(struct hfsmount *hfsmp, cnid_t cnid, struct vnode **vpp, int skiplock)
return (error);
}

/* Hide open files that have been deleted */
if ((hfsmp->hfs_privdir_desc.cd_cnid != 0) &&
(cndesc.cd_parentcnid == hfsmp->hfs_privdir_desc.cd_cnid)) {
// XXXdbg - if this is a hardlink, we could call
// hfs_chash_snoop() to see if there is
// already a cnode and vnode present for
// this fileid. however I'd rather not
// risk it at this point in Tiger.
cat_releasedesc(&cndesc);
error = ENOENT;
*vpp = NULL;
return (error);
/*
* If we just looked up a raw hardlink inode,
* then finish initializing it.
*/
if ((cndesc.cd_parentcnid == hfsmp->hfs_privdir_desc.cd_cnid) &&
(bcmp(cndesc.cd_nameptr, HFS_INODE_PREFIX, HFS_INODE_PREFIX_LEN) == 0)) {
linkref = strtoul((const char*)&cndesc.cd_nameptr[HFS_INODE_PREFIX_LEN], NULL, 10);
cnattr.ca_rdev = linkref;

// patch up the parentcnid
if (cnattr.ca_attrblks != 0) {
cndesc.cd_parentcnid = cnattr.ca_attrblks;
}
}
}

Expand All @@ -2246,6 +2245,10 @@ hfs_vget(struct hfsmount *hfsmp, cnid_t cnid, struct vnode **vpp, int skiplock)

/* XXX should we supply the parent as well... ? */
error = hfs_getnewvnode(hfsmp, NULLVP, &cn, &cndesc, 0, &cnattr, &cnfork, &vp);
if (error == 0 && linkref != 0) {
VTOC(vp)->c_flag |= C_HARDLINK;
}

FREE_ZONE(cn.cn_pnbuf, cn.cn_pnlen, M_NAMEI);

cat_releasedesc(&cndesc);
Expand Down Expand Up @@ -3277,7 +3280,6 @@ hfs_reclaimspace(struct hfsmount *hfsmp, u_long startblk)
if (VTOF(vp)->ff_blocks > 0) {
error = hfs_relocate(vp, hfsmp->hfs_metazone_end + 1, kauth_cred_get(), current_proc());
}
hfs_unlock(VTOC(vp));
if (error)
break;

Expand All @@ -3286,17 +3288,17 @@ hfs_reclaimspace(struct hfsmount *hfsmp, u_long startblk)
error = hfs_vgetrsrc(hfsmp, vp, &rvp, current_proc());
if (error)
break;
hfs_lock(VTOC(rvp), HFS_EXCLUSIVE_LOCK);
error = hfs_relocate(rvp, hfsmp->hfs_metazone_end + 1, kauth_cred_get(), current_proc());
hfs_unlock(VTOC(rvp));
vnode_put(rvp);
if (error)
break;
}
hfs_unlock(VTOC(vp));
vnode_put(vp);
vp = NULL;
}
if (vp) {
hfs_unlock(VTOC(vp));
vnode_put(vp);
vp = NULL;
}
Expand Down
56 changes: 54 additions & 2 deletions bsd/hfs/hfs_vfsutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
//
if ( (vcb->vcbAtrb & kHFSVolumeJournaledMask)
&& (SWAP_BE32(vhp->lastMountedVersion) != kHFSJMountVersion)
&& (hfsmp->jnl == NULL)) {
&& (hfsmp->jnl == NULL)) {

retval = hfs_late_journal_init(hfsmp, vhp, args);
if (retval != 0) {
Expand Down Expand Up @@ -604,9 +604,13 @@ OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
} else if (hfsmp->jnl) {
vfs_setflags(hfsmp->hfs_mp, (uint64_t)((unsigned int)MNT_JOURNALED));
}
} else if (hfsmp->jnl) {
} else if (hfsmp->jnl || ((vcb->vcbAtrb & kHFSVolumeJournaledMask) && (hfsmp->hfs_flags & HFS_READ_ONLY))) {
struct cat_attr jinfo_attr, jnl_attr;

if (hfsmp->hfs_flags & HFS_READ_ONLY) {
vcb->vcbAtrb &= ~kHFSVolumeJournaledMask;
}

// if we're here we need to fill in the fileid's for the
// journal and journal_info_block.
hfsmp->hfs_jnlinfoblkid = GetFileInfo(vcb, kRootDirID, ".journal_info_block", &jinfo_attr, NULL);
Expand All @@ -615,6 +619,10 @@ OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
printf("hfs: danger! couldn't find the file-id's for the journal or journal_info_block\n");
printf("hfs: jnlfileid %d, jnlinfoblkid %d\n", hfsmp->hfs_jnlfileid, hfsmp->hfs_jnlinfoblkid);
}

if (hfsmp->hfs_flags & HFS_READ_ONLY) {
vcb->vcbAtrb |= kHFSVolumeJournaledMask;
}
}

/*
Expand Down Expand Up @@ -1728,6 +1736,28 @@ hfs_early_journal_init(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
hfsmp->jnl_start = jibp->offset / SWAP_BE32(vhp->blockSize);
hfsmp->jnl_size = jibp->size;

if ((hfsmp->hfs_flags & HFS_READ_ONLY) && (vfs_flags(hfsmp->hfs_mp) & MNT_ROOTFS) == 0) {
// if the file system is read-only, check if the journal is empty.
// if it is, then we can allow the mount. otherwise we have to
// return failure.
retval = journal_is_clean(hfsmp->jvp,
jibp->offset + embeddedOffset,
jibp->size,
devvp,
hfsmp->hfs_phys_block_size);

hfsmp->jnl = NULL;

buf_brelse(jinfo_bp);

if (retval) {
printf("hfs: early journal init: volume on %s is read-only and journal is dirty. Can not mount volume.\n",
vnode_name(devvp));
}

return retval;
}

if (jibp->flags & kJIJournalNeedInitMask) {
printf("hfs: Initializing the journal (joffset 0x%llx sz 0x%llx)...\n",
jibp->offset + embeddedOffset, jibp->size);
Expand Down Expand Up @@ -1915,6 +1945,28 @@ hfs_late_journal_init(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp, void *_a
hfsmp->jnl_start = jibp->offset / SWAP_BE32(vhp->blockSize);
hfsmp->jnl_size = jibp->size;

if ((hfsmp->hfs_flags & HFS_READ_ONLY) && (vfs_flags(hfsmp->hfs_mp) & MNT_ROOTFS) == 0) {
// if the file system is read-only, check if the journal is empty.
// if it is, then we can allow the mount. otherwise we have to
// return failure.
retval = journal_is_clean(hfsmp->jvp,
jibp->offset + (off_t)vcb->hfsPlusIOPosOffset,
jibp->size,
devvp,
hfsmp->hfs_phys_block_size);

hfsmp->jnl = NULL;

buf_brelse(jinfo_bp);

if (retval) {
printf("hfs: late journal init: volume on %s is read-only and journal is dirty. Can not mount volume.\n",
vnode_name(devvp));
}

return retval;
}

if (jibp->flags & kJIJournalNeedInitMask) {
printf("hfs: Initializing the journal (joffset 0x%llx sz 0x%llx)...\n",
jibp->offset + (off_t)vcb->hfsPlusIOPosOffset, jibp->size);
Expand Down
22 changes: 21 additions & 1 deletion bsd/hfs/hfs_vnops.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ hfs_vnop_getattr(struct vnop_getattr_args *ap)
if (vnode_isvroot(vp)) {
if (hfsmp->hfs_privdir_desc.cd_cnid != 0)
--entries; /* hide private dir */
if (hfsmp->jnl)
if (hfsmp->jnl || ((HFSTOVCB(hfsmp)->vcbAtrb & kHFSVolumeJournaledMask) && (hfsmp->hfs_flags & HFS_READ_ONLY)))
entries -= 2; /* hide the journal files */
}
VATTR_RETURN(vap, va_nlink, (uint64_t)entries);
Expand Down Expand Up @@ -1890,6 +1890,10 @@ hfs_removefile(struct vnode *dvp, struct vnode *vp, struct componentname *cnp,
__private_extern__ void
replace_desc(struct cnode *cp, struct cat_desc *cdp)
{
if (&cp->c_desc == cdp) {
return;
}

/* First release allocated name buffer */
if (cp->c_desc.cd_flags & CD_HASBUF && cp->c_desc.cd_nameptr != 0) {
char *name = cp->c_desc.cd_nameptr;
Expand Down Expand Up @@ -3167,6 +3171,22 @@ hfs_vgetrsrc(struct hfsmount *hfsmp, struct vnode *vp, struct vnode **rvpp, __un
struct componentname cn;
int lockflags;

/*
* Make sure cnode lock is exclusive, if not upgrade it.
*
* We assume that we were called from a read-only VNOP (getattr)
* and that its safe to have the cnode lock dropped and reacquired.
*/
if (cp->c_lockowner != current_thread()) {
/*
* If the upgrade fails we loose the lock and
* have to take the exclusive lock on our own.
*/
if (lck_rw_lock_shared_to_exclusive(&cp->c_rwlock) != 0)
lck_rw_lock_exclusive(&cp->c_rwlock);
cp->c_lockowner = current_thread();
}

lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG, HFS_SHARED_LOCK);

/* Get resource fork data */
Expand Down
21 changes: 18 additions & 3 deletions bsd/hfs/hfs_xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,12 @@ hfs_vnop_getxattr(struct vnop_getxattr_args *ap)
if ( !RESOURCE_FORK_EXISTS(vp)) {
return (ENOATTR);
}
if ((result = hfs_vgetrsrc(hfsmp, vp, &rvp, vfs_context_proc(ap->a_context)))) {
if ((result = hfs_lock(VTOC(vp), HFS_EXCLUSIVE_LOCK))) {
return (result);
}
result = hfs_vgetrsrc(hfsmp, vp, &rvp, vfs_context_proc(ap->a_context));
hfs_unlock(VTOC(vp));
if (result) {
return (result);
}
if (uio == NULL) {
Expand Down Expand Up @@ -292,7 +297,12 @@ hfs_vnop_setxattr(struct vnop_setxattr_args *ap)
return (ENOATTR);
}
}
if ((result = hfs_vgetrsrc(hfsmp, vp, &rvp, vfs_context_proc(ap->a_context)))) {
if ((result = hfs_lock(VTOC(vp), HFS_EXCLUSIVE_LOCK))) {
return (result);
}
result = hfs_vgetrsrc(hfsmp, vp, &rvp, vfs_context_proc(ap->a_context));
hfs_unlock(VTOC(vp));
if (result) {
return (result);
}
result = VNOP_WRITE(rvp, uio, 0, ap->a_context);
Expand Down Expand Up @@ -468,7 +478,12 @@ hfs_vnop_removexattr(struct vnop_removexattr_args *ap)
if ( !RESOURCE_FORK_EXISTS(vp) ) {
return (ENOATTR);
}
if ((result = hfs_vgetrsrc(hfsmp, vp, &rvp, p))) {
if ((result = hfs_lock(VTOC(vp), HFS_EXCLUSIVE_LOCK))) {
return (result);
}
result = hfs_vgetrsrc(hfsmp, vp, &rvp, p);
hfs_unlock(VTOC(vp));
if (result) {
return (result);
}
hfs_lock_truncate(VTOC(rvp), TRUE);
Expand Down
Loading

0 comments on commit ab636a6

Please sign in to comment.