#
# Copyright (c) 1995, 1997-1998 Apple Computer, Inc. All Rights Reserved.
# Copyright (c) 1992, 1993
#	The Regents of the University of California.  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.
# 3. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
#	This product includes software developed by the University of
#	California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
#
#	@(#)vnode_if.src	8.12 (Berkeley) 5/14/95
#

#
# Above each of the vop descriptors is a specification of the locking
# protocol used by each vop call.  The first column is the name of
# the variable, the remaining three columns are in, out and error
# respectively.  The "in" column defines the lock state on input,
# the "out" column defines the state on succesful return, and the
# "error" column defines the locking state on error exit.
#
# The locking value can take the following values:
# L: locked.
# U: unlocked/
# -: not applicable.  vnode does not yet (or no longer) exists.
# =: the same on input and output, may be either L or U.
# X: locked if not nil.
#

# If a vnode operation if likely to generate buffer cache IO
# for file data, add the word "UBC" on the line containing the
# name of the vnode operation. The word "UBC" must be the third
# word on the line, right after "{".


#
#% lookup	dvp	L ? ?
#% lookup	vpp	- L -
#
# XXX - the lookup locking protocol defies simple description and depends
#	on the flags and operation fields in the (cnp) structure.  Note
#	ebly that *vpp may equal dvp and both may be locked.
#
vop_lookup {
	IN struct vnode *dvp;
	INOUT struct vnode **vpp;
	IN struct componentname *cnp;
};

#
#% cachedlookup	dvp	L ? ?
#% cachedlookup	vpp	- L -
#
# This must be an exact copy of lookup.  See kern/vfs_cache.c for details.
#
vop_cachedlookup {
	IN struct vnode *dvp;
	INOUT struct vnode **vpp;
	IN struct componentname *cnp;
};

#
#% create	dvp	L L L
#% create	vpp	- L -
#
vop_create {
	IN WILLRELE struct vnode *dvp;
	OUT struct vnode **vpp;
	IN struct componentname *cnp;
	IN struct vattr *vap;
};

#
#% whiteout	dvp	L L L
#% whiteout	cnp	- - -
#% whiteout	flag	- - -
#
vop_whiteout {
	IN WILLRELE struct vnode *dvp;
	IN struct componentname *cnp;
	IN int flags;
};

#
#% mknod	dvp	L U U
#% mknod	vpp	- X -
#
vop_mknod {
	IN WILLRELE struct vnode *dvp;
	OUT WILLRELE struct vnode **vpp;
	IN struct componentname *cnp;
	IN struct vattr *vap;
};

#
#% mkcomplex	dvp	L U U
#% mkcomplex	vpp	- X -
#
vop_mkcomplex {
	IN WILLRELE struct vnode *dvp;
	OUT WILLRELE struct vnode **vpp;
	IN struct componentname *cnp;
	IN struct vattr *vap;
	IN u_long type;
};

#
#% open		vp	L L L
#
vop_open {
	IN struct vnode *vp;
	IN int mode;
	IN struct ucred *cred;
	IN struct proc *p;
};

#
#% close	vp	U U U
#
vop_close {
	IN struct vnode *vp;
	IN int fflag;
	IN struct ucred *cred;
	IN struct proc *p;
};

#
#% access	vp	L L L
#
vop_access {
	IN struct vnode *vp;
	IN int mode;
	IN struct ucred *cred;
	IN struct proc *p;
};

#
#% getattr	vp	= = =
#
vop_getattr {
	IN struct vnode *vp;
	IN struct vattr *vap;
	IN struct ucred *cred;
	IN struct proc *p;
};

#
#% setattr	vp	L L L
#
vop_setattr {
	IN struct vnode *vp;
	IN struct vattr *vap;
	IN struct ucred *cred;
	IN struct proc *p;
};

#
#% getattrlist	vp	= = =
#
vop_getattrlist {
	IN struct vnode *vp;
	IN struct attrlist *alist;
	INOUT struct uio *uio;
	IN struct ucred *cred;
	IN struct proc *p;
};

#
#% setattrlist	vp	L L L
#
vop_setattrlist {
	IN struct vnode *vp;
	IN struct attrlist *alist;
	INOUT struct uio *uio;
	IN struct ucred *cred;
	IN struct proc *p;
};

#
#% read		vp	L L L
#
vop_read { UBC
	IN struct vnode *vp;
	INOUT struct uio *uio;
	IN int ioflag;
	IN struct ucred *cred;
};

#
#% write	vp	L L L
#
vop_write { UBC
	IN struct vnode *vp;
	INOUT struct uio *uio;
	IN int ioflag;
	IN struct ucred *cred;
};

#
#% lease	vp	= = =
#
vop_lease {
	IN struct vnode *vp;
	IN struct proc *p;
	IN struct ucred *cred;
	IN int flag;
};

#
#% ioctl	vp	U U U
#
vop_ioctl {
	IN struct vnode *vp;
	IN u_long command;
	IN caddr_t data;
	IN int fflag;
	IN struct ucred *cred;
	IN struct proc *p;
};

