예제 #1
0
/*
 * nremove takes a locked, resolved ncp that generally represents a
 * positive hit and removes the file.
 *
 * The dvp passed in is referenced but unlocked.
 *
 * The namecache is automatically adjusted by this function.  The ncp
 * is left locked on return.
 *
 * MPSAFE
 */
int
vop_nremove(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp,
	    struct ucred *cred)
{
	struct vop_nremove_args ap;
	VFS_MPLOCK_DECLARE;
	int error;
	struct vattr va;

	ap.a_head.a_desc = &vop_nremove_desc;
	ap.a_head.a_ops = ops;
	ap.a_nch = nch;
	ap.a_dvp = dvp;
	ap.a_cred = cred;

	if ((error = VOP_GETATTR(nch->ncp->nc_vp, &va)) != 0)
		return (error);

	VFS_MPLOCK1(dvp->v_mount);
	DO_OPS(ops, error, &ap, vop_nremove);
	/* Only update space counters if this is the last hard link */
	if ((error == 0) && (va.va_nlink == 1)) {
		VFS_ACCOUNT(nch->mount, va.va_uid, va.va_gid, -va.va_size);
	}
	VFS_MPUNLOCK(dvp->v_mount);
	return(error);
}
예제 #2
0
/*
 * NOTE: VAGE is always cleared when calling VOP_OPEN().
 */
int
vop_open(struct vop_ops *ops, struct vnode *vp, int mode, struct ucred *cred,
	struct file *fp)
{
	struct vop_open_args ap;
	VFS_MPLOCK_DECLARE;
	int error;

	/*
	 * Decrement 3-2-1-0.  Does not decrement beyond 0
	 */
	if (vp->v_flag & VAGE0) {
		vclrflags(vp, VAGE0);
	} else if (vp->v_flag & VAGE1) {
		vclrflags(vp, VAGE1);
		vsetflags(vp, VAGE0);
	}

	ap.a_head.a_desc = &vop_open_desc;
	ap.a_head.a_ops = ops;
	ap.a_vp = vp;
	ap.a_fp = fp;
	ap.a_mode = mode;
	ap.a_cred = cred;

	VFS_MPLOCK1(vp->v_mount);
	DO_OPS(ops, error, &ap, vop_open);
	VFS_MPUNLOCK(vp->v_mount);
	return(error);
}
예제 #3
0
int
vop_mountctl_ap(struct vop_mountctl_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_mountctl);
	return(error);
}
예제 #4
0
int
vop_nlookupdotdot_ap(struct vop_nlookupdotdot_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_nlookupdotdot);
	return(error);
}
예제 #5
0
int
vop_nsymlink_ap(struct vop_nsymlink_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_nsymlink);
	return(error);
}
예제 #6
0
int
vop_nrename_ap(struct vop_nrename_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_nrename);
	return(error);
}
예제 #7
0
int
vop_kqfilter_ap(struct vop_kqfilter_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_kqfilter);
	return(error);
}
예제 #8
0
int
vop_setextattr_ap(struct vop_setextattr_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_setextattr);
	return(error);
}
예제 #9
0
int
vop_freeblks_ap(struct vop_freeblks_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_freeblks);
	return(error);
}
예제 #10
0
int
vop_aclcheck_ap(struct vop_aclcheck_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_aclcheck);
	return(error);
}
예제 #11
0
int
vop_balloc_ap(struct vop_balloc_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_balloc);
	return(error);
}
예제 #12
0
int
vop_putpages_ap(struct vop_putpages_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_putpages);
	return(error);
}
예제 #13
0
int
vop_pathconf_ap(struct vop_pathconf_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_pathconf);
	return(error);
}
예제 #14
0
int
vop_strategy_ap(struct vop_strategy_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_strategy);
	return(error);
}
예제 #15
0
int
vop_reclaim_ap(struct vop_reclaim_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_reclaim);
	return(error);
}
예제 #16
0
int
vop_nwhiteout_ap(struct vop_nwhiteout_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_nwhiteout);
	return(error);
}
예제 #17
0
int
vop_nmknod_ap(struct vop_nmknod_args *ap)
{
	int error;

	DO_OPS(ap->a_head.a_ops, error, ap, vop_nmknod);
	return(error);
}
예제 #18
0
/*
 * MPSAFE
 */
int
vop_write(struct vop_ops *ops, struct vnode *vp, struct uio *uio, int ioflag,
	struct ucred *cred)
{
	struct vop_write_args ap;
	VFS_MPLOCK_DECLARE;
	int error, do_accounting = 0;
	struct vattr va;
	uint64_t size_before=0, size_after=0;
	struct mount *mp;
	uint64_t offset, delta;

