xref: /csrg-svn/sys/miscfs/deadfs/dead_vnops.c (revision 54630)
139483Smckusick /*
239483Smckusick  * Copyright (c) 1989 The Regents of the University of California.
339483Smckusick  * All rights reserved.
439483Smckusick  *
544429Sbostic  * %sccs.include.redist.c%
639483Smckusick  *
7*54630Smckusick  *	@(#)dead_vnops.c	7.22 (Berkeley) 07/03/92
839483Smckusick  */
939483Smckusick 
1039483Smckusick #include "param.h"
1148012Smckusick #include "systm.h"
1239483Smckusick #include "time.h"
1339483Smckusick #include "vnode.h"
1439483Smckusick #include "errno.h"
1539483Smckusick #include "namei.h"
1639483Smckusick #include "buf.h"
1739483Smckusick 
1848012Smckusick /*
1948012Smckusick  * Prototypes for dead operations on vnodes.
2048012Smckusick  */
2148012Smckusick int	dead_badop(),
2248012Smckusick 	dead_ebadf();
2353536Sheideman int	dead_lookup __P((struct vop_lookup_args *));
2453536Sheideman #define dead_create ((int (*) __P((struct  vop_create_args *)))dead_badop)
2553536Sheideman #define dead_mknod ((int (*) __P((struct  vop_mknod_args *)))dead_badop)
2653536Sheideman int	dead_open __P((struct vop_open_args *));
2753536Sheideman #define dead_close ((int (*) __P((struct  vop_close_args *)))nullop)
2853536Sheideman #define dead_access ((int (*) __P((struct  vop_access_args *)))dead_ebadf)
2953536Sheideman #define dead_getattr ((int (*) __P((struct  vop_getattr_args *)))dead_ebadf)
3053536Sheideman #define dead_setattr ((int (*) __P((struct  vop_setattr_args *)))dead_ebadf)
3153536Sheideman int	dead_read __P((struct vop_read_args *));
3253536Sheideman int	dead_write __P((struct vop_write_args *));
3353536Sheideman int	dead_ioctl __P((struct vop_ioctl_args *));
3453536Sheideman int	dead_select __P((struct vop_select_args *));
3553536Sheideman #define dead_mmap ((int (*) __P((struct  vop_mmap_args *)))dead_badop)
3653536Sheideman #define dead_fsync ((int (*) __P((struct  vop_fsync_args *)))nullop)
3753536Sheideman #define dead_seek ((int (*) __P((struct  vop_seek_args *)))nullop)
3853536Sheideman #define dead_remove ((int (*) __P((struct  vop_remove_args *)))dead_badop)
3953536Sheideman #define dead_link ((int (*) __P((struct  vop_link_args *)))dead_badop)
4053536Sheideman #define dead_rename ((int (*) __P((struct  vop_rename_args *)))dead_badop)
4153536Sheideman #define dead_mkdir ((int (*) __P((struct  vop_mkdir_args *)))dead_badop)
4253536Sheideman #define dead_rmdir ((int (*) __P((struct  vop_rmdir_args *)))dead_badop)
4353536Sheideman #define dead_symlink ((int (*) __P((struct  vop_symlink_args *)))dead_badop)
4453536Sheideman #define dead_readdir ((int (*) __P((struct  vop_readdir_args *)))dead_ebadf)
4553536Sheideman #define dead_readlink ((int (*) __P((struct  vop_readlink_args *)))dead_ebadf)
4653536Sheideman #define dead_abortop ((int (*) __P((struct  vop_abortop_args *)))dead_badop)
4753536Sheideman #define dead_inactive ((int (*) __P((struct  vop_inactive_args *)))nullop)
4853536Sheideman #define dead_reclaim ((int (*) __P((struct  vop_reclaim_args *)))nullop)
4953536Sheideman int	dead_lock __P((struct vop_lock_args *));
5053536Sheideman #define dead_unlock ((int (*) __P((struct  vop_unlock_args *)))nullop)
5153536Sheideman int	dead_bmap __P((struct vop_bmap_args *));
5253536Sheideman int	dead_strategy __P((struct vop_strategy_args *));
5353536Sheideman int	dead_print __P((struct vop_print_args *));
5453536Sheideman #define dead_islocked ((int (*) __P((struct  vop_islocked_args *)))nullop)
5553536Sheideman #define dead_advlock ((int (*) __P((struct  vop_advlock_args *)))dead_ebadf)
5653536Sheideman #define dead_blkatoff ((int (*) __P((struct  vop_blkatoff_args *)))dead_badop)
5753536Sheideman #define dead_valloc ((int (*) __P((struct  vop_valloc_args *)))dead_badop)
5853536Sheideman #define dead_vfree ((int (*) __P((struct  vop_vfree_args *)))dead_badop)
5953536Sheideman #define dead_truncate ((int (*) __P((struct  vop_truncate_args *)))nullop)
6053536Sheideman #define dead_update ((int (*) __P((struct  vop_update_args *)))nullop)
6153536Sheideman #define dead_bwrite ((int (*) __P((struct  vop_bwrite_args *)))nullop)
6239483Smckusick 
6353536Sheideman int (**dead_vnodeop_p)();
6453536Sheideman struct vnodeopv_entry_desc dead_vnodeop_entries[] = {
6553536Sheideman 	{ &vop_default_desc, vn_default_error },
6653536Sheideman 	{ &vop_lookup_desc, dead_lookup },	/* lookup */
6753536Sheideman 	{ &vop_create_desc, dead_create },	/* create */
6853536Sheideman 	{ &vop_mknod_desc, dead_mknod },	/* mknod */
6953536Sheideman 	{ &vop_open_desc, dead_open },	/* open */
7053536Sheideman 	{ &vop_close_desc, dead_close },	/* close */
7153536Sheideman 	{ &vop_access_desc, dead_access },	/* access */
7253536Sheideman 	{ &vop_getattr_desc, dead_getattr },	/* getattr */
7353536Sheideman 	{ &vop_setattr_desc, dead_setattr },	/* setattr */
7453536Sheideman 	{ &vop_read_desc, dead_read },	/* read */
7553536Sheideman 	{ &vop_write_desc, dead_write },	/* write */
7653536Sheideman 	{ &vop_ioctl_desc, dead_ioctl },	/* ioctl */
7753536Sheideman 	{ &vop_select_desc, dead_select },	/* select */
7853536Sheideman 	{ &vop_mmap_desc, dead_mmap },	/* mmap */
7953536Sheideman 	{ &vop_fsync_desc, dead_fsync },	/* fsync */
8053536Sheideman 	{ &vop_seek_desc, dead_seek },	/* seek */
8153536Sheideman 	{ &vop_remove_desc, dead_remove },	/* remove */
8253536Sheideman 	{ &vop_link_desc, dead_link },	/* link */
8353536Sheideman 	{ &vop_rename_desc, dead_rename },	/* rename */
8453536Sheideman 	{ &vop_mkdir_desc, dead_mkdir },	/* mkdir */
8553536Sheideman 	{ &vop_rmdir_desc, dead_rmdir },	/* rmdir */
8653536Sheideman 	{ &vop_symlink_desc, dead_symlink },	/* symlink */
8753536Sheideman 	{ &vop_readdir_desc, dead_readdir },	/* readdir */
8853536Sheideman 	{ &vop_readlink_desc, dead_readlink },	/* readlink */
8953536Sheideman 	{ &vop_abortop_desc, dead_abortop },	/* abortop */
9053536Sheideman 	{ &vop_inactive_desc, dead_inactive },	/* inactive */
9153536Sheideman 	{ &vop_reclaim_desc, dead_reclaim },	/* reclaim */
9253536Sheideman 	{ &vop_lock_desc, dead_lock },	/* lock */
9353536Sheideman 	{ &vop_unlock_desc, dead_unlock },	/* unlock */
9453536Sheideman 	{ &vop_bmap_desc, dead_bmap },	/* bmap */
9553536Sheideman 	{ &vop_strategy_desc, dead_strategy },	/* strategy */
9653536Sheideman 	{ &vop_print_desc, dead_print },	/* print */
9753536Sheideman 	{ &vop_islocked_desc, dead_islocked },	/* islocked */
9853536Sheideman 	{ &vop_advlock_desc, dead_advlock },	/* advlock */
9953536Sheideman 	{ &vop_blkatoff_desc, dead_blkatoff },	/* blkatoff */
10053536Sheideman 	{ &vop_valloc_desc, dead_valloc },	/* valloc */
10153536Sheideman 	{ &vop_vfree_desc, dead_vfree },	/* vfree */
10253536Sheideman 	{ &vop_truncate_desc, dead_truncate },	/* truncate */
10353536Sheideman 	{ &vop_update_desc, dead_update },	/* update */
10453536Sheideman 	{ &vop_bwrite_desc, dead_bwrite },	/* bwrite */
10553536Sheideman 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
10639483Smckusick };
10753536Sheideman struct vnodeopv_desc dead_vnodeop_opv_desc =
10853536Sheideman 	{ &dead_vnodeop_p, dead_vnodeop_entries };
10939483Smckusick 
11039483Smckusick /*
11139483Smckusick  * Trivial lookup routine that always fails.
11239483Smckusick  */
11348012Smckusick /* ARGSUSED */
11452303Sheideman int
115*54630Smckusick dead_lookup(ap)
116*54630Smckusick 	struct vop_lookup_args /* {
117*54630Smckusick 		struct vnode * a_dvp;
118*54630Smckusick 		struct vnode ** a_vpp;
119*54630Smckusick 		struct componentname * a_cnp;
120*54630Smckusick 	} */ *ap;
12139483Smckusick {
12239483Smckusick 
12353595Sheideman 	*ap->a_vpp = NULL;
12439483Smckusick 	return (ENOTDIR);
12539483Smckusick }
12639483Smckusick 
12739483Smckusick /*
12839483Smckusick  * Open always fails as if device did not exist.
12939483Smckusick  */
13039483Smckusick /* ARGSUSED */
131*54630Smckusick dead_open(ap)
132*54630Smckusick 	struct vop_open_args /* {
133*54630Smckusick 		struct vnode *a_vp;
134*54630Smckusick 		int  a_mode;
135*54630Smckusick 		struct ucred *a_cred;
136*54630Smckusick 		struct proc *a_p;
137*54630Smckusick 	} */ *ap;
13839483Smckusick {
13939483Smckusick 
14039483Smckusick 	return (ENXIO);
14139483Smckusick }
14239483Smckusick 
14339483Smckusick /*
14439483Smckusick  * Vnode op for read
14539483Smckusick  */
14639591Smckusick /* ARGSUSED */
147*54630Smckusick dead_read(ap)
148*54630Smckusick 	struct vop_read_args /* {
149*54630Smckusick 		struct vnode *a_vp;
150*54630Smckusick 		struct uio *a_uio;
151*54630Smckusick 		int  a_ioflag;
152*54630Smckusick 		struct ucred *a_cred;
153*54630Smckusick 	} */ *ap;
15439483Smckusick {
15539483Smckusick 
15653595Sheideman 	if (chkvnlock(ap->a_vp))
15739591Smckusick 		panic("dead_read: lock");
15839591Smckusick 	/*
15939591Smckusick 	 * Return EOF for character devices, EIO for others
16039591Smckusick 	 */
16153595Sheideman 	if (ap->a_vp->v_type != VCHR)
16239483Smckusick 		return (EIO);
16339591Smckusick 	return (0);
16439483Smckusick }
16539483Smckusick 
16639483Smckusick /*
16739483Smckusick  * Vnode op for write
16839483Smckusick  */
16939591Smckusick /* ARGSUSED */
170*54630Smckusick dead_write(ap)
171*54630Smckusick 	struct vop_write_args /* {
172*54630Smckusick 		struct vnode *a_vp;
173*54630Smckusick 		struct uio *a_uio;
174*54630Smckusick 		int  a_ioflag;
175*54630Smckusick 		struct ucred *a_cred;
176*54630Smckusick 	} */ *ap;
17739483Smckusick {
17839483Smckusick 
17953595Sheideman 	if (chkvnlock(ap->a_vp))
18039591Smckusick 		panic("dead_write: lock");
18139591Smckusick 	return (EIO);
18239483Smckusick }
18339483Smckusick 
18439483Smckusick /*
18539483Smckusick  * Device ioctl operation.
18639483Smckusick  */
18739483Smckusick /* ARGSUSED */
188*54630Smckusick dead_ioctl(ap)
189*54630Smckusick 	struct vop_ioctl_args /* {
190*54630Smckusick 		struct vnode *a_vp;
191*54630Smckusick 		int  a_command;
192*54630Smckusick 		caddr_t  a_data;
193*54630Smckusick 		int  a_fflag;
194*54630Smckusick 		struct ucred *a_cred;
195*54630Smckusick 		struct proc *a_p;
196*54630Smckusick 	} */ *ap;
19739483Smckusick {
19839483Smckusick 
19953595Sheideman 	if (!chkvnlock(ap->a_vp))
20039483Smckusick 		return (EBADF);
20153757Sheideman 	return (VCALL(ap->a_vp, VOFFSET(vop_ioctl), ap));
20239483Smckusick }
20339483Smckusick 
20439483Smckusick /* ARGSUSED */
205*54630Smckusick dead_select(ap)
206*54630Smckusick 	struct vop_select_args /* {
207*54630Smckusick 		struct vnode *a_vp;
208*54630Smckusick 		int  a_which;
209*54630Smckusick 		int  a_fflags;
210*54630Smckusick 		struct ucred *a_cred;
211*54630Smckusick 		struct proc *a_p;
212*54630Smckusick 	} */ *ap;
21339483Smckusick {
21439483Smckusick 
21539483Smckusick 	/*
21639483Smckusick 	 * Let the user find out that the descriptor is gone.
21739483Smckusick 	 */
21839483Smckusick 	return (1);
21939483Smckusick }
22039483Smckusick 
22139483Smckusick /*
22239483Smckusick  * Just call the device strategy routine
22339483Smckusick  */
224*54630Smckusick dead_strategy(ap)
225*54630Smckusick 	struct vop_strategy_args /* {
226*54630Smckusick 		struct buf *a_bp;
227*54630Smckusick 	} */ *ap;
22839483Smckusick {
22939483Smckusick 
23053595Sheideman 	if (ap->a_bp->b_vp == NULL || !chkvnlock(ap->a_bp->b_vp)) {
23153595Sheideman 		ap->a_bp->b_flags |= B_ERROR;
23253595Sheideman 		biodone(ap->a_bp);
23339483Smckusick 		return (EIO);
23439518Smckusick 	}
23553595Sheideman 	return (VOP_STRATEGY(ap->a_bp));
23639483Smckusick }
23739483Smckusick 
23839483Smckusick /*
23939483Smckusick  * Wait until the vnode has finished changing state.
24039483Smckusick  */
241*54630Smckusick dead_lock(ap)
242*54630Smckusick 	struct vop_lock_args /* {
243*54630Smckusick 		struct vnode *a_vp;
244*54630Smckusick 	} */ *ap;
24539483Smckusick {
24639483Smckusick 
24753595Sheideman 	if (!chkvnlock(ap->a_vp))
24839483Smckusick 		return (0);
24953757Sheideman 	return (VCALL(ap->a_vp, VOFFSET(vop_lock), ap));
25039483Smckusick }
25139483Smckusick 
25239483Smckusick /*
25339508Smckusick  * Wait until the vnode has finished changing state.
25439508Smckusick  */
255*54630Smckusick dead_bmap(ap)
256*54630Smckusick 	struct vop_bmap_args /* {
257*54630Smckusick 		struct vnode *a_vp;
258*54630Smckusick 		daddr_t  a_bn;
259*54630Smckusick 		struct vnode **a_vpp;
260*54630Smckusick 		daddr_t *a_bnp;
261*54630Smckusick 	} */ *ap;
26239508Smckusick {
26339508Smckusick 
26453595Sheideman 	if (!chkvnlock(ap->a_vp))
26539508Smckusick 		return (EIO);
26653595Sheideman 	return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp));
26739508Smckusick }
26839508Smckusick 
26939508Smckusick /*
27039911Smckusick  * Print out the contents of a dead vnode.
27139911Smckusick  */
27245110Smckusick /* ARGSUSED */
273*54630Smckusick dead_print(ap)
274*54630Smckusick 	struct vop_print_args /* {
275*54630Smckusick 		struct vnode *a_vp;
276*54630Smckusick 	} */ *ap;
27739911Smckusick {
27839911Smckusick 
27939911Smckusick 	printf("tag VT_NON, dead vnode\n");
28039911Smckusick }
28139911Smckusick 
28239911Smckusick /*
28339486Smckusick  * Empty vnode failed operation
28439486Smckusick  */
28539486Smckusick dead_ebadf()
28639486Smckusick {
28739486Smckusick 
28839486Smckusick 	return (EBADF);
28939486Smckusick }
29039486Smckusick 
29139486Smckusick /*
29239483Smckusick  * Empty vnode bad operation
29339483Smckusick  */
29439483Smckusick dead_badop()
29539483Smckusick {
29639483Smckusick 
29739483Smckusick 	panic("dead_badop called");
29839483Smckusick 	/* NOTREACHED */
29939483Smckusick }
30039483Smckusick 
30139483Smckusick /*
30239483Smckusick  * Empty vnode null operation
30339483Smckusick  */
30439483Smckusick dead_nullop()
30539483Smckusick {
30639483Smckusick 
30739483Smckusick 	return (0);
30839483Smckusick }
30939519Smckusick 
31039519Smckusick /*
31139519Smckusick  * We have to wait during times when the vnode is
31239519Smckusick  * in a state of change.
31339519Smckusick  */
31439519Smckusick chkvnlock(vp)
31539519Smckusick 	register struct vnode *vp;
31639519Smckusick {
31739519Smckusick 	int locked = 0;
31839519Smckusick 
31939519Smckusick 	while (vp->v_flag & VXLOCK) {
32039519Smckusick 		vp->v_flag |= VXWANT;
32139519Smckusick 		sleep((caddr_t)vp, PINOD);
32239519Smckusick 		locked = 1;
32339519Smckusick 	}
32439519Smckusick 	return (locked);
32539519Smckusick }
326