#
#% select	vp	U U U
#
# Needs work?  (fflags)
#
vop_select {
	IN struct vnode *vp;
	IN int which;
	IN int fflags;
	IN struct ucred *cred;
	IN void  * wql;
	IN struct proc *p;
};

#
#% exchange fvp		L L L
#% exchange tvp		L L L
#
vop_exchange {
	IN struct vnode *fvp;
	IN struct vnode *tvp;
	IN struct ucred *cred;
	IN struct proc *p;
};

#
#% kqfilt_add   vp	L L L
#
vop_kqfilt_add {
	IN struct vnode *vp;
	IN struct knote *kn;
	IN struct proc *p;
};

#
#% kqfilt_remove	vp	L L L
#
vop_kqfilt_remove {
	IN struct vnode *vp;
	IN uintptr_t ident;
	IN struct proc *p;
};

#
#% revoke	vp	U U U
#
vop_revoke {
	IN struct vnode *vp;
	IN int flags;
};

#
# XXX - not used
#
vop_mmap {
	IN struct vnode *vp;
	IN int fflags;
	IN struct ucred *cred;
	IN struct proc *p;
};

#
#% fsync	vp	L L L
#
vop_fsync { UBC
	IN struct vnode *vp;
	IN struct ucred *cred;
	IN int waitfor;
	IN struct proc *p;
};

#
# XXX - not used
# Needs work: Is newoff right?  What's it mean?
#
vop_seek {
	IN struct vnode *vp;
	IN off_t oldoff;
	IN off_t newoff;
	IN struct ucred *cred;
};

#
#% remove	dvp	L U U
#% remove	vp	L U U
#
vop_remove {
	IN WILLRELE struct vnode *dvp;
	IN WILLRELE struct vnode *vp;
	IN struct componentname *cnp;
};

#
#% link		vp	U U U
#% link		tdvp	L U U
#
vop_link {
	IN struct vnode *vp;
	IN WILLRELE struct vnode *tdvp;
	IN struct componentname *cnp;
};

#
#% rename	fdvp	U U U
#% rename	fvp	U U U
#% rename	tdvp	L U U
#% rename	tvp	X U U
#
vop_rename {
	IN WILLRELE struct vnode *fdvp;
	IN WILLRELE struct vnode *fvp;
	IN struct componentname *fcnp;
	IN WILLRELE struct vnode *tdvp;
	IN WILLRELE struct vnode *tvp;
	IN struct componentname *tcnp;
};

#
#% mkdir	dvp	L U U
#% mkdir	vpp	- L -
#
vop_mkdir {
	IN WILLRELE struct vnode *dvp;
	OUT struct vnode **vpp;
	IN struct componentname *cnp;
	IN struct vattr *vap;
};

#
#% rmdir	dvp	L U U
#% rmdir	vp	L U U
#
vop_rmdir {
	IN WILLRELE struct vnode *dvp;
	IN WILLRELE struct vnode *vp;
	IN struct componentname *cnp;
};

#
#% symlink	dvp	L U U
#% symlink	vpp	- U -
#
# XXX - note that the return vnode has already been VRELE'ed
#	by the filesystem layer.  To use it you must use vget,
#	possibly with a further namei.
#
vop_symlink {
	IN WILLRELE struct vnode *dvp;
	OUT WILLRELE struct vnode **vpp;
	IN struct componentname *cnp;
	IN struct vattr *vap;
	IN char *target;
};

#
#% readdir	vp	L L L
#
vop_readdir {
	IN struct vnode *vp;
	INOUT struct uio *uio;
	IN struct ucred *cred;
	INOUT int *eofflag;
	OUT int *ncookies;
	INOUT u_long **cookies;
};

#
#% readdirattr	vp	L L L
#
vop_readdirattr {
	IN struct vnode *vp;
	IN struct attrlist *alist;
	INOUT struct uio *uio;
	IN u_long maxcount;
	IN u_long options;
	OUT u_long *newstate;
	OUT int *eofflag;
	OUT u_long *actualcount;
	OUT u_long **cookies;
	IN struct ucred *cred;
};

#
#% readlink	vp	L L L
#
vop_readlink {
	IN struct vnode *vp;
	INOUT struct uio *uio;
	IN struct ucred *cred;
};

#
#% abortop	dvp	= = =
#
vop_abortop {
	IN struct vnode *dvp;
	IN struct componentname *cnp;
};

#
#% inactive	vp	L U U
#
vop_inactive {
	IN struct vnode *vp;
	IN struct proc *p;
};

#
#% reclaim	vp	U U U
#
vop_reclaim {
	IN struct vnode *vp;
	IN struct proc *p;
};

#
#% lock		vp	U L U
#
vop_lock {
	IN struct vnode *vp;
	IN int flags;
	IN struct proc *p;
};

#
#% unlock	vp	L U L
#
vop_unlock {
	IN struct vnode *vp;
	IN int flags;
	IN struct proc *p;
};

#
#% bmap		vp	L L L
#% bmap		vpp	- U -
#
vop_bmap {
	IN struct vnode *vp;
	IN daddr_t bn;
	OUT struct vnode **vpp;
	IN daddr_t *bnp;
	OUT int *runp;
};