	ap.a_head.a_desc = &vop_write_desc;
	ap.a_head.a_ops = ops;
	ap.a_vp = vp;
	ap.a_uio = uio;
	ap.a_ioflag = ioflag;
	ap.a_cred = cred;

	/* is this a regular vnode ? */
	VFS_MPLOCK_FLAG(vp->v_mount, MNTK_WR_MPSAFE);
	if (vfs_quota_enabled && (vp->v_type == VREG)) {
		if ((error = VOP_GETATTR(vp, &va)) != 0)
			goto done;
		size_before = va.va_size;
		/* this file may already have been removed */
		if (va.va_nlink > 0)
			do_accounting = 1;

		offset = uio->uio_offset;
		if (ioflag & IO_APPEND)
			offset = size_before;
		size_after = offset + uio->uio_resid;
		if (size_after < size_before)
			size_after = size_before;
		delta = size_after - size_before;
		mp = vq_vptomp(vp);
		/* QUOTA CHECK */
		if (!vq_write_ok(mp, va.va_uid, va.va_gid, delta)) {
			error = EDQUOT;
			goto done;
		}
	}
	DO_OPS(ops, error, &ap, vop_write);
	if ((error == 0) && do_accounting) {
		VFS_ACCOUNT(mp, va.va_uid, va.va_gid, size_after - size_before);
	}
done:
	VFS_MPUNLOCK(vp->v_mount);
	return(error);
}
예제 #19
0
/*
 * MPSAFE
 */
int
vop_strategy(struct vop_ops *ops, struct vnode *vp, struct bio *bio)
{
	struct vop_strategy_args ap;
	VFS_MPLOCK_DECLARE;
	int error;

	ap.a_head.a_desc = &vop_strategy_desc;
	ap.a_head.a_ops = ops;
	ap.a_vp = vp;
	ap.a_bio = bio;

	if (vp->v_mount) {
		VFS_MPLOCK_FLAG(vp->v_mount, MNTK_SG_MPSAFE);
		DO_OPS(ops, error, &ap, vop_strategy);
		VFS_MPUNLOCK(vp->v_mount);
	} else {
		/* ugly hack for swap */
		get_mplock();
		DO_OPS(ops, error, &ap, vop_strategy);
		rel_mplock();
	}
	return(error);
}
예제 #20
0
/*
 * MPSAFE
 */
int
vop_print(struct vop_ops *ops, struct vnode *vp)
{
	struct vop_print_args ap;
	VFS_MPLOCK_DECLARE;
	int error;

	ap.a_head.a_desc = &vop_print_desc;
	ap.a_head.a_ops = ops;
	ap.a_vp = vp;

	VFS_MPLOCK1(vp->v_mount);
	DO_OPS(ops, error, &ap, vop_print);
	VFS_MPUNLOCK(vp->v_mount);
	return(error);
}
예제 #21
0
/*
 * MPSAFE
 */
int
vop_kqfilter(struct vop_ops *ops, struct vnode *vp, struct knote *kn)
{
	struct vop_kqfilter_args ap;
	VFS_MPLOCK_DECLARE;
	int error;

	ap.a_head.a_desc = &vop_kqfilter_desc;
	ap.a_head.a_ops = ops;
	ap.a_vp = vp;
	ap.a_kn = kn;

	VFS_MPLOCK1(vp->v_mount);
	DO_OPS(ops, error, &ap, vop_kqfilter);
	VFS_MPUNLOCK(vp->v_mount);
	return(error);
}
예제 #22
0
/*
 * MPSAFE
 */
int
vop_close(struct vop_ops *ops, struct vnode *vp, int fflag)
{
	struct vop_close_args ap;
	VFS_MPLOCK_DECLARE;
	int error;

	ap.a_head.a_desc = &vop_close_desc;
	ap.a_head.a_ops = ops;
	ap.a_vp = vp;
	ap.a_fflag = fflag;

	VFS_MPLOCK1(vp->v_mount);
	DO_OPS(ops, error, &ap, vop_close);
	VFS_MPUNLOCK(vp->v_mount);
	return(error);
}
예제 #23
0
/*
 * MPSAFE
 */
int
vop_markatime(struct vop_ops *ops, struct vnode *vp, struct ucred *cred)
{
	struct vop_markatime_args ap;
	VFS_MPLOCK_DECLARE;
	int error;

	ap.a_head.a_desc = &vop_markatime_desc;
	ap.a_head.a_ops = ops;
	ap.a_vp = vp;
	ap.a_cred = cred;

	VFS_MPLOCK1(vp->v_mount);
	DO_OPS(ops, error, &ap, vop_markatime);
	VFS_MPUNLOCK(vp->v_mount);
	return(error);
}
예제 #24
0
int
vop_old_lookup(struct vop_ops *ops, struct vnode *dvp,
	struct vnode **vpp, struct componentname *cnp)
{
	struct vop_old_lookup_args ap;
	VFS_MPLOCK_DECLARE;
	int error;

