+ vfs_context_t newcontext;
+
+ newcontext = (vfs_context_t)kalloc(sizeof(struct vfs_context));
+
+ if (newcontext) {
+ kauth_cred_t safecred;
+ if (ctx) {
+ newcontext->vc_thread = ctx->vc_thread;
+ safecred = ctx->vc_ucred;
+ } else {
+ newcontext->vc_thread = current_thread();
+ safecred = kauth_cred_get();
+ }
+ if (IS_VALID_CRED(safecred))
+ kauth_cred_ref(safecred);
+ newcontext->vc_ucred = safecred;
+ return(newcontext);
+ }
+ return(NULL);
+}
+
+
+vfs_context_t
+vfs_context_current(void)
+{
+ vfs_context_t ctx = NULL;
+ volatile uthread_t ut = (uthread_t)get_bsdthread_info(current_thread());
+
+ if (ut != NULL ) {
+ if (ut->uu_context.vc_ucred != NULL) {
+ ctx = &ut->uu_context;
+ }
+ }
+
+ return(ctx == NULL ? vfs_context_kernel() : ctx);
+}
+
+
+/*
+ * XXX Do not ask
+ *
+ * Dangerous hack - adopt the first kernel thread as the current thread, to
+ * get to the vfs_context_t in the uthread associated with a kernel thread.
+ * This is used by UDF to make the call into IOCDMediaBSDClient,
+ * IOBDMediaBSDClient, and IODVDMediaBSDClient to determine whether the
+ * ioctl() is being called from kernel or user space (and all this because
+ * we do not pass threads into our ioctl()'s, instead of processes).
+ *
+ * This is also used by imageboot_setup(), called early from bsd_init() after
+ * kernproc has been given a credential.
+ *
+ * Note: The use of proc_thread() here is a convenience to avoid inclusion
+ * of many Mach headers to do the reference directly rather than indirectly;
+ * we will need to forego this convenience when we reture proc_thread().
+ */
+static struct vfs_context kerncontext;
+vfs_context_t
+vfs_context_kernel(void)
+{
+ if (kerncontext.vc_ucred == NOCRED)
+ kerncontext.vc_ucred = kernproc->p_ucred;
+ if (kerncontext.vc_thread == NULL)
+ kerncontext.vc_thread = proc_thread(kernproc);
+
+ return(&kerncontext);
+}
+
+
+int
+vfs_context_rele(vfs_context_t ctx)
+{
+ if (ctx) {
+ if (IS_VALID_CRED(ctx->vc_ucred))
+ kauth_cred_unref(&ctx->vc_ucred);
+ kfree(ctx, sizeof(struct vfs_context));
+ }
+ return(0);
+}
+
+
+kauth_cred_t
+vfs_context_ucred(vfs_context_t ctx)
+{
+ return (ctx->vc_ucred);
+}
+
+/*
+ * Return true if the context is owned by the superuser.
+ */
+int
+vfs_context_issuser(vfs_context_t ctx)
+{
+ return(kauth_cred_issuser(vfs_context_ucred(ctx)));
+}
+
+int vfs_context_iskernel(vfs_context_t ctx)
+{
+ return ctx == &kerncontext;
+}
+
+/*
+ * Given a context, for all fields of vfs_context_t which
+ * are not held with a reference, set those fields to the
+ * values for the current execution context. Currently, this
+ * just means the vc_thread.
+ *
+ * Returns: 0 for success, nonzero for failure
+ *
+ * The intended use is:
+ * 1. vfs_context_create() gets the caller a context
+ * 2. vfs_context_bind() sets the unrefcounted data
+ * 3. vfs_context_rele() releases the context
+ *
+ */
+int
+vfs_context_bind(vfs_context_t ctx)
+{
+ ctx->vc_thread = current_thread();
+ return 0;
+}
+
+int vfs_isswapmount(mount_t mnt)
+{
+ return mnt && ISSET(mnt->mnt_kern_flag, MNTK_SWAP_MOUNT) ? 1 : 0;
+}
+
+/* XXXXXXXXXXXXXX VNODE KAPIS XXXXXXXXXXXXXXXXXXXXXXXXX */
+
+
+/*
+ * Convert between vnode types and inode formats (since POSIX.1
+ * defines mode word of stat structure in terms of inode formats).
+ */
+enum vtype
+vnode_iftovt(int mode)
+{
+ return(iftovt_tab[((mode) & S_IFMT) >> 12]);
+}
+
+int
+vnode_vttoif(enum vtype indx)
+{
+ return(vttoif_tab[(int)(indx)]);
+}
+
+int
+vnode_makeimode(int indx, int mode)
+{
+ return (int)(VTTOIF(indx) | (mode));
+}
+
+
+/*
+ * vnode manipulation functions.
+ */
+
+/* returns system root vnode iocount; It should be released using vnode_put() */
+vnode_t
+vfs_rootvnode(void)
+{
+ int error;