/*
- * Copyright (c) 2000-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2018 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
return (ENOMEM);
}
+#define DBG_MOUNTROOT (FSDBG_CODE(DBG_MOUNT, 0))
/*
* Find an appropriate filesystem to use for the root. If a filesystem
mount_t mp;
vnode_t bdevvp_rootvp;
+ KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_START);
if (mountroot != NULL) {
/*
* used for netboot which follows a different set of rules
*/
error = (*mountroot)();
+
+ KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, error, 0);
return (error);
}
if ((error = bdevvp(rootdev, &rootvp))) {
printf("vfs_mountroot: can't setup bdevvp\n");
+
+ KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, error, 1);
return (error);
}
/*
vnode_put(rootvp);
#if CONFIG_MACF
- if ((vfs_flags(mp) & MNT_MULTILABEL) == 0)
+ if ((vfs_flags(mp) & MNT_MULTILABEL) == 0) {
+ KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, 0, 2);
return (0);
+ }
error = VFS_ROOT(mp, &vp, ctx);
if (error) {
goto fail;
}
#endif
+ KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, 0, 3);
return (0);
}
#if CONFIG_MACF
fail:
#endif
vfs_rootmountfailed(mp);
-
+
if (error != EINVAL)
printf("%s_mountroot failed: %d\n", vfsp->vfc_name, error);
}
+ KDBG_RELEASE(DBG_MOUNTROOT | DBG_FUNC_END, error ? error : ENODEV, 4);
return (ENODEV);
}
temp = MNT_DEFAULT_IOQUEUE_DEPTH;
mp->mnt_ioqueue_depth = temp;
- mp->mnt_ioscale = (mp->mnt_ioqueue_depth + (MNT_DEFAULT_IOQUEUE_DEPTH - 1)) / MNT_DEFAULT_IOQUEUE_DEPTH;
+ mp->mnt_ioscale = MNT_IOSCALE(mp->mnt_ioqueue_depth);
if (mp->mnt_ioscale > 1)
printf("ioqueue_depth = %d, ioscale = %d\n", (int)mp->mnt_ioqueue_depth, (int)mp->mnt_ioscale);
if (space < req->oldlen)
return (ENOMEM);
- MALLOC(fsidlst, fsid_t *, req->oldlen, M_TEMP, M_WAITOK);
+ MALLOC(fsidlst, fsid_t *, req->oldlen, M_TEMP, M_WAITOK | M_ZERO);
if (fsidlst == NULL) {
return (ENOMEM);
}
lck_mtx_lock(fs_klist_lock);
kn->kn_sfflags = kev->fflags;
- if ((kn->kn_status & KN_UDATA_SPECIFIC) == 0)
- kn->kn_udata = kev->udata;
/*
* the above filter function sets bits even if nobody is looking for them.
{
int *name, namelen;
struct vfstable *vfsp;
- struct vfsconf vfsc;
+ struct vfsconf vfsc = {};
(void)oidp;
name = arg1;
SYSCTL_INT(_vfs_generic, VFS_MAXTYPENUM, maxtypenum,
CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
&maxvfstypenum, 0, "");
-SYSCTL_INT(_vfs_generic, OID_AUTO, sync_timeout, CTLFLAG_RW | CTLFLAG_LOCKED, &sync_timeout, 0, "");
+SYSCTL_INT(_vfs_generic, OID_AUTO, sync_timeout, CTLFLAG_RW | CTLFLAG_LOCKED, &sync_timeout_seconds, 0, "");
SYSCTL_NODE(_vfs_generic, VFS_CONF, conf,
CTLFLAG_RD | CTLFLAG_LOCKED,
sysctl_vfs_generic_conf, "");
ut = get_bsdthread_info(current_thread());
if ((current_proc()->p_lflag & P_LRAGE_VNODES) ||
- (ut->uu_flag & UT_RAGE_VNODES)) {
+ (ut->uu_flag & (UT_RAGE_VNODES | UT_KERN_RAGE_VNODES))) {
/*
* process has indicated that it wants any
* vnodes created on its behalf to be rapidly
* aged to reduce the impact on the cached set
* of vnodes
+ *
+ * if UT_KERN_RAGE_VNODES is set, then the
+ * kernel internally wants vnodes to be rapidly
+ * aged, even if the process hasn't requested
+ * this
*/
vp->v_flag |= VRAGE;
}
if (!batched) {
*vpp = (vnode_t) 0;
vnode_put(vp);
+ vp = NULLVP;
}
}
+ /*
+ * For creation VNOPs, this is the equivalent of
+ * lookup_handle_found_vnode.
+ */
+ if (kdebug_enable && *vpp)
+ kdebug_lookup(*vpp, cnp);
+
out:
vn_attribute_cleanup(vap, defaulted);
struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp,
vfs_context_t ctx, vfs_rename_flags_t flags, void *reserved)
{
+
+ return vn_authorize_renamex_with_paths(fdvp, fvp, fcnp, NULL, tdvp, tvp, tcnp, NULL, ctx, flags, reserved);
+}
+
+int
+vn_authorize_renamex_with_paths(struct vnode *fdvp, struct vnode *fvp, struct componentname *fcnp, const char *from_path,
+ struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp, const char *to_path,
+ vfs_context_t ctx, vfs_rename_flags_t flags, void *reserved)
+{
int error = 0;
int moving = 0;
bool swap = flags & VFS_RENAME_SWAP;
/***** <Kauth> *****/
+ /*
+ * As part of the Kauth step, we call out to allow 3rd-party
+ * fileop notification of "about to rename". This is needed
+ * in the event that 3rd-parties need to know that the DELETE
+ * authorization is actually part of a rename. It's important
+ * that we guarantee that the DELETE call-out will always be
+ * made if the WILL_RENAME call-out is made. Another fileop
+ * call-out will be performed once the operation is completed.
+ * We can ignore the result of kauth_authorize_fileop().
+ *
+ * N.B. We are passing the vnode and *both* paths to each
+ * call; kauth_authorize_fileop() extracts the "from" path
+ * when posting a KAUTH_FILEOP_WILL_RENAME notification.
+ * As such, we only post these notifications if all of the
+ * information we need is provided.
+ */
+
if (swap) {
kauth_action_t f = 0, t = 0;
if (vnode_isdir(tvp))
t = KAUTH_VNODE_ADD_SUBDIRECTORY;
}
+ if (to_path != NULL)
+ kauth_authorize_fileop(vfs_context_ucred(ctx),
+ KAUTH_FILEOP_WILL_RENAME,
+ (uintptr_t)fvp,
+ (uintptr_t)to_path);
error = vnode_authorize(fvp, fdvp, KAUTH_VNODE_DELETE | f, ctx);
if (error)
goto out;
+ if (from_path != NULL)
+ kauth_authorize_fileop(vfs_context_ucred(ctx),
+ KAUTH_FILEOP_WILL_RENAME,
+ (uintptr_t)tvp,
+ (uintptr_t)from_path);
error = vnode_authorize(tvp, tdvp, KAUTH_VNODE_DELETE | t, ctx);
if (error)
goto out;
* If fvp is a directory, and we are changing it's parent,
* then we also need rights to rewrite its ".." entry as well.
*/
+ if (to_path != NULL)
+ kauth_authorize_fileop(vfs_context_ucred(ctx),
+ KAUTH_FILEOP_WILL_RENAME,
+ (uintptr_t)fvp,
+ (uintptr_t)to_path);
if (vnode_isdir(fvp)) {
if ((error = vnode_authorize(fvp, fdvp, KAUTH_VNODE_DELETE | KAUTH_VNODE_ADD_SUBDIRECTORY, ctx)) != 0)
goto out;
mount_unlock(mp);
}
-
void
vnode_setswapmount(vnode_t vp)
{
lck_mtx_unlock(&rp->vr_lock);
+#if CONFIG_MACF
+ int rv = mac_vnode_check_trigger_resolve(ctx, vp, &ndp->ni_cnd);
+ if (rv != 0)
+ return rv;
+#endif
+
/*
* XXX
* assumes that resolver will not access this trigger vnode (otherwise the kernel will deadlock)
/* vn_getpath() NUL-terminates, and len includes the NUL */
if (!rv) {
- kdebug_lookup_gen_events(ctx->path, len, vp, TRUE);
+ kdebug_vfs_lookup(ctx->path, len, vp,
+ KDBG_VFS_LOOKUP_FLAG_LOOKUP | KDBG_VFS_LOOKUP_FLAG_NOPROCFILT);
if (++(ctx->count) == 1000) {
thread_yield_to_preemption();