xref: /csrg-svn/sys/miscfs/deadfs/dead_vnops.c (revision 44429)
139483Smckusick /*
239483Smckusick  * Copyright (c) 1989 The Regents of the University of California.
339483Smckusick  * All rights reserved.
439483Smckusick  *
5*44429Sbostic  * %sccs.include.redist.c%
639483Smckusick  *
7*44429Sbostic  *	@(#)dead_vnops.c	7.10 (Berkeley) 06/28/90
839483Smckusick  */
939483Smckusick 
1039483Smckusick #include "param.h"
1139483Smckusick #include "time.h"
1239483Smckusick #include "vnode.h"
1339483Smckusick #include "errno.h"
1439483Smckusick #include "namei.h"
1539483Smckusick #include "buf.h"
1639483Smckusick 
1739483Smckusick int	dead_lookup(),
1839483Smckusick 	dead_open(),
1939483Smckusick 	dead_read(),
2039483Smckusick 	dead_write(),
2139483Smckusick 	dead_strategy(),
2239483Smckusick 	dead_ioctl(),
2339483Smckusick 	dead_select(),
2439483Smckusick 	dead_lock(),
2539508Smckusick 	dead_bmap(),
2639911Smckusick 	dead_print(),
2739486Smckusick 	dead_ebadf(),
2839483Smckusick 	dead_badop(),
2939483Smckusick 	dead_nullop();
3039483Smckusick 
3139483Smckusick struct vnodeops dead_vnodeops = {
3239483Smckusick 	dead_lookup,	/* lookup */
3339483Smckusick 	dead_badop,	/* create */
3439483Smckusick 	dead_badop,	/* mknod */
3539483Smckusick 	dead_open,	/* open */
3639483Smckusick 	dead_nullop,	/* close */
3739486Smckusick 	dead_ebadf,	/* access */
3839486Smckusick 	dead_ebadf,	/* getattr */
3939486Smckusick 	dead_ebadf,	/* setattr */
4039483Smckusick 	dead_read,	/* read */
4139483Smckusick 	dead_write,	/* write */
4239483Smckusick 	dead_ioctl,	/* ioctl */
4339483Smckusick 	dead_select,	/* select */
4439483Smckusick 	dead_badop,	/* mmap */
4539483Smckusick 	dead_nullop,	/* fsync */
4639483Smckusick 	dead_nullop,	/* seek */
4739483Smckusick 	dead_badop,	/* remove */
4839483Smckusick 	dead_badop,	/* link */
4939483Smckusick 	dead_badop,	/* rename */
5039483Smckusick 	dead_badop,	/* mkdir */
5139483Smckusick 	dead_badop,	/* rmdir */
5239483Smckusick 	dead_badop,	/* symlink */
5339486Smckusick 	dead_ebadf,	/* readdir */
5439486Smckusick 	dead_ebadf,	/* readlink */
5539483Smckusick 	dead_badop,	/* abortop */
5639483Smckusick 	dead_nullop,	/* inactive */
5739483Smckusick 	dead_nullop,	/* reclaim */
5839483Smckusick 	dead_lock,	/* lock */
5939483Smckusick 	dead_nullop,	/* unlock */
6039508Smckusick 	dead_bmap,	/* bmap */
6139483Smckusick 	dead_strategy,	/* strategy */
6239911Smckusick 	dead_print,	/* print */
6339911Smckusick 	dead_nullop,	/* islocked */
6439483Smckusick };
6539483Smckusick 
6639483Smckusick /*
6739483Smckusick  * Trivial lookup routine that always fails.
6839483Smckusick  */
6939483Smckusick dead_lookup(vp, ndp)
7039483Smckusick 	struct vnode *vp;
7139483Smckusick 	struct nameidata *ndp;
7239483Smckusick {
7339483Smckusick 
7439483Smckusick 	ndp->ni_dvp = vp;
7539483Smckusick 	ndp->ni_vp = NULL;
7639483Smckusick 	return (ENOTDIR);
7739483Smckusick }
7839483Smckusick 
7939483Smckusick /*
8039483Smckusick  * Open always fails as if device did not exist.
8139483Smckusick  */
8239483Smckusick /* ARGSUSED */
8339483Smckusick dead_open(vp, mode, cred)
8439483Smckusick 	struct vnode *vp;
8539483Smckusick 	int mode;
8639483Smckusick 	struct ucred *cred;
8739483Smckusick {
8839483Smckusick 
8939483Smckusick 	return (ENXIO);
9039483Smckusick }
9139483Smckusick 
9239483Smckusick /*
9339483Smckusick  * Vnode op for read
9439483Smckusick  */
9539591Smckusick /* ARGSUSED */
9639591Smckusick dead_read(vp, uio, ioflag, cred)
9739483Smckusick 	struct vnode *vp;
9839483Smckusick 	struct uio *uio;
9939483Smckusick 	int ioflag;
10039483Smckusick 	struct ucred *cred;
10139483Smckusick {
10239483Smckusick 
10339591Smckusick 	if (chkvnlock(vp))
10439591Smckusick 		panic("dead_read: lock");
10539591Smckusick 	/*
10639591Smckusick 	 * Return EOF for character devices, EIO for others
10739591Smckusick 	 */
10839591Smckusick 	if (vp->v_type != VCHR)
10939483Smckusick 		return (EIO);
11039591Smckusick 	return (0);
11139483Smckusick }
11239483Smckusick 
11339483Smckusick /*
11439483Smckusick  * Vnode op for write
11539483Smckusick  */
11639591Smckusick /* ARGSUSED */
11739591Smckusick dead_write(vp, uio, ioflag, cred)
11839483Smckusick 	register struct vnode *vp;
11939483Smckusick 	struct uio *uio;
12039483Smckusick 	int ioflag;
12139483Smckusick 	struct ucred *cred;
12239483Smckusick {
12339483Smckusick 
12439591Smckusick 	if (chkvnlock(vp))
12539591Smckusick 		panic("dead_write: lock");
12639591Smckusick 	return (EIO);
12739483Smckusick }
12839483Smckusick 
12939483Smckusick /*
13039483Smckusick  * Device ioctl operation.
13139483Smckusick  */
13239483Smckusick /* ARGSUSED */
13339483Smckusick dead_ioctl(vp, com, data, fflag, cred)
13439483Smckusick 	struct vnode *vp;
13539483Smckusick 	register int com;
13639483Smckusick 	caddr_t data;
13739483Smckusick 	int fflag;
13839483Smckusick 	struct ucred *cred;
13939483Smckusick {
14039483Smckusick 
14139519Smckusick 	if (!chkvnlock(vp))
14239483Smckusick 		return (EBADF);
14339483Smckusick 	return (VOP_IOCTL(vp, com, data, fflag, cred));
14439483Smckusick }
14539483Smckusick 
14639483Smckusick /* ARGSUSED */
14740188Smckusick dead_select(vp, which, fflags, cred)
14839483Smckusick 	struct vnode *vp;
14940188Smckusick 	int which, fflags;
15039483Smckusick 	struct ucred *cred;
15139483Smckusick {
15239483Smckusick 
15339483Smckusick 	/*
15439483Smckusick 	 * Let the user find out that the descriptor is gone.
15539483Smckusick 	 */
15639483Smckusick 	return (1);
15739483Smckusick }
15839483Smckusick 
15939483Smckusick /*
16039483Smckusick  * Just call the device strategy routine
16139483Smckusick  */
16239483Smckusick dead_strategy(bp)
16339483Smckusick 	register struct buf *bp;
16439483Smckusick {
16539483Smckusick 
16639519Smckusick 	if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) {
16739518Smckusick 		bp->b_flags |= B_ERROR;
16839853Smckusick 		biodone(bp);
16939483Smckusick 		return (EIO);
17039518Smckusick 	}
17139483Smckusick 	return (VOP_STRATEGY(bp));
17239483Smckusick }
17339483Smckusick 
17439483Smckusick /*
17539483Smckusick  * Wait until the vnode has finished changing state.
17639483Smckusick  */
17739483Smckusick dead_lock(vp)
17839483Smckusick 	struct vnode *vp;
17939483Smckusick {
18039483Smckusick 
18139519Smckusick 	if (!chkvnlock(vp))
18239483Smckusick 		return (0);
18339483Smckusick 	return (VOP_LOCK(vp));
18439483Smckusick }
18539483Smckusick 
18639483Smckusick /*
18739508Smckusick  * Wait until the vnode has finished changing state.
18839508Smckusick  */
18939508Smckusick dead_bmap(vp, bn, vpp, bnp)
19039508Smckusick 	struct vnode *vp;
19139508Smckusick 	daddr_t bn;
19239508Smckusick 	struct vnode **vpp;
19339508Smckusick 	daddr_t *bnp;
19439508Smckusick {
19539508Smckusick 
19639519Smckusick 	if (!chkvnlock(vp))
19739508Smckusick 		return (EIO);
19839508Smckusick 	return (VOP_BMAP(vp, bn, vpp, bnp));
19939508Smckusick }
20039508Smckusick 
20139508Smckusick /*
20239911Smckusick  * Print out the contents of a dead vnode.
20339911Smckusick  */
20439911Smckusick dead_print(vp)
20539911Smckusick 	struct vnode *vp;
20639911Smckusick {
20739911Smckusick 
20839911Smckusick 	printf("tag VT_NON, dead vnode\n");
20939911Smckusick }
21039911Smckusick 
21139911Smckusick /*
21239486Smckusick  * Empty vnode failed operation
21339486Smckusick  */
21439486Smckusick dead_ebadf()
21539486Smckusick {
21639486Smckusick 
21739486Smckusick 	return (EBADF);
21839486Smckusick }
21939486Smckusick 
22039486Smckusick /*
22139483Smckusick  * Empty vnode bad operation
22239483Smckusick  */
22339483Smckusick dead_badop()
22439483Smckusick {
22539483Smckusick 
22639483Smckusick 	panic("dead_badop called");
22739483Smckusick 	/* NOTREACHED */
22839483Smckusick }
22939483Smckusick 
23039483Smckusick /*
23139483Smckusick  * Empty vnode null operation
23239483Smckusick  */
23339483Smckusick dead_nullop()
23439483Smckusick {
23539483Smckusick 
23639483Smckusick 	return (0);
23739483Smckusick }
23839519Smckusick 
23939519Smckusick /*
24039519Smckusick  * We have to wait during times when the vnode is
24139519Smckusick  * in a state of change.
24239519Smckusick  */
24339519Smckusick chkvnlock(vp)
24439519Smckusick 	register struct vnode *vp;
24539519Smckusick {
24639519Smckusick 	int locked = 0;
24739519Smckusick 
24839519Smckusick 	while (vp->v_flag & VXLOCK) {
24939519Smckusick 		vp->v_flag |= VXWANT;
25039519Smckusick 		sleep((caddr_t)vp, PINOD);
25139519Smckusick 		locked = 1;
25239519Smckusick 	}
25339519Smckusick 	return (locked);
25439519Smckusick }
255