xref: /csrg-svn/sys/miscfs/deadfs/dead_vnops.c (revision 40188)
139483Smckusick /*
239483Smckusick  * Copyright (c) 1989 The Regents of the University of California.
339483Smckusick  * All rights reserved.
439483Smckusick  *
539483Smckusick  * Redistribution and use in source and binary forms are permitted
639483Smckusick  * provided that the above copyright notice and this paragraph are
739483Smckusick  * duplicated in all such forms and that any documentation,
839483Smckusick  * advertising materials, and other materials related to such
939483Smckusick  * distribution and use acknowledge that the software was developed
1039483Smckusick  * by the University of California, Berkeley.  The name of the
1139483Smckusick  * University may not be used to endorse or promote products derived
1239483Smckusick  * from this software without specific prior written permission.
1339483Smckusick  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1439483Smckusick  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1539483Smckusick  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1639483Smckusick  *
17*40188Smckusick  *	@(#)dead_vnops.c	7.9 (Berkeley) 02/21/90
1839483Smckusick  */
1939483Smckusick 
2039483Smckusick #include "param.h"
2139483Smckusick #include "time.h"
2239483Smckusick #include "vnode.h"
2339483Smckusick #include "errno.h"
2439483Smckusick #include "namei.h"
2539483Smckusick #include "buf.h"
2639483Smckusick 
2739483Smckusick int	dead_lookup(),
2839483Smckusick 	dead_open(),
2939483Smckusick 	dead_read(),
3039483Smckusick 	dead_write(),
3139483Smckusick 	dead_strategy(),
3239483Smckusick 	dead_ioctl(),
3339483Smckusick 	dead_select(),
3439483Smckusick 	dead_lock(),
3539508Smckusick 	dead_bmap(),
3639911Smckusick 	dead_print(),
3739486Smckusick 	dead_ebadf(),
3839483Smckusick 	dead_badop(),
3939483Smckusick 	dead_nullop();
4039483Smckusick 
4139483Smckusick struct vnodeops dead_vnodeops = {
4239483Smckusick 	dead_lookup,	/* lookup */
4339483Smckusick 	dead_badop,	/* create */
4439483Smckusick 	dead_badop,	/* mknod */
4539483Smckusick 	dead_open,	/* open */
4639483Smckusick 	dead_nullop,	/* close */
4739486Smckusick 	dead_ebadf,	/* access */
4839486Smckusick 	dead_ebadf,	/* getattr */
4939486Smckusick 	dead_ebadf,	/* setattr */
5039483Smckusick 	dead_read,	/* read */
5139483Smckusick 	dead_write,	/* write */
5239483Smckusick 	dead_ioctl,	/* ioctl */
5339483Smckusick 	dead_select,	/* select */
5439483Smckusick 	dead_badop,	/* mmap */
5539483Smckusick 	dead_nullop,	/* fsync */
5639483Smckusick 	dead_nullop,	/* seek */
5739483Smckusick 	dead_badop,	/* remove */
5839483Smckusick 	dead_badop,	/* link */
5939483Smckusick 	dead_badop,	/* rename */
6039483Smckusick 	dead_badop,	/* mkdir */
6139483Smckusick 	dead_badop,	/* rmdir */
6239483Smckusick 	dead_badop,	/* symlink */
6339486Smckusick 	dead_ebadf,	/* readdir */
6439486Smckusick 	dead_ebadf,	/* readlink */
6539483Smckusick 	dead_badop,	/* abortop */
6639483Smckusick 	dead_nullop,	/* inactive */
6739483Smckusick 	dead_nullop,	/* reclaim */
6839483Smckusick 	dead_lock,	/* lock */
6939483Smckusick 	dead_nullop,	/* unlock */
7039508Smckusick 	dead_bmap,	/* bmap */
7139483Smckusick 	dead_strategy,	/* strategy */
7239911Smckusick 	dead_print,	/* print */
7339911Smckusick 	dead_nullop,	/* islocked */
7439483Smckusick };
7539483Smckusick 
7639483Smckusick /*
7739483Smckusick  * Trivial lookup routine that always fails.
7839483Smckusick  */
7939483Smckusick dead_lookup(vp, ndp)
8039483Smckusick 	struct vnode *vp;
8139483Smckusick 	struct nameidata *ndp;
8239483Smckusick {
8339483Smckusick 
8439483Smckusick 	ndp->ni_dvp = vp;
8539483Smckusick 	ndp->ni_vp = NULL;
8639483Smckusick 	return (ENOTDIR);
8739483Smckusick }
8839483Smckusick 
8939483Smckusick /*
9039483Smckusick  * Open always fails as if device did not exist.
9139483Smckusick  */
9239483Smckusick /* ARGSUSED */
9339483Smckusick dead_open(vp, mode, cred)
9439483Smckusick 	struct vnode *vp;
9539483Smckusick 	int mode;
9639483Smckusick 	struct ucred *cred;
9739483Smckusick {
9839483Smckusick 
9939483Smckusick 	return (ENXIO);
10039483Smckusick }
10139483Smckusick 
10239483Smckusick /*
10339483Smckusick  * Vnode op for read
10439483Smckusick  */
10539591Smckusick /* ARGSUSED */
10639591Smckusick dead_read(vp, uio, ioflag, cred)
10739483Smckusick 	struct vnode *vp;
10839483Smckusick 	struct uio *uio;
10939483Smckusick 	int ioflag;
11039483Smckusick 	struct ucred *cred;
11139483Smckusick {
11239483Smckusick 
11339591Smckusick 	if (chkvnlock(vp))
11439591Smckusick 		panic("dead_read: lock");
11539591Smckusick 	/*
11639591Smckusick 	 * Return EOF for character devices, EIO for others
11739591Smckusick 	 */
11839591Smckusick 	if (vp->v_type != VCHR)
11939483Smckusick 		return (EIO);
12039591Smckusick 	return (0);
12139483Smckusick }
12239483Smckusick 
12339483Smckusick /*
12439483Smckusick  * Vnode op for write
12539483Smckusick  */
12639591Smckusick /* ARGSUSED */
12739591Smckusick dead_write(vp, uio, ioflag, cred)
12839483Smckusick 	register struct vnode *vp;
12939483Smckusick 	struct uio *uio;
13039483Smckusick 	int ioflag;
13139483Smckusick 	struct ucred *cred;
13239483Smckusick {
13339483Smckusick 
13439591Smckusick 	if (chkvnlock(vp))
13539591Smckusick 		panic("dead_write: lock");
13639591Smckusick 	return (EIO);
13739483Smckusick }
13839483Smckusick 
13939483Smckusick /*
14039483Smckusick  * Device ioctl operation.
14139483Smckusick  */
14239483Smckusick /* ARGSUSED */
14339483Smckusick dead_ioctl(vp, com, data, fflag, cred)
14439483Smckusick 	struct vnode *vp;
14539483Smckusick 	register int com;
14639483Smckusick 	caddr_t data;
14739483Smckusick 	int fflag;
14839483Smckusick 	struct ucred *cred;
14939483Smckusick {
15039483Smckusick 
15139519Smckusick 	if (!chkvnlock(vp))
15239483Smckusick 		return (EBADF);
15339483Smckusick 	return (VOP_IOCTL(vp, com, data, fflag, cred));
15439483Smckusick }
15539483Smckusick 
15639483Smckusick /* ARGSUSED */
157*40188Smckusick dead_select(vp, which, fflags, cred)
15839483Smckusick 	struct vnode *vp;
159*40188Smckusick 	int which, fflags;
16039483Smckusick 	struct ucred *cred;
16139483Smckusick {
16239483Smckusick 
16339483Smckusick 	/*
16439483Smckusick 	 * Let the user find out that the descriptor is gone.
16539483Smckusick 	 */
16639483Smckusick 	return (1);
16739483Smckusick }
16839483Smckusick 
16939483Smckusick /*
17039483Smckusick  * Just call the device strategy routine
17139483Smckusick  */
17239483Smckusick dead_strategy(bp)
17339483Smckusick 	register struct buf *bp;
17439483Smckusick {
17539483Smckusick 
17639519Smckusick 	if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) {
17739518Smckusick 		bp->b_flags |= B_ERROR;
17839853Smckusick 		biodone(bp);
17939483Smckusick 		return (EIO);
18039518Smckusick 	}
18139483Smckusick 	return (VOP_STRATEGY(bp));
18239483Smckusick }
18339483Smckusick 
18439483Smckusick /*
18539483Smckusick  * Wait until the vnode has finished changing state.
18639483Smckusick  */
18739483Smckusick dead_lock(vp)
18839483Smckusick 	struct vnode *vp;
18939483Smckusick {
19039483Smckusick 
19139519Smckusick 	if (!chkvnlock(vp))
19239483Smckusick 		return (0);
19339483Smckusick 	return (VOP_LOCK(vp));
19439483Smckusick }
19539483Smckusick 
19639483Smckusick /*
19739508Smckusick  * Wait until the vnode has finished changing state.
19839508Smckusick  */
19939508Smckusick dead_bmap(vp, bn, vpp, bnp)
20039508Smckusick 	struct vnode *vp;
20139508Smckusick 	daddr_t bn;
20239508Smckusick 	struct vnode **vpp;
20339508Smckusick 	daddr_t *bnp;
20439508Smckusick {
20539508Smckusick 
20639519Smckusick 	if (!chkvnlock(vp))
20739508Smckusick 		return (EIO);
20839508Smckusick 	return (VOP_BMAP(vp, bn, vpp, bnp));
20939508Smckusick }
21039508Smckusick 
21139508Smckusick /*
21239911Smckusick  * Print out the contents of a dead vnode.
21339911Smckusick  */
21439911Smckusick dead_print(vp)
21539911Smckusick 	struct vnode *vp;
21639911Smckusick {
21739911Smckusick 
21839911Smckusick 	printf("tag VT_NON, dead vnode\n");
21939911Smckusick }
22039911Smckusick 
22139911Smckusick /*
22239486Smckusick  * Empty vnode failed operation
22339486Smckusick  */
22439486Smckusick dead_ebadf()
22539486Smckusick {
22639486Smckusick 
22739486Smckusick 	return (EBADF);
22839486Smckusick }
22939486Smckusick 
23039486Smckusick /*
23139483Smckusick  * Empty vnode bad operation
23239483Smckusick  */
23339483Smckusick dead_badop()
23439483Smckusick {
23539483Smckusick 
23639483Smckusick 	panic("dead_badop called");
23739483Smckusick 	/* NOTREACHED */
23839483Smckusick }
23939483Smckusick 
24039483Smckusick /*
24139483Smckusick  * Empty vnode null operation
24239483Smckusick  */
24339483Smckusick dead_nullop()
24439483Smckusick {
24539483Smckusick 
24639483Smckusick 	return (0);
24739483Smckusick }
24839519Smckusick 
24939519Smckusick /*
25039519Smckusick  * We have to wait during times when the vnode is
25139519Smckusick  * in a state of change.
25239519Smckusick  */
25339519Smckusick chkvnlock(vp)
25439519Smckusick 	register struct vnode *vp;
25539519Smckusick {
25639519Smckusick 	int locked = 0;
25739519Smckusick 
25839519Smckusick 	while (vp->v_flag & VXLOCK) {
25939519Smckusick 		vp->v_flag |= VXWANT;
26039519Smckusick 		sleep((caddr_t)vp, PINOD);
26139519Smckusick 		locked = 1;
26239519Smckusick 	}
26339519Smckusick 	return (locked);
26439519Smckusick }
265