#
# Needs work: no vp?
#
#vop_strategy {
#	IN struct buf *bp;
#};

#
#% print	vp	= = =
#
vop_print {
	IN struct vnode *vp;
};

#
#% islocked	vp	= = =
#
vop_islocked {
	IN struct vnode *vp;
};

#
#% pathconf	vp	L L L
#
vop_pathconf {
	IN struct vnode *vp;
	IN int name;
	OUT register_t *retval;
};

#
#% advlock	vp	U U U
#
vop_advlock {
	IN struct vnode *vp;
	IN caddr_t id;
	IN int op;
	IN struct flock *fl;
	IN int flags;
};

#
#% blkatoff	vp	L L L
#
vop_blkatoff {
	IN struct vnode *vp;
	IN off_t offset;
	OUT char **res;
	OUT struct buf **bpp;
};

#
#% valloc	pvp	L L L
#
vop_valloc {
	IN struct vnode *pvp;
	IN int mode;
	IN struct ucred *cred;
	OUT struct vnode **vpp;
};

#
#% reallocblks	vp	L L L
#
vop_reallocblks {
	IN struct vnode *vp;
	IN struct cluster_save *buflist;
};

#
#% vfree	pvp	L L L
#
vop_vfree {
	IN struct vnode *pvp;
	IN ino_t ino;
	IN int mode;
};

#
#% truncate	vp	L L L
#
vop_truncate { UBC
	IN struct vnode *vp;
	IN off_t length;
	IN int flags;
	IN struct ucred *cred;
	IN struct proc *p;
};

#
#% allocate	vp	L L L
#
vop_allocate {
	IN struct vnode *vp;
	IN off_t length;
	IN u_int32_t flags;
	OUT off_t *bytesallocated;
	IN off_t offset;
	IN struct ucred *cred;
	IN struct proc *p;
};

#
#% update	vp	L L L
#
vop_update {
	IN struct vnode *vp;
	IN struct timeval *access;
	IN struct timeval *modify;
	IN int waitfor;
};

#
#% pgrd		vp	L L L
#
vop_pgrd {
	IN struct vnode *vp;
	INOUT struct uio *uio;
	IN struct ucred *cred;
};

#
#% pgwr		vp	L L L
#
vop_pgwr {
	IN struct vnode *vp;
	INOUT struct uio *uio;
	IN struct ucred *cred;
	IN vm_offset_t	offset;
};

#
# Needs work: no vp?
#
#vop_bwrite {
#	IN struct buf *bp;
#};

#
#% pagein	vp	= = =
#
vop_pagein {
	IN struct vnode *vp;
	IN upl_t pl;
	IN vm_offset_t pl_offset;
	IN off_t f_offset;
	IN size_t size;
	IN struct ucred *cred;
	IN int flags;
};

#
#% pageout	vp	= = =
#
vop_pageout {
	IN struct vnode *vp;
	IN upl_t pl;
	IN vm_offset_t pl_offset;
	IN off_t f_offset;
	IN size_t size;
	IN struct ucred *cred;
	IN int flags;
};

#
#% devblocksize	vp	= = =
#
vop_devblocksize {
	IN struct vnode *vp;
	OUT register_t *retval;
};

#
#% searchfs	vp	L L L
#
vop_searchfs {
	IN struct vnode *vp;
	IN void *searchparams1;
	IN void *searchparams2;
	IN struct attrlist *searchattrs;
	IN u_long maxmatches;
	IN struct timeval *timelimit;
	OUT struct attrlist *returnattrs;
	OUT u_long *nummatches;
	IN u_long scriptcode;
	IN u_long options;
	INOUT struct uio *uio;
	INOUT struct searchstate *searchstate;
};

#
#% copyfile fvp U U U
#% copyfile tdvp L U U
#% copyfile tvp X U U
#
vop_copyfile {
    IN WILLRELE struct vnode *fvp;
    IN WILLRELE struct vnode *tdvp;
    IN WILLRELE struct vnode *tvp;
    IN struct componentname *tcnp;
    IN int mode;
    IN int flags;
};

#
#% blktooff vp = = =
#
# Given a logical block number for a vnode
# return file offset
#
vop_blktooff {
	IN struct vnode *vp;
	IN daddr_t lblkno;
	OUT off_t *offset;
};

#
#% offtoblk vp = = =
#
# Given a file offset for a vnode
# return logical block number
#
vop_offtoblk {
	IN struct vnode *vp;
	IN off_t offset;
	OUT daddr_t *lblkno;
};

#
#% cmap vp L L L
#
# Given a file offset and size of IO for a vnode
# return physical block number and bytes physically
# contiguous at that physical block.
#
# An offset into the physical block may be returned [optional]
# This is needed to support 4K/1K UFS on the devices with 2K
# sector size.
vop_cmap {
	IN struct vnode *vp;
	IN off_t foffset;
	IN size_t size;
	OUT daddr_t *bpn;
	OUT size_t *run;
	OUT void *poff;
};