	ap.a_head.a_desc = &vop_old_lookup_desc;
	ap.a_head.a_ops = ops;
	ap.a_dvp = dvp;
	ap.a_vpp = vpp;
	ap.a_cnp = cnp;
	VFS_MPLOCK1(dvp->v_mount);
	DO_OPS(ops, error, &ap, vop_old_lookup);
	VFS_MPUNLOCK(dvp->v_mount);
	return(error);
}
예제 #25
0
/*
 * MPSAFE
 */
int
vop_fsync(struct vop_ops *ops, struct vnode *vp, int waitfor, int flags)
{
	struct vop_fsync_args ap;
	VFS_MPLOCK_DECLARE;
	int error;

	ap.a_head.a_desc = &vop_fsync_desc;
	ap.a_head.a_ops = ops;
	ap.a_vp = vp;
	ap.a_waitfor = waitfor;
	ap.a_flags = flags;

	VFS_MPLOCK1(vp->v_mount);
	DO_OPS(ops, error, &ap, vop_fsync);
	VFS_MPUNLOCK(vp->v_mount);
	return(error);
}
예제 #26
0
/*
 * MPSAFE
 */
int
vop_poll(struct vop_ops *ops, struct vnode *vp, int events, struct ucred *cred)
{
	struct vop_poll_args ap;
	VFS_MPLOCK_DECLARE;
	int error;

	ap.a_head.a_desc = &vop_poll_desc;
	ap.a_head.a_ops = ops;
	ap.a_vp = vp;
	ap.a_events = events;
	ap.a_cred = cred;

	VFS_MPLOCK1(vp->v_mount);
	DO_OPS(ops, error, &ap, vop_poll);
	VFS_MPUNLOCK(vp->v_mount);
	return(error);
}
예제 #27
0
/*
 * MPSAFE
 */
int
vop_getattr(struct vop_ops *ops, struct vnode *vp, struct vattr *vap)
{
	struct vop_getattr_args ap;
	VFS_MPLOCK_DECLARE;
	int error;

	ap.a_head.a_desc = &vop_getattr_desc;
	ap.a_head.a_ops = ops;
	ap.a_vp = vp;
	ap.a_vap = vap;

	VFS_MPLOCK_FLAG(vp->v_mount, MNTK_GA_MPSAFE);
	DO_OPS(ops, error, &ap, vop_getattr);
	VFS_MPUNLOCK(vp->v_mount);

	return(error);
}
예제 #28
0
/*
 * MPSAFE
 */
int
vop_freeblks(struct vop_ops *ops, struct vnode *vp, off_t offset, int length)
{
	struct vop_freeblks_args ap;
	VFS_MPLOCK_DECLARE;
	int error;

	ap.a_head.a_desc = &vop_freeblks_desc;
	ap.a_head.a_ops = ops;
	ap.a_vp = vp;
	ap.a_offset = offset;
	ap.a_length = length;

	VFS_MPLOCK1(vp->v_mount);
	DO_OPS(ops, error, &ap, vop_freeblks);
	VFS_MPUNLOCK(vp->v_mount);
	return(error);
}
예제 #29
0
/*
 * MPSAFE
 */
int
vop_reallocblks(struct vop_ops *ops, struct vnode *vp,
	struct cluster_save *buflist)
{
	struct vop_reallocblks_args ap;
	VFS_MPLOCK_DECLARE;
	int error;

	ap.a_head.a_desc = &vop_reallocblks_desc;
	ap.a_head.a_ops = ops;
	ap.a_vp = vp;
	ap.a_buflist = buflist;

	VFS_MPLOCK1(vp->v_mount);
	DO_OPS(ops, error, &ap, vop_reallocblks);
	VFS_MPUNLOCK(vp->v_mount);
	return(error);
}
예제 #30
0
/*
 * MPSAFE
 */
int
vop_mmap(struct vop_ops *ops, struct vnode *vp, int fflags, struct ucred *cred)
{
	struct vop_mmap_args ap;
	VFS_MPLOCK_DECLARE;
	int error;

	ap.a_head.a_desc = &vop_mmap_desc;
	ap.a_head.a_ops = ops;
	ap.a_vp = vp;
	ap.a_fflags = fflags;
	ap.a_cred = cred;

	VFS_MPLOCK(vp->v_mount);
	DO_OPS(ops, error, &ap, vop_mmap);
	VFS_MPUNLOCK(vp->v_mount);
	return(error);
}