diff options
Diffstat (limited to 'sys/contrib/lomac/lomacfs_vnops.c')
-rw-r--r-- | sys/contrib/lomac/lomacfs_vnops.c | 1141 |
1 files changed, 0 insertions, 1141 deletions
diff --git a/sys/contrib/lomac/lomacfs_vnops.c b/sys/contrib/lomac/lomacfs_vnops.c deleted file mode 100644 index daae064..0000000 --- a/sys/contrib/lomac/lomacfs_vnops.c +++ /dev/null @@ -1,1141 +0,0 @@ -/*- - * Copyright (c) 2001 Networks Associates Technology, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/mutex.h> -#include <sys/proc.h> -#include <sys/mount.h> -#include <sys/namei.h> -#include <sys/sysctl.h> -#include <sys/vnode.h> - -#include <vm/vm.h> -#include <vm/vm_object.h> -#include <vm/vnode_pager.h> - -#include <machine/limits.h> - -#include "lomacfs.h" -#include "kernel_mediate.h" -#include "kernel_monitor.h" - -#if defined(LOMAC_DEBUG_LOOKUPSTATS) -static unsigned int lomacfs_successful_lookups, lomacfs_failed_lookups, - lomacfs_successful_cachedlookups, lomacfs_failed_cachedlookups, - lomacfs_node_alloc_clashes, lomacfs_node_alloc_failures; - -SYSCTL_NODE(_vfs, OID_AUTO, lomacfs, CTLFLAG_RW, 0, "LOMACFS filesystem"); -SYSCTL_NODE(_vfs_lomacfs, OID_AUTO, debug, CTLFLAG_RW, 0, "debug stats"); -SYSCTL_UINT(_vfs_lomacfs_debug, OID_AUTO, successful_lookups, - CTLFLAG_RW, &lomacfs_successful_lookups, 0, ""); -SYSCTL_UINT(_vfs_lomacfs_debug, OID_AUTO, failed_lookups, - CTLFLAG_RW, &lomacfs_failed_lookups, 0, ""); -SYSCTL_UINT(_vfs_lomacfs_debug, OID_AUTO, successful_cachedlookups, - CTLFLAG_RW, &lomacfs_successful_cachedlookups, 0, ""); -SYSCTL_UINT(_vfs_lomacfs_debug, OID_AUTO, failed_cachedlookups, - CTLFLAG_RW, &lomacfs_failed_cachedlookups, 0, ""); -SYSCTL_UINT(_vfs_lomacfs_debug, OID_AUTO, node_alloc_clashes, - CTLFLAG_RW, &lomacfs_node_alloc_clashes, 0, ""); -SYSCTL_UINT(_vfs_lomacfs_debug, OID_AUTO, node_alloc_failures, - CTLFLAG_RW, &lomacfs_node_alloc_failures, 0, ""); -#endif - -static int -lomacfs_defaultop( - struct vop_generic_args /* { - struct vnodeop_desc *a_desc; - } */ *ap -) { - - printf("lomacfs: %s unsupported\n", ap->a_desc->vdesc_name); - return (EOPNOTSUPP); -} - -static int -lomacfs_inactive( - struct vop_inactive_args /* { - struct vnode *a_vp; - struct thread *a_td; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - struct vnode *lvp = VTOLVP(vp); - struct thread *td = ap->a_td; - - KASSERT(lvp != NULL, ("inactive with NULL lowervp")); - VOP_UNLOCK(ap->a_vp, 0, td); - /* - * Temporarily drop our reference to the lower vnode, while keeping - * it held, to possibly call VOP_INACTIVE() on the lower layer. - */ - vrele(lvp); -#if defined(LOMAC_DEBUG_INACTIVE) - do { -#if defined(LOMAC_DEBUG_INCNAME) - const char *name = VTOLOMAC(vp)->ln_name; -#else - const char *name = "[unknown]"; -#endif - printf("lomacfs: inactive(%p \"%s\"), lvp usecount down to %u\n", - vp, name, lvp->v_usecount); - } while (0); -#endif - /* - * Since the lower fs may actually remove the vnode on last - * release, destroy ourselves mostly here if that occurs. - * - * Additionally, devices should be totally freed - * on last close, not lazily. - */ - if (lvp->v_usecount == 0 && - (lvp->v_type != VREG && lvp->v_type != VDIR)) { - vdrop(lvp); - VTOLVP(vp) = NULL; - cache_purge(vp); - } else - vref(lvp); - return (0); -} - -static int -lomacfs_reclaim( - struct vop_reclaim_args /* { - struct vnode *a_vp; - struct thread *a_td; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - struct lomac_node *ln = VTOLOMAC(vp); - struct vnode *lvp = VTOLVP(vp); - - if (lvp != NULL) - vrele(lvp); -#if defined(LOMAC_DEBUG_RECLAIM) - if (lvp != NULL) { -#if defined(LOMAC_DEBUG_INCNAME) - const char *name = ln->ln_name; -#else - const char *name = "[unknown]"; -#endif - printf("lomacfs: reclaim(%p \"%s\"), lvp usecount down to %u\n", - vp, name, lvp->v_usecount); - } -#endif - if (lvp != NULL) - vdrop(lvp); - vp->v_data = NULL; - vp->v_rdev = NULL; - free(ln, M_LOMACFS); - - return (0); -} - -static int -lomacfs_print( - struct vop_print_args /* { - struct vnode *a_vp; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - - printf ("\ttag VT_LOMACFS, vp=%p, lowervp=%p\n", vp, - VTOLVP(vp)); - return (0); -} - -static int -lomacfs_lock( - struct vop_lock_args /* { - struct vnode *a_vp; - int a_flags; - struct thread *a_td; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - int flags = ap->a_flags; - struct thread *td = ap->a_td; - struct vnode *lvp; - int lflags = flags & ~(LK_INTERLOCK | LK_THISLAYER); - int error; - - /* - * To prevent race conditions involving doing a lookup - * on "..", we have to lock the lower node, then lock our - * node. Most of the time it won't matter that we lock our - * node (as any locking would need the lower one locked - * first). But we can LK_DRAIN the upper lock as a step - * towards decomissioning it. - */ - lvp = VTOLVP(vp); - if (lvp == NULL || flags & LK_THISLAYER) - return (lockmgr(&vp->v_lock, flags, &vp->v_interlock, td)); - if (flags & LK_INTERLOCK) { - mtx_unlock(&vp->v_interlock); - flags &= ~LK_INTERLOCK; - } - if ((flags & LK_TYPE_MASK) == LK_DRAIN) { - error = vn_lock(lvp, - (lflags & ~LK_TYPE_MASK) | LK_EXCLUSIVE | LK_CANRECURSE, - td); - } else - error = vn_lock(lvp, lflags | LK_CANRECURSE, td); - if (error) - return (error); - error = lockmgr(&vp->v_lock, flags, &vp->v_interlock, td); - if (error) - VOP_UNLOCK(lvp, 0, td); - return (error); -} - -/* - * We need to process our own vnode unlock and then clear the - * interlock flag as it applies only to our vnode, not the - * vnodes below us on the stack. - */ -static int -lomacfs_unlock( - struct vop_unlock_args /* { - struct vnode *a_vp; - int a_flags; - struct thread *a_td; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - int flags = ap->a_flags; - int lflags = (ap->a_flags | LK_RELEASE) & - ~(LK_THISLAYER | LK_INTERLOCK); - struct thread *td = ap->a_td; - struct vnode *lvp = VTOLVP(vp); - int error; - - error = lockmgr(&vp->v_lock, flags | LK_RELEASE, &vp->v_interlock, td); - if (lvp == NULL || flags & LK_THISLAYER || error) - return (error); - /* - * Hmm... in a vput(), this means we'll grab the lomacfs interlock, - * then the lower interlock. I don't think this matters, though, - * since both won't be held at the same time. - */ - if (lvp != NULL) - error = VOP_UNLOCK(lvp, lflags, td); - return (error); -} - -static int -lomacfs_islocked( - struct vop_islocked_args /* { - struct vnode *a_vp; - struct thread *a_td; - } */ *ap -) { - - struct vnode *vp = ap->a_vp; - struct thread *td = ap->a_td; - - return (lockstatus(&vp->v_lock, td)); -} - -static int -lomacfs_lookup( - struct vop_lookup_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - } */ *ap -) { - int error; - - error = vfs_cache_lookup(ap); -#if defined(LOMAC_DEBUG_LOOKUPSTATS) - if (error == 0) - lomacfs_successful_lookups++; - else - lomacfs_failed_lookups++; -#endif -#if defined(LOMAC_DEBUG_LOOKUP) - if (error == 0 && (*ap->a_vpp)->v_mount == dvp->v_mount) { - struct vnode *vp = *ap->a_vpp; -#if defined(LOMAC_DEBUG_INCNAME) - const char *name = VTOLOMAC(vp)->ln_name; -#else - const char *name = "[unknown]"; -#endif - printf("lomacfs: lookup(%p \"%s\"), lvp usecount up to %u\n", - vp, name, VTOLVP(vp)->v_usecount); - } -#endif - return (error); -} - -static int -lomacfs_cachedlookup( - struct vop_lookup_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - } */ *ap -) { - struct vnode *dvp = ap->a_dvp; - struct componentname *cnp = ap->a_cnp; - struct vnode *ldvp = VTOLVP(dvp); - struct vnode *lvp; - int makeentry; - int error; - - if (cnp->cn_flags & ISLASTCN && cnp->cn_nameiop != LOOKUP && - cnp->cn_nameiop != CREATE) { - lomac_object_t lobj = { LO_TYPE_LVNODE, { dvp } }; - const char *op; - - if (cnp->cn_nameiop == DELETE) - op = "delete"; - else - op = "rename"; - - if (!mediate_subject_object(op, curthread->td_proc, &lobj)) - return (EPERM); - } - makeentry = cnp->cn_flags & MAKEENTRY; - cnp->cn_flags &= ~makeentry; - error = VOP_LOOKUP(ldvp, &lvp, cnp); - cnp->cn_flags |= makeentry; - if ((error == 0 || error == EJUSTRETURN) && - cnp->cn_flags != (cnp->cn_flags | LOCKPARENT | ISLASTCN)) - (void)VOP_UNLOCK(dvp, LK_THISLAYER, curthread); - if (error == 0 && lvp->v_type != VSOCK) { - struct mount *mp; - - /* - * Check to see if the vnode has been mounted on; - * if so find the root of the mounted file system. - */ - if (lvp->v_type == VDIR && (mp = lvp->v_mountedhere) && - (cnp->cn_flags & NOCROSSMOUNT) == 0) { - struct vnode *tdp; - - if (vfs_busy(mp, 0, 0, curthread)) - goto forget_it; - VOP_UNLOCK(lvp, 0, curthread); - error = VFS_ROOT(mp, &tdp); - vfs_unbusy(mp, curthread); - if (error) { - vrele(lvp); - return (error); - } - vrele(lvp); - lvp = tdp; - } -forget_it: - /* - * For a create or for devices (dynamic things, aren't they), - * don't enter the vnode into the cache. - */ - if (cnp->cn_nameiop == CREATE || lvp->v_type == VCHR) - cnp->cn_flags &= ~makeentry; - /* - * The top half of dvp is locked, but ldvp is unlocked. - * Additionally, lvp is locked already, and - * lomacfs_node_alloc() always returns it locked. - */ - error = lomacfs_node_alloc(dvp->v_mount, cnp, - dvp, lvp, ap->a_vpp); - if (cnp->cn_nameiop == CREATE) - cnp->cn_flags |= makeentry; -#if defined(LOMAC_DEBUG_LOOKUPSTATS) - if (error) { - if (error != EEXIST) { - lomacfs_node_alloc_failures++; - } else { - lomacfs_node_alloc_clashes++; - error = 0; - } - } -#else - if (error == EEXIST) - error = 0; -#endif - } else if (error == 0) { - /* - * For sockets, just return the "real" thing - * after entering it into the cache. - */ - *ap->a_vpp = lvp; - if (cnp->cn_nameiop != CREATE && cnp->cn_flags & MAKEENTRY) - cache_enter(dvp, lvp, cnp); - } - -#if defined(LOMAC_DEBUG_LOOKUPSTATS) - if (error == 0) - lomacfs_successful_cachedlookups++; - else - lomacfs_failed_cachedlookups++; -#endif - return (error); -} - -static int -lomacfs_getattr( - struct vop_getattr_args /* { - struct vnode *a_vp; - struct vattr *a_vap; - struct ucred *a_cred; - struct thread *a_td; - */ *ap -) { - struct vnode *vp = ap->a_vp; - struct vattr *vap = ap->a_vap; - int error; - - error = VOP_GETATTR(VTOLVP(vp), vap, ap->a_cred, ap->a_td); - if (error == 0 && vap->va_fsid == VNOVAL) - vap->va_fsid = VTOLVP(vp)->v_mount->mnt_stat.f_fsid.val[0]; - return (error); -} - -static int -lomacfs_setattr( - struct vop_getattr_args /* { - struct vnode *a_vp; - struct vattr *a_vap; - struct ucred *a_cred; - struct thread *a_td; - */ *ap -) { - lomac_object_t lobj = { LO_TYPE_LVNODE, { ap->a_vp } }; - int error; - - if (mediate_subject_object(ap->a_desc->vdesc_name, curthread->td_proc, - &lobj)) - error = VOP_SETATTR(VTOLVP(ap->a_vp), ap->a_vap, ap->a_cred, - ap->a_td); - else - error = EPERM; - return (error); -} - -static int -lomacfs_readdir( - struct vop_readdir_args /* { - struct vnode *a_vp; - struct uio *a_uio; - struct ucred *a_cred; - int *a_eofflag; - int *a_ncookies; - u_long **a_cookies; - } */ *ap -) { - - return (VOP_READDIR(VTOLVP(ap->a_vp), ap->a_uio, ap->a_cred, - ap->a_eofflag, ap->a_ncookies, ap->a_cookies)); -} - -static int -lomacfs_open( - struct vop_open_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - lomac_object_t lobj; - int error; - - lobj.lo_type = LO_TYPE_LVNODE; - lobj.lo_object.vnode = ap->a_vp; - if (!mediate_subject_object_open(ap->a_td->td_proc, &lobj)) - error = EPERM; - else - error = VOP_OPEN(VTOLVP(ap->a_vp), ap->a_mode, ap->a_cred, - ap->a_td); - return (error); -} - -static int -lomacfs_close( - struct vop_close_args /* { - struct vnode *a_vp; - int a_fflag; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - struct vnode *lvp = VTOLVP(vp); - int error; - - /* - * XXX - * Try to cope with the horrible semantics introduced here... - */ - vref(lvp); - error = VOP_CLOSE(lvp, ap->a_fflag, ap->a_cred, ap->a_td); - if (error == EAGAIN) - error = 0; - else - vrele(lvp); - return (error); -} - -static int -lomacfs_access( - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - - return (VOP_ACCESS(VTOLVP(ap->a_vp), ap->a_mode, ap->a_cred, ap->a_td)); -} - -static int -lomacfs_readlink( - struct vop_readlink_args /* { - struct vnode *a_vp; - struct uio *a_uio; - struct ucred *a_cred; - } */ *ap -) { - struct vnode *lvp = VTOLVP(ap->a_vp); - - if (lvp == NULL) - return (EPERM); - return (VOP_READLINK(lvp, ap->a_uio, ap->a_cred)); -} - -static int -lomacfs_lease( - struct vop_lease_args /* { - struct vnode *a_vp; - struct thread *a_td; - struct ucred *a_cred; - int a_flag; - } */ *ap -) { - struct vnode *lvp = VTOLVP(ap->a_vp); - - return (VOP_LEASE(lvp, ap->a_td, ap->a_cred, ap->a_flag)); -} - -static int -lomacfs_read( - struct vop_read_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap -) { - struct vnode *lvp = VTOLVP(ap->a_vp); - lomac_object_t lobj = { LO_TYPE_LVNODE, { ap->a_vp } }; - int error; - - error = monitor_read_object(curthread->td_proc, &lobj); - if (error == 0) - error = VOP_READ(lvp, ap->a_uio, ap->a_ioflag, ap->a_cred); - return (error); -} - -static int -lomacfs_write( - struct vop_write_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *ap -) { - struct vnode *lvp = VTOLVP(ap->a_vp); - lomac_object_t lobj = { LO_TYPE_LVNODE, { ap->a_vp } }; - int error; - - if (mediate_subject_object(ap->a_desc->vdesc_name, curthread->td_proc, - &lobj)) - error = VOP_WRITE(lvp, ap->a_uio, ap->a_ioflag, ap->a_cred); - else - error = EPERM; - return (error); -} - -static int -lomacfs_ioctl( - struct vop_ioctl_args /* { - struct vnode *a_vp; - u_long a_command; - caddr_t a_data; - int a_fflag; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - struct vnode *lvp = VTOLVP(ap->a_vp); - - return (VOP_IOCTL(lvp, ap->a_command, ap->a_data, ap->a_fflag, - ap->a_cred, ap->a_td)); -} - -static int -lomacfs_muxcreate( - struct vop_create_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - struct vattr *a_vap; - } */ *ap -) { - struct vnode *dvp = ap->a_dvp; - struct vnode *ldvp = VTOLVP(dvp); - struct componentname *cnp = ap->a_cnp; - struct vattr *vap = ap->a_vap; - int makeentry = cnp->cn_flags & MAKEENTRY; - lomac_object_t lobj = { LO_TYPE_LVNODE, { dvp } }; - struct thread *td = curthread; - int error; - - if (!mediate_subject_object(ap->a_desc->vdesc_name, td->td_proc, - &lobj) || (vap->va_type == VCHR && - !mediate_subject_at_level("mknod", curthread->td_proc, - LOMAC_HIGHEST_LEVEL))) - return (EPERM); - ap->a_dvp = ldvp; - cnp->cn_flags &= ~makeentry; - error = VCALL(ldvp, ap->a_desc->vdesc_offset, ap); - if (error == 0) { - struct vnode *vp; - int issock; - - issock = vap->va_type == VSOCK; - vp = *ap->a_vpp; - *ap->a_vpp = NULL; - if (!issock) - cnp->cn_flags |= makeentry; - error = lomacfs_node_alloc(dvp->v_mount, cnp, dvp, vp, - ap->a_vpp); - if (error) - vput(vp); - else if (issock) { - /* - * I should really find a nicer way to do this. - */ - vref(vp); - vput(*ap->a_vpp); - *ap->a_vpp = vp; - (void)VOP_LOCK(vp, LK_EXCLUSIVE | LK_RETRY, td); - } - } - return (error); -} - -static int -lomacfs_muxremove( - struct vop_remove_args /* { - struct vnode *a_dvp; - struct vnode *a_vp; - struct componentname *a_cnp; - } */ *ap -) { - struct vnode *dvp = ap->a_dvp; - struct vnode *vp = ap->a_vp; - int error; - - ap->a_dvp = VTOLVP(dvp); - if (VISLOMAC(vp)) - ap->a_vp = VTOLVP(vp); - error = VCALL(ap->a_dvp, ap->a_desc->vdesc_offset, ap); - if (error == 0) - cache_purge(vp); - return (error); -} - -static int -lomacfs_fsync( - struct vop_fsync_args /* { - struct vnode *a_vp; - struct ucred *a_cred; - int a_waitfor; - struct thread *a_td; - } */ *ap -) { - - return (VOP_FSYNC(VTOLVP(ap->a_vp), ap->a_cred, ap->a_waitfor, - ap->a_td)); -} - -static int -lomacfs_advlock( - struct vop_advlock_args /* { - struct vnode *a_vp; - caddr_t a_id; - int a_op; - struct flock *a_fl; - int a_flags; - } */ *ap -) { - - return (VOP_ADVLOCK(VTOLVP(ap->a_vp), ap->a_id, ap->a_op, ap->a_fl, - ap->a_flags)); -} - -static int -lomacfs_whiteout( - struct vop_whiteout_args /* { - struct vnode *a_dvp; - struct componentname *a_cnp; - int a_flags; - } */ *ap -) { - - return (VOP_WHITEOUT(VTOLVP(ap->a_dvp), ap->a_cnp, ap->a_flags)); -} - -static int -lomacfs_poll( - struct vop_poll_args /* { - struct vnode *a_vp; - int a_events; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - - return (VOP_POLL(VTOLVP(ap->a_vp), ap->a_events, ap->a_cred, ap->a_td)); -} - -static int -lomacfs_revoke( - struct vop_revoke_args /* { - struct vnode *a_vp; - int a_flags; - } */ *ap -) { - - return (VOP_REVOKE(VTOLVP(ap->a_vp), ap->a_flags)); -} - -static int -lomacfs_link( - struct vop_link_args /* { - struct vnode *a_tdvp; - struct vnode *a_vp; - struct componentname *a_cnp; - } */ *ap -) { - struct vnode *tdvp = ap->a_tdvp; - struct vnode *vp = ap->a_vp; - struct vnode *lvp = VISLOMAC(vp) ? VTOLVP(vp) : vp; - struct componentname *cnp = ap->a_cnp; - int error; - - error = VOP_LINK(VTOLVP(tdvp), lvp, cnp); - if (error == 0 && vp->v_type == VSOCK) { - cache_enter(tdvp, vp, cnp); -#if defined(LOMAC_DEBUG_LINK) - do { - struct vnode *nvp; - int nerror; - - nerror = cache_lookup(tdvp, &nvp, cnp); - printf("lomacfs: link(%p), cache_lookup() = %d (%p)\n", - vp, nerror, nvp); - } while (0); -#endif - } - return (error); -} - -static int -lomacfs_rename( - struct vop_rename_args /* { - struct vnode *a_fdvp; - struct vnode *a_fvp; - struct componentname *a_fcnp; - struct vnode *a_tdvp; - struct vnode *a_tvp; - struct componentname *a_tcnp; - } */ *ap -) { - struct vnode *fdvp = ap->a_fdvp; - struct vnode *fvp = ap->a_fvp; - struct componentname *fcnp = ap->a_fcnp; - struct vnode *tdvp = ap->a_tdvp; - struct vnode *tvp = ap->a_tvp; - struct componentname *tcnp = ap->a_tcnp; - int fvp_is_lomac = VISLOMAC(fvp); - int error; - - vref(VTOLVP(fdvp)); - /* - * Handle the case when LOMAC returns a real vnode for - * VSOCK, rather than the LOMAC covering vnode. - */ - if (fvp_is_lomac) - vref(VTOLVP(fvp)); - vref(VTOLVP(tdvp)); - if (tvp != NULL) - vref(VTOLVP(tvp)); - error = VOP_RENAME(VTOLVP(fdvp), fvp_is_lomac ? VTOLVP(fvp) : fvp, fcnp, - VTOLVP(tdvp), tvp != NULL ? VTOLVP(tvp) : NULL, tcnp); - if (fvp->v_type == VDIR) { - if (tvp != NULL && tvp->v_type == VDIR) - cache_purge(tdvp); - cache_purge(fdvp); - } - cache_purge(fvp); - if (tvp != NULL) - cache_purge(tvp); - (void)VOP_UNLOCK(tdvp, LK_THISLAYER, curthread); - vrele(fdvp); - if (fvp_is_lomac) - vrele(fvp); - vrele(tdvp); - if (tvp != NULL) { - (void)VOP_UNLOCK(tvp, LK_THISLAYER, curthread); - vrele(tvp); - } else if (tcnp->cn_nameiop == RENAME /* NOCACHE unsets MAKEENTRY */ - && fvp->v_type == VSOCK) - cache_enter(tdvp, fvp, tcnp); - return (error); -} - -static int -lomacfs_strategy( - struct vop_strategy_args /* { - struct vnode *a_vp; - struct buf *a_bp; - } */ *ap -) { - - return (VOP_STRATEGY(VTOLVP(ap->a_vp), ap->a_bp)); -} - -/* - * Let an underlying filesystem do the work of creating the "actual" - * vm_object_t, and we will reference it. - */ -static int -lomacfs_createvobject( - struct vop_createvobject_args /* { - struct vnode *vp; - struct ucred *cred; - struct proc *p; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - struct vnode *lowervp = VTOLOMAC(vp) != NULL ? VTOLVP(vp) : NULL; - int error; - - if (vp->v_type == VNON || lowervp == NULL) - return (EINVAL); - error = VOP_CREATEVOBJECT(lowervp, ap->a_cred, ap->a_td); - if (error) - return (error); - vp->v_flag |= VOBJBUF; - return (error); -} - -/* - * We need to destroy the lower vnode object only if we created it. - * XXX - I am very unsure about all of this. - */ -static int -lomacfs_destroyvobject( - struct vop_destroyvobject_args /* { - struct vnode *vp; - } */ *ap -) { - struct vnode *vp = ap->a_vp; - - vp->v_flag &= ~VOBJBUF; - return (0); -} - -static int -lomacfs_bmap( - struct vop_bmap_args /* { - struct vnode *a_vp; - daddr_t a_bn; - struct vnode **a_vpp; - daddr_t *a_bnp; - int *a_runp; - int *a_runb; - } */ *ap -) { - - return (VOP_BMAP(VTOLVP(ap->a_vp), ap->a_bn, ap->a_vpp, ap->a_bnp, - ap->a_runp, ap->a_runb)); -} - -static int -lomacfs_getpages( - struct vop_getpages_args /* { - struct vnode *a_vp; - vm_page_t *a_m; - int a_count; - int a_reqpage; - vm_ooffset_t a_offset; - } */ *ap -) { - - return (VOP_GETPAGES(VTOLVP(ap->a_vp), ap->a_m, ap->a_count, - ap->a_reqpage, ap->a_offset)); -} - -static int -lomacfs_putpages( - struct vop_putpages_args /* { - struct vnode *a_vp; - vm_page_t *a_m; - int a_count; - int a_sync; - int *a_rtvals; - vm_ooffset_t a_offset; - } */ *ap -) { - - return (VOP_PUTPAGES(VTOLVP(ap->a_vp), ap->a_m, ap->a_count, - ap->a_sync, ap->a_rtvals, ap->a_offset)); -} - -static int -lomacfs_getvobject( - struct vop_getvobject_args /* { - struct vnode *a_vp; - struct vm_object **a_objpp; - } */ *ap -) { - struct vnode *lvp = VTOLVP(ap->a_vp); - - if (lvp == NULL) - return EINVAL; - return (VOP_GETVOBJECT(lvp, ap->a_objpp)); -} - -static int -lomacfs_kqfilter( - struct vop_kqfilter_args /* { - struct vnode *a_vp; - struct knote *a_kn; - } */ *ap -) { - - return (VOP_KQFILTER(VTOLVP(ap->a_vp), ap->a_kn)); -} - -static int -lomacfs_pathconf( - struct vop_pathconf_args /* { - struct vnode *a_vp; - int a_name; - register_t *a_retval; - } */ *ap -) { - - return (VOP_PATHCONF(VTOLVP(ap->a_vp), ap->a_name, ap->a_retval)); -} - -static int -lomacfs_reallocblks( - struct vop_reallocblks_args /* { - struct vnode *a_vp; - struct cluster_save *a_buflist; - } */ *ap -) { - - return (VOP_REALLOCBLKS(VTOLVP(ap->a_vp), ap->a_buflist)); -} - -static int -lomacfs_freeblks( - struct vop_freeblks_args /* { - struct vnode *a_vp; - daddr_t a_addr; - daddr_t a_length; - } */ *ap -) { - - return (VOP_FREEBLKS(VTOLVP(ap->a_vp), ap->a_addr, ap->a_length)); -} - -static int -lomacfs_getacl( - struct vop_getacl_args /* { - struct vnode *a_vp; - acl_type_t a_type; - struct acl *a_aclp; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - - return (VOP_GETACL(VTOLVP(ap->a_vp), ap->a_type, ap->a_aclp, ap->a_cred, - ap->a_td)); -} - -static int -lomacfs_setacl( - struct vop_setacl_args /* { - struct vnode *a_vp; - acl_type_t a_type; - struct acl *a_aclp; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - lomac_object_t lobj; - - lobj.lo_type = LO_TYPE_LVNODE; - lobj.lo_object.vnode = ap->a_vp; - if (!mediate_subject_object("setacl", ap->a_td->td_proc, &lobj)) - return (EPERM); - else - return (VOP_SETACL(VTOLVP(ap->a_vp), ap->a_type, ap->a_aclp, - ap->a_cred, ap->a_td)); -} - -static int -lomacfs_aclcheck( - struct vop_aclcheck_args /* { - struct vnode *a_vp; - acl_type_t a_type; - struct acl *a_aclp; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - - return (VOP_ACLCHECK(VTOLVP(ap->a_vp), ap->a_type, ap->a_aclp, - ap->a_cred, ap->a_td)); -} - -static int -lomacfs_getextattr( - struct vop_getextattr_args /* { - struct vnode *a_vp; - int a_attrnamespace; - const char *a_name; - struct uio *a_uio; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - lomac_object_t lobj; - - lobj.lo_type = LO_TYPE_LVNODE; - lobj.lo_object.vnode = ap->a_vp; - if (monitor_read_object(ap->a_td->td_proc, &lobj)) - return (EPERM); - else - return (VOP_GETEXTATTR(VTOLVP(ap->a_vp), ap->a_attrnamespace, - ap->a_name, ap->a_uio, ap->a_cred, ap->a_td)); -} - -static int -lomacfs_setextattr( - struct vop_setextattr_args /* { - struct vnode *a_vp; - int a_attrnamespace; - const char *a_name; - struct uio *a_uio; - struct ucred *a_cred; - struct thread *a_td; - } */ *ap -) { - lomac_object_t lobj; - - lobj.lo_type = LO_TYPE_LVNODE; - lobj.lo_object.vnode = ap->a_vp; - if (!mediate_subject_object("setextattr", ap->a_td->td_proc, &lobj)) - return (EPERM); - else - return (VOP_SETEXTATTR(VTOLVP(ap->a_vp), ap->a_attrnamespace, - ap->a_name, ap->a_uio, ap->a_cred, ap->a_td)); -} - -vop_t **lomacfs_vnodeop_p; -static struct vnodeopv_entry_desc lomacfs_vnodeop_entries[] = { - { &vop_default_desc, (vop_t *)lomacfs_defaultop }, - { &vop_inactive_desc, (vop_t *)lomacfs_inactive }, - { &vop_reclaim_desc, (vop_t *)lomacfs_reclaim }, - { &vop_print_desc, (vop_t *)lomacfs_print }, - { &vop_lock_desc, (vop_t *)lomacfs_lock }, - { &vop_unlock_desc, (vop_t *)lomacfs_unlock }, - { &vop_islocked_desc, (vop_t *)lomacfs_islocked }, - { &vop_lookup_desc, (vop_t *)lomacfs_lookup }, - { &vop_setattr_desc, (vop_t *)lomacfs_setattr }, - { &vop_getattr_desc, (vop_t *)lomacfs_getattr }, - { &vop_readdir_desc, (vop_t *)lomacfs_readdir }, - { &vop_open_desc, (vop_t *)lomacfs_open }, - { &vop_close_desc, (vop_t *)lomacfs_close }, - { &vop_access_desc, (vop_t *)lomacfs_access }, - { &vop_readlink_desc, (vop_t *)lomacfs_readlink }, - { &vop_lease_desc, (vop_t *)lomacfs_lease }, - { &vop_read_desc, (vop_t *)lomacfs_read }, - { &vop_write_desc, (vop_t *)lomacfs_write }, - { &vop_ioctl_desc, (vop_t *)lomacfs_ioctl }, - { &vop_create_desc, (vop_t *)lomacfs_muxcreate }, - { &vop_mkdir_desc, (vop_t *)lomacfs_muxcreate }, - { &vop_mknod_desc, (vop_t *)lomacfs_muxcreate }, - { &vop_symlink_desc, (vop_t *)lomacfs_muxcreate }, - { &vop_remove_desc, (vop_t *)lomacfs_muxremove }, - { &vop_rmdir_desc, (vop_t *)lomacfs_muxremove }, - { &vop_fsync_desc, (vop_t *)lomacfs_fsync }, - { &vop_advlock_desc, (vop_t *)lomacfs_advlock }, - { &vop_whiteout_desc, (vop_t *)lomacfs_whiteout }, - { &vop_poll_desc, (vop_t *)lomacfs_poll }, - { &vop_link_desc, (vop_t *)lomacfs_link }, - { &vop_rename_desc, (vop_t *)lomacfs_rename }, - { &vop_revoke_desc, (vop_t *)lomacfs_revoke }, - { &vop_cachedlookup_desc, (vop_t *)lomacfs_cachedlookup }, - { &vop_lookup_desc, (vop_t *)lomacfs_lookup }, - { &vop_bmap_desc, (vop_t *)lomacfs_bmap }, - { &vop_getpages_desc, (vop_t *)lomacfs_getpages }, - { &vop_putpages_desc, (vop_t *)lomacfs_putpages }, - { &vop_strategy_desc, (vop_t *)lomacfs_strategy }, - { &vop_createvobject_desc, (vop_t *)lomacfs_createvobject }, - { &vop_destroyvobject_desc, (vop_t *)lomacfs_destroyvobject }, - { &vop_getvobject_desc, (vop_t *)lomacfs_getvobject }, - { &vop_getwritemount_desc, (vop_t *)vop_stdgetwritemount }, - { &vop_kqfilter_desc, (vop_t *)lomacfs_kqfilter }, - { &vop_pathconf_desc, (vop_t *)lomacfs_pathconf }, - { &vop_reallocblks_desc, (vop_t *)lomacfs_reallocblks }, - { &vop_freeblks_desc, (vop_t *)lomacfs_freeblks }, - { &vop_getacl_desc, (vop_t *)lomacfs_getacl }, - { &vop_setacl_desc, (vop_t *)lomacfs_setacl }, - { &vop_aclcheck_desc, (vop_t *)lomacfs_aclcheck }, - { &vop_getextattr_desc, (vop_t *)lomacfs_getextattr }, - { &vop_setextattr_desc, (vop_t *)lomacfs_setextattr }, - { NULL, NULL } -}; -static struct vnodeopv_desc lomacfs_vnodeopv_opv_desc = - { &lomacfs_vnodeop_p, lomacfs_vnodeop_entries }; -VNODEOP_SET(lomacfs_vnodeopv_opv_desc); |