xref: /csrg-svn/sys/miscfs/fdesc/fdesc_vnops.c (revision 54980)
153838Spendry /*
253838Spendry  * Copyright (c) 1992 The Regents of the University of California
353838Spendry  * Copyright (c) 1990, 1992 Jan-Simon Pendry
453838Spendry  * All rights reserved.
553838Spendry  *
653838Spendry  * This code is derived from software donated to Berkeley by
753838Spendry  * Jan-Simon Pendry.
853838Spendry  *
953838Spendry  * %sccs.include.redist.c%
1053838Spendry  *
11*54980Spendry  *	@(#)fdesc_vnops.c	1.3 (Berkeley) 07/12/92
1253838Spendry  *
1353838Spendry  * $Id: fdesc_vnops.c,v 1.7 1992/05/30 10:05:34 jsp Exp jsp $
1453838Spendry  */
1553838Spendry 
1653838Spendry /*
1753838Spendry  * /dev/fd Filesystem
1853838Spendry  */
1953838Spendry 
2053838Spendry #include <sys/param.h>
2153838Spendry #include <sys/systm.h>
2253838Spendry #include <sys/types.h>
2353838Spendry #include <sys/time.h>
2453838Spendry #include <sys/proc.h>
2553838Spendry #include <sys/resourcevar.h>
2653838Spendry #include <sys/filedesc.h>
2753838Spendry #include <sys/vnode.h>
2853838Spendry #include <sys/malloc.h>
2953838Spendry #include <sys/file.h>
3053838Spendry #include <sys/stat.h>
3153838Spendry #include <sys/mount.h>
3253838Spendry #include <sys/namei.h>
3353838Spendry #include <sys/buf.h>
3453838Spendry #include <fdesc/fdesc.h>
3553838Spendry 
3653838Spendry /*
3753838Spendry  * vp is the current namei directory
3853838Spendry  * ndp is the name to locate in that directory...
3953838Spendry  */
4053838Spendry fdesc_lookup (ap)
4153838Spendry 	struct vop_lookup_args *ap;
4253838Spendry {
4354049Spendry 	struct vnode **vpp = ap->a_vpp;
4454049Spendry 	struct vnode *dvp = ap->a_dvp;
4553838Spendry 	char *pname;
4653838Spendry 	struct proc *p;
4753838Spendry 	int nfiles;
4853838Spendry 	unsigned fd;
4953838Spendry 	int error;
5053838Spendry 	struct vnode *fvp;
5153838Spendry 
5253838Spendry #ifdef FDESC_DIAGNOSTIC
5353838Spendry 	printf("fdesc_lookup(%x)\n", ap);
5454049Spendry 	printf("fdesc_lookup(dp = %x, vpp = %x, cnp = %x)\n", dvp, vpp, ap->a_cnp);
5553838Spendry #endif
5653838Spendry 	pname = ap->a_cnp->cn_nameptr;
5753838Spendry #ifdef FDESC_DIAGNOSTIC
5853838Spendry 	printf("fdesc_lookup(%s)\n", pname);
5953838Spendry #endif
6053838Spendry 	if (ap->a_cnp->cn_namelen == 1 && *pname == '.') {
6154049Spendry 		*vpp = dvp;
6254049Spendry 		VREF(dvp);
6354049Spendry 		/*VOP_LOCK(dvp);*/
6453838Spendry 		return (0);
6553838Spendry 	}
6653838Spendry 
6753838Spendry 	p = ap->a_cnp->cn_proc;
6853838Spendry 	nfiles = p->p_fd->fd_nfiles;
6953838Spendry 
7053838Spendry 	fd = 0;
7153838Spendry 	while (*pname >= '0' && *pname <= '9') {
7253838Spendry 		fd = 10 * fd + *pname++ - '0';
7353838Spendry 		if (fd >= nfiles)
7453838Spendry 			break;
7553838Spendry 	}
7653838Spendry 
7753838Spendry #ifdef FDESC_DIAGNOSTIC
7853838Spendry 	printf("fdesc_lookup: fd = %d, *pname = %x\n", fd, *pname);
7953838Spendry #endif
8053838Spendry 	if (*pname != '\0') {
8153838Spendry 		error = ENOENT;
8253838Spendry 		goto bad;
8353838Spendry 	}
8453838Spendry 
8553838Spendry 	if (fd >= nfiles || p->p_fd->fd_ofiles[fd] == NULL) {
8653838Spendry 		error = EBADF;
8753838Spendry 		goto bad;
8853838Spendry 	}
8953838Spendry 
9053838Spendry #ifdef FDESC_DIAGNOSTIC
9153838Spendry 	printf("fdesc_lookup: allocate new vnode\n");
9253838Spendry #endif
9354049Spendry 	error = getnewvnode(VT_UFS, dvp->v_mount, fdesc_vnodeop_p, &fvp);
9453838Spendry 	if (error)
9553838Spendry 		goto bad;
9653838Spendry 	MALLOC(fvp->v_data, void *, sizeof(struct fdescnode), M_TEMP, M_WAITOK);
9753838Spendry 	VTOFDESC(fvp)->f_fd = fd;
9853838Spendry 	/*VTOFDESC(fvp)->f_isroot = 0;*/
9954049Spendry 	*vpp = fvp;
10053838Spendry #ifdef FDESC_DIAGNOSTIC
10153838Spendry 	printf("fdesc_lookup: newvp = %x\n", fvp);
10253838Spendry #endif
10353838Spendry 	return (0);
10453838Spendry 
10553838Spendry bad:;
10654049Spendry 	*vpp = NULL;
10753838Spendry #ifdef FDESC_DIAGNOSTIC
10853838Spendry 	printf("fdesc_lookup: error = %d\n", error);
10953838Spendry #endif
11053838Spendry 	return (error);
11153838Spendry }
11253838Spendry 
11353838Spendry fdesc_open (ap)
11453838Spendry 	struct vop_open_args *ap;
11553838Spendry {
11654049Spendry 	struct vnode *vp = ap->a_vp;
11754049Spendry 
11853838Spendry 	/*
11953838Spendry 	 * Can always open the root (modulo perms)
12053838Spendry 	 */
12154049Spendry 	if (vp->v_flag & VROOT)
12253838Spendry 		return (0);
12353838Spendry 
12453838Spendry 	/*
12553838Spendry 	 * XXX Kludge: set ap->a_p->p_dupfd to contain the value of the
12653838Spendry 	 * the file descriptor being sought for duplication. The error
12753838Spendry 	 * return ensures that the vnode for this device will be released
12853838Spendry 	 * by vn_open. Open will detect this special error and take the
12953838Spendry 	 * actions in dupfdopen.  Other callers of vn_open or VOP_OPEN
13053838Spendry 	 * will simply report the error.
13153838Spendry 	 */
13254049Spendry 	ap->a_p->p_dupfd = VTOFDESC(vp)->f_fd;	/* XXX */
13353838Spendry 	return (ENODEV);
13453838Spendry }
13553838Spendry 
13653838Spendry static int
13753838Spendry fdesc_attr(fd, vap, cred, p)
13853838Spendry 	int fd;
13953838Spendry 	struct vattr *vap;
14053838Spendry 	struct ucred *cred;
14153838Spendry 	struct proc *p;
14253838Spendry {
14353838Spendry 	struct filedesc *fdp = p->p_fd;
14453838Spendry 	struct file *fp;
14553838Spendry 	int error;
14653838Spendry 
14753838Spendry #ifdef FDESC_DIAGNOSTIC
14853838Spendry 	printf("fdesc_attr: fd = %d, nfiles = %d\n", fd, fdp->fd_nfiles);
14953838Spendry #endif
15053838Spendry 	if (fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL) {
15153838Spendry #ifdef FDESC_DIAGNOSTIC
15253838Spendry 		printf("fdesc_attr: fp = %x (EBADF)\n", fp);
15353838Spendry #endif
15453838Spendry 		return (EBADF);
15553838Spendry 	}
15653838Spendry 
15753838Spendry 	/*
15853838Spendry 	 * Can stat the underlying vnode, but not sockets because
15953838Spendry 	 * they don't use struct vattrs.  Well, we could convert from
16053838Spendry 	 * a struct stat back to a struct vattr, later...
16153838Spendry 	 */
16253838Spendry 	switch (fp->f_type) {
16353838Spendry 	case DTYPE_VNODE:
16453838Spendry 		error = VOP_GETATTR((struct vnode *) fp->f_data, vap, cred, p);
16553838Spendry 		break;
16653838Spendry 
16753838Spendry 	case DTYPE_SOCKET:
16853838Spendry 		error = EOPNOTSUPP;
16953838Spendry 		break;
17053838Spendry 
17153838Spendry 	default:
17253838Spendry 		panic("fdesc attr");
17353838Spendry 		break;
17453838Spendry 	}
17553838Spendry 
17653838Spendry #ifdef FDESC_DIAGNOSTIC
17753838Spendry 	printf("fdesc_attr: returns error %d\n", error);
17853838Spendry #endif
17953838Spendry 	return (error);
18053838Spendry }
18153838Spendry 
18253838Spendry fdesc_getattr (ap)
18353838Spendry 	struct vop_getattr_args *ap;
18453838Spendry {
18554049Spendry 	struct vnode *vp = ap->a_vp;
18654049Spendry 	struct vattr *vap = ap->a_vap;
18753838Spendry 	unsigned fd;
18853838Spendry 	int error;
18953838Spendry 
19054049Spendry 	if (vp->v_flag & VROOT) {
19153838Spendry #ifdef FDESC_DIAGNOSTIC
19253838Spendry 		printf("fdesc_getattr: stat rootdir\n");
19353838Spendry #endif
19454049Spendry 		bzero((caddr_t) vap, sizeof(*vap));
19554049Spendry 		vattr_null(vap);
19654049Spendry 		vap->va_type = VDIR;
19754049Spendry 		vap->va_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
19854049Spendry 		vap->va_nlink = 2;
19954049Spendry 		vap->va_uid = 0;
20054049Spendry 		vap->va_gid = 0;
20154049Spendry 		vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
20254049Spendry 		vap->va_fileid = 2;
20354049Spendry 		/* vap->va_qsize = 0; */
20454049Spendry 		vap->va_size = DEV_BSIZE;
20554049Spendry 		vap->va_blocksize = DEV_BSIZE;
20654049Spendry 		microtime(&vap->va_atime);
20754049Spendry 		vap->va_mtime = vap->va_atime;
20854049Spendry 		vap->va_ctime = vap->va_ctime;
20954049Spendry 		vap->va_gen = 0;
21054049Spendry 		vap->va_flags = 0;
21154049Spendry 		vap->va_rdev = 0;
21254049Spendry 		/* vap->va_qbytes = 0; */
21354049Spendry 		vap->va_bytes = 0;
21453838Spendry 		return (0);
21553838Spendry 	}
21653838Spendry 
21754049Spendry 	fd = VTOFDESC(vp)->f_fd;
21854049Spendry 	error = fdesc_attr(fd, vap, ap->a_cred, ap->a_p);
21953838Spendry 	if (error == 0)
22054049Spendry 		vp->v_type = vap->va_type;
22153838Spendry 	return (error);
22253838Spendry }
22353838Spendry 
22453838Spendry fdesc_setattr (ap)
22553838Spendry 	struct vop_setattr_args *ap;
22653838Spendry {
22753838Spendry 	struct filedesc *fdp = ap->a_p->p_fd;
22853838Spendry 	struct file *fp;
22953838Spendry 	unsigned fd;
23053838Spendry 	int error;
23153838Spendry 
23253838Spendry 	/*
23353838Spendry 	 * Can't mess with the root vnode
23453838Spendry 	 */
23553838Spendry 	if (ap->a_vp->v_flag & VROOT)
23653838Spendry 		return (EACCES);
23753838Spendry 
23853838Spendry 	fd = VTOFDESC(ap->a_vp)->f_fd;
23953838Spendry #ifdef FDESC_DIAGNOSTIC
24053838Spendry 	printf("fdesc_setattr: fd = %d, nfiles = %d\n", fd, fdp->fd_nfiles);
24153838Spendry #endif
24253838Spendry 	if (fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL) {
24353838Spendry #ifdef FDESC_DIAGNOSTIC
24453838Spendry 		printf("fdesc_setattr: fp = %x (EBADF)\n", fp);
24553838Spendry #endif
24653838Spendry 		return (EBADF);
24753838Spendry 	}
24853838Spendry 
24953838Spendry 	/*
25053838Spendry 	 * Can setattr the underlying vnode, but not sockets!
25153838Spendry 	 */
25253838Spendry 	switch (fp->f_type) {
25353838Spendry 	case DTYPE_VNODE:
25453838Spendry 		error = VOP_SETATTR((struct vnode *) fp->f_data, ap->a_vap, ap->a_cred, ap->a_p);
25553838Spendry 		break;
25653838Spendry 
25753838Spendry 	case DTYPE_SOCKET:
25853838Spendry 		error = EOPNOTSUPP;
25953838Spendry 		break;
26053838Spendry 
26153838Spendry 	default:
26253838Spendry 		panic("fdesc setattr");
26353838Spendry 		break;
26453838Spendry 	}
26553838Spendry 
26653838Spendry #ifdef FDESC_DIAGNOSTIC
26753838Spendry 	printf("fdesc_setattr: returns error %d\n", error);
26853838Spendry #endif
26953838Spendry 	return (error);
27053838Spendry }
27153838Spendry 
27253838Spendry fdesc_readdir (ap)
27353838Spendry 	struct vop_readdir_args *ap;
27453838Spendry {
27554049Spendry 	struct uio *uio = ap->a_uio;
27653838Spendry 	struct filedesc *fdp;
27753838Spendry 	int i;
27853838Spendry 	int error;
27953838Spendry 
28053838Spendry #define UIO_MX 16
28153838Spendry 
28254049Spendry 	fdp = uio->uio_procp->p_fd;
28354049Spendry 	i = uio->uio_offset / UIO_MX;
28453838Spendry 	error = 0;
28554049Spendry 	while (uio->uio_resid > 0) {
28653838Spendry 		if (i >= fdp->fd_nfiles) {
287*54980Spendry 			/* *ap->a_eofflagp = 1; */
28853838Spendry 			break;
28953838Spendry 		}
29053838Spendry 		if (fdp->fd_ofiles[i] != NULL) {
29153838Spendry 			struct readdir d;
29253838Spendry 			struct readdir *dp = &d;
29353838Spendry 			char *cp = dp->d_name;
29453838Spendry #ifdef FDESC_FILEID
29553838Spendry 			struct vattr va;
29653838Spendry #endif
29753838Spendry 			bzero((caddr_t) dp, UIO_MX);
29853838Spendry 
29953838Spendry 			dp->d_namlen = sprintf(dp->d_name, "%d", i);
30053838Spendry 			/*
30153838Spendry 			 * Fill in the remaining fields
30253838Spendry 			 */
30353838Spendry 			dp->d_reclen = UIO_MX;
30453838Spendry 			dp->d_ino = i + 3;
30553838Spendry #ifdef FDESC_FILEID
30653838Spendry 			/*
30753838Spendry 			 * If we want the file ids to match the
30853838Spendry 			 * we must call getattr on the underlying file.
30953838Spendry 			 * fdesc_attr may return an error, in which case
31053838Spendry 			 * we ignore the returned file id.
31153838Spendry 			 */
31253838Spendry 			error = fdesc_attr(i, &va, ap->a_cred, p);
31353838Spendry 			if (error == 0)
31453838Spendry 				dp->d_ino = va.va_fileid;
31553838Spendry #endif
31653838Spendry 			/*
31753838Spendry 			 * And ship to userland
31853838Spendry 			 */
31954049Spendry 			error = uiomove((caddr_t) dp, UIO_MX, uio);
32053838Spendry 			if (error)
32153838Spendry 				break;
32253838Spendry 		}
32353838Spendry 		i++;
32453838Spendry 	}
32553838Spendry 
32654049Spendry 	uio->uio_offset = i * UIO_MX;
32753838Spendry 	return (error);
32853838Spendry }
32953838Spendry 
33053838Spendry fdesc_inactive (ap)
33153838Spendry 	struct vop_inactive_args *ap;
33253838Spendry {
33354049Spendry 	struct vnode *vp = ap->a_vp;
33454049Spendry 
33553838Spendry 	/*
33653838Spendry 	 * Clear out the v_type field to avoid
33753838Spendry 	 * nasty things happening in vgone().
33853838Spendry 	 */
33954049Spendry 	vp->v_type = VNON;
34053838Spendry #ifdef FDESC_DIAGNOSTIC
34154049Spendry 	printf("fdesc_inactive(%x)\n", vp);
34253838Spendry #endif
34353838Spendry 	return (0);
34453838Spendry }
34553838Spendry 
34653838Spendry fdesc_reclaim (ap)
34753838Spendry 	struct  vop_reclaim_args *ap;
34853838Spendry {
34953838Spendry 	struct vnode *vp = ap->a_vp;
35053838Spendry 	printf("fdesc_reclaim(%x)\n", vp);
35153838Spendry 	if (vp->v_data) {
35253838Spendry 		FREE(vp->v_data, M_TEMP);
35353838Spendry 		vp->v_data = 0;
35453838Spendry 	}
35553838Spendry 	return (0);
35653838Spendry }
35753838Spendry 
35853838Spendry /*
35953838Spendry  * Print out the contents of a /dev/fd vnode.
36053838Spendry  */
36153838Spendry /* ARGSUSED */
36253838Spendry fdesc_print (ap)
36353838Spendry 	struct vop_print_args *ap;
36453838Spendry {
36553838Spendry 	printf("tag VT_NON, fdesc vnode\n");
36653838Spendry }
36753838Spendry 
36853838Spendry /*void*/
36953838Spendry fdesc_vfree (ap)
37053838Spendry 	struct vop_vfree_args *ap;
37153838Spendry {
37253838Spendry 
37353838Spendry 	return;
37453838Spendry }
37553838Spendry 
37653838Spendry /*
37753838Spendry  * /dev/fd vnode unsupported operation
37853838Spendry  */
37953838Spendry fdesc_enotsupp()
38053838Spendry {
38153838Spendry 	return (EOPNOTSUPP);
38253838Spendry }
38353838Spendry 
38453838Spendry /*
38553838Spendry  * /dev/fd "should never get here" operation
38653838Spendry  */
38753838Spendry fdesc_badop()
38853838Spendry {
38953838Spendry 	panic("fdesc: bad op");
39053838Spendry 	/* NOTREACHED */
39153838Spendry }
39253838Spendry 
39353838Spendry /*
39453838Spendry  * /dev/fd vnode null operation
39553838Spendry  */
39653838Spendry fdesc_nullop()
39753838Spendry {
39853838Spendry 	return (0);
39953838Spendry }
40053838Spendry 
40153838Spendry #define fdesc_create ((int (*) __P((struct  vop_create_args *)))fdesc_enotsupp)
40253838Spendry #define fdesc_mknod ((int (*) __P((struct  vop_mknod_args *)))fdesc_enotsupp)
40353838Spendry #define fdesc_close ((int (*) __P((struct  vop_close_args *)))nullop)
40453838Spendry #define fdesc_access ((int (*) __P((struct  vop_access_args *)))nullop)
40553838Spendry #define fdesc_read ((int (*) __P((struct  vop_read_args *)))fdesc_enotsupp)
40653838Spendry #define fdesc_write ((int (*) __P((struct  vop_write_args *)))fdesc_enotsupp)
40753838Spendry #define fdesc_ioctl ((int (*) __P((struct  vop_ioctl_args *)))fdesc_enotsupp)
40853838Spendry #define fdesc_select ((int (*) __P((struct  vop_select_args *)))fdesc_enotsupp)
40953838Spendry #define fdesc_mmap ((int (*) __P((struct  vop_mmap_args *)))fdesc_enotsupp)
41053838Spendry #define fdesc_fsync ((int (*) __P((struct  vop_fsync_args *)))nullop)
41153838Spendry #define fdesc_seek ((int (*) __P((struct  vop_seek_args *)))nullop)
41253838Spendry #define fdesc_remove ((int (*) __P((struct  vop_remove_args *)))fdesc_enotsupp)
41353838Spendry #define fdesc_link ((int (*) __P((struct  vop_link_args *)))fdesc_enotsupp)
41453838Spendry #define fdesc_rename ((int (*) __P((struct  vop_rename_args *)))fdesc_enotsupp)
41553838Spendry #define fdesc_mkdir ((int (*) __P((struct  vop_mkdir_args *)))fdesc_enotsupp)
41653838Spendry #define fdesc_rmdir ((int (*) __P((struct  vop_rmdir_args *)))fdesc_enotsupp)
41753838Spendry #define fdesc_symlink ((int (*) __P((struct  vop_symlink_args *)))fdesc_enotsupp)
41853838Spendry #define fdesc_readlink ((int (*) __P((struct  vop_readlink_args *)))fdesc_enotsupp)
41953838Spendry #define fdesc_abortop ((int (*) __P((struct  vop_abortop_args *)))nullop)
42053838Spendry #define fdesc_lock ((int (*) __P((struct  vop_lock_args *)))nullop)
42153838Spendry #define fdesc_unlock ((int (*) __P((struct  vop_unlock_args *)))nullop)
42253838Spendry #define fdesc_bmap ((int (*) __P((struct  vop_bmap_args *)))fdesc_badop)
42353838Spendry #define fdesc_strategy ((int (*) __P((struct  vop_strategy_args *)))fdesc_badop)
42453838Spendry #define fdesc_islocked ((int (*) __P((struct  vop_islocked_args *)))nullop)
42553838Spendry #define fdesc_advlock ((int (*) __P((struct  vop_advlock_args *)))fdesc_enotsupp)
42653838Spendry #define fdesc_blkatoff ((int (*) __P((struct  vop_blkatoff_args *)))fdesc_enotsupp)
42753838Spendry #define fdesc_vget ((int (*) __P((struct  vop_vget_args *)))fdesc_enotsupp)
42853838Spendry #define fdesc_valloc ((int(*) __P(( \
42953838Spendry 		struct vnode *pvp, \
43053838Spendry 		int mode, \
43153838Spendry 		struct ucred *cred, \
43253838Spendry 		struct vnode **vpp))) fdesc_enotsupp)
43353838Spendry #define fdesc_truncate ((int (*) __P((struct  vop_truncate_args *)))fdesc_enotsupp)
43453838Spendry #define fdesc_update ((int (*) __P((struct  vop_update_args *)))fdesc_enotsupp)
43553838Spendry #define fdesc_bwrite ((int (*) __P((struct  vop_bwrite_args *)))fdesc_enotsupp)
43653838Spendry 
43753838Spendry int (**fdesc_vnodeop_p)();
43853838Spendry struct vnodeopv_entry_desc fdesc_vnodeop_entries[] = {
43953838Spendry 	{ &vop_default_desc, vn_default_error },
44053838Spendry 	{ &vop_lookup_desc, fdesc_lookup },	/* lookup */
44153838Spendry 	{ &vop_create_desc, fdesc_create },	/* create */
44253838Spendry 	{ &vop_mknod_desc, fdesc_mknod },	/* mknod */
44353838Spendry 	{ &vop_open_desc, fdesc_open },	/* open */
44453838Spendry 	{ &vop_close_desc, fdesc_close },	/* close */
44553838Spendry 	{ &vop_access_desc, fdesc_access },	/* access */
44653838Spendry 	{ &vop_getattr_desc, fdesc_getattr },	/* getattr */
44753838Spendry 	{ &vop_setattr_desc, fdesc_setattr },	/* setattr */
44853838Spendry 	{ &vop_read_desc, fdesc_read },	/* read */
44953838Spendry 	{ &vop_write_desc, fdesc_write },	/* write */
45053838Spendry 	{ &vop_ioctl_desc, fdesc_ioctl },	/* ioctl */
45153838Spendry 	{ &vop_select_desc, fdesc_select },	/* select */
45253838Spendry 	{ &vop_mmap_desc, fdesc_mmap },	/* mmap */
45353838Spendry 	{ &vop_fsync_desc, fdesc_fsync },	/* fsync */
45453838Spendry 	{ &vop_seek_desc, fdesc_seek },	/* seek */
45553838Spendry 	{ &vop_remove_desc, fdesc_remove },	/* remove */
45653838Spendry 	{ &vop_link_desc, fdesc_link },	/* link */
45753838Spendry 	{ &vop_rename_desc, fdesc_rename },	/* rename */
45853838Spendry 	{ &vop_mkdir_desc, fdesc_mkdir },	/* mkdir */
45953838Spendry 	{ &vop_rmdir_desc, fdesc_rmdir },	/* rmdir */
46053838Spendry 	{ &vop_symlink_desc, fdesc_symlink },	/* symlink */
46153838Spendry 	{ &vop_readdir_desc, fdesc_readdir },	/* readdir */
46253838Spendry 	{ &vop_readlink_desc, fdesc_readlink },	/* readlink */
46353838Spendry 	{ &vop_abortop_desc, fdesc_abortop },	/* abortop */
46453838Spendry 	{ &vop_inactive_desc, fdesc_inactive },	/* inactive */
46553838Spendry 	{ &vop_reclaim_desc, fdesc_reclaim },	/* reclaim */
46653838Spendry 	{ &vop_lock_desc, fdesc_lock },	/* lock */
46753838Spendry 	{ &vop_unlock_desc, fdesc_unlock },	/* unlock */
46853838Spendry 	{ &vop_bmap_desc, fdesc_bmap },	/* bmap */
46953838Spendry 	{ &vop_strategy_desc, fdesc_strategy },	/* strategy */
47053838Spendry 	{ &vop_print_desc, fdesc_print },	/* print */
47153838Spendry 	{ &vop_islocked_desc, fdesc_islocked },	/* islocked */
47253838Spendry 	{ &vop_advlock_desc, fdesc_advlock },	/* advlock */
47353838Spendry 	{ &vop_blkatoff_desc, fdesc_blkatoff },	/* blkatoff */
47453838Spendry 	{ &vop_valloc_desc, fdesc_valloc },	/* valloc */
47553838Spendry 	{ &vop_vfree_desc, fdesc_vfree },	/* vfree */
47653838Spendry 	{ &vop_truncate_desc, fdesc_truncate },	/* truncate */
47753838Spendry 	{ &vop_update_desc, fdesc_update },	/* update */
47853838Spendry 	{ &vop_bwrite_desc, fdesc_bwrite },	/* bwrite */
47953838Spendry 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
48053838Spendry };
48153838Spendry struct vnodeopv_desc fdesc_vnodeop_opv_desc =
48253838Spendry 	{ &fdesc_vnodeop_p, fdesc_vnodeop_entries };
483