xref: /csrg-svn/sys/miscfs/deadfs/dead_vnops.c (revision 53536)
139483Smckusick /*
239483Smckusick  * Copyright (c) 1989 The Regents of the University of California.
339483Smckusick  * All rights reserved.
439483Smckusick  *
544429Sbostic  * %sccs.include.redist.c%
639483Smckusick  *
7*53536Sheideman  *	@(#)dead_vnops.c	7.18 (Berkeley) 05/14/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();
23*53536Sheideman int	dead_lookup __P((struct vop_lookup_args *));
24*53536Sheideman #define dead_create ((int (*) __P((struct  vop_create_args *)))dead_badop)
25*53536Sheideman #define dead_mknod ((int (*) __P((struct  vop_mknod_args *)))dead_badop)
26*53536Sheideman int	dead_open __P((struct vop_open_args *));
27*53536Sheideman #define dead_close ((int (*) __P((struct  vop_close_args *)))nullop)
28*53536Sheideman #define dead_access ((int (*) __P((struct  vop_access_args *)))dead_ebadf)
29*53536Sheideman #define dead_getattr ((int (*) __P((struct  vop_getattr_args *)))dead_ebadf)
30*53536Sheideman #define dead_setattr ((int (*) __P((struct  vop_setattr_args *)))dead_ebadf)
31*53536Sheideman int	dead_read __P((struct vop_read_args *));
32*53536Sheideman int	dead_write __P((struct vop_write_args *));
33*53536Sheideman int	dead_ioctl __P((struct vop_ioctl_args *));
34*53536Sheideman int	dead_select __P((struct vop_select_args *));
35*53536Sheideman #define dead_mmap ((int (*) __P((struct  vop_mmap_args *)))dead_badop)
36*53536Sheideman #define dead_fsync ((int (*) __P((struct  vop_fsync_args *)))nullop)
37*53536Sheideman #define dead_seek ((int (*) __P((struct  vop_seek_args *)))nullop)
38*53536Sheideman #define dead_remove ((int (*) __P((struct  vop_remove_args *)))dead_badop)
39*53536Sheideman #define dead_link ((int (*) __P((struct  vop_link_args *)))dead_badop)
40*53536Sheideman #define dead_rename ((int (*) __P((struct  vop_rename_args *)))dead_badop)
41*53536Sheideman #define dead_mkdir ((int (*) __P((struct  vop_mkdir_args *)))dead_badop)
42*53536Sheideman #define dead_rmdir ((int (*) __P((struct  vop_rmdir_args *)))dead_badop)
43*53536Sheideman #define dead_symlink ((int (*) __P((struct  vop_symlink_args *)))dead_badop)
44*53536Sheideman #define dead_readdir ((int (*) __P((struct  vop_readdir_args *)))dead_ebadf)
45*53536Sheideman #define dead_readlink ((int (*) __P((struct  vop_readlink_args *)))dead_ebadf)
46*53536Sheideman #define dead_abortop ((int (*) __P((struct  vop_abortop_args *)))dead_badop)
47*53536Sheideman #define dead_inactive ((int (*) __P((struct  vop_inactive_args *)))nullop)
48*53536Sheideman #define dead_reclaim ((int (*) __P((struct  vop_reclaim_args *)))nullop)
49*53536Sheideman int	dead_lock __P((struct vop_lock_args *));
50*53536Sheideman #define dead_unlock ((int (*) __P((struct  vop_unlock_args *)))nullop)
51*53536Sheideman int	dead_bmap __P((struct vop_bmap_args *));
52*53536Sheideman int	dead_strategy __P((struct vop_strategy_args *));
53*53536Sheideman int	dead_print __P((struct vop_print_args *));
54*53536Sheideman #define dead_islocked ((int (*) __P((struct  vop_islocked_args *)))nullop)
55*53536Sheideman #define dead_advlock ((int (*) __P((struct  vop_advlock_args *)))dead_ebadf)
56*53536Sheideman #define dead_blkatoff ((int (*) __P((struct  vop_blkatoff_args *)))dead_badop)
57*53536Sheideman #define dead_vget ((int (*) __P((struct  vop_vget_args *)))dead_badop)
58*53536Sheideman #define dead_valloc ((int (*) __P((struct  vop_valloc_args *)))dead_badop)
59*53536Sheideman #define dead_vfree ((int (*) __P((struct  vop_vfree_args *)))dead_badop)
60*53536Sheideman #define dead_truncate ((int (*) __P((struct  vop_truncate_args *)))nullop)
61*53536Sheideman #define dead_update ((int (*) __P((struct  vop_update_args *)))nullop)
62*53536Sheideman #define dead_bwrite ((int (*) __P((struct  vop_bwrite_args *)))nullop)
6339483Smckusick 
64*53536Sheideman int (**dead_vnodeop_p)();
65*53536Sheideman struct vnodeopv_entry_desc dead_vnodeop_entries[] = {
66*53536Sheideman 	{ &vop_default_desc, vn_default_error },
67*53536Sheideman 	{ &vop_lookup_desc, dead_lookup },	/* lookup */
68*53536Sheideman 	{ &vop_create_desc, dead_create },	/* create */
69*53536Sheideman 	{ &vop_mknod_desc, dead_mknod },	/* mknod */
70*53536Sheideman 	{ &vop_open_desc, dead_open },	/* open */
71*53536Sheideman 	{ &vop_close_desc, dead_close },	/* close */
72*53536Sheideman 	{ &vop_access_desc, dead_access },	/* access */
73*53536Sheideman 	{ &vop_getattr_desc, dead_getattr },	/* getattr */
74*53536Sheideman 	{ &vop_setattr_desc, dead_setattr },	/* setattr */
75*53536Sheideman 	{ &vop_read_desc, dead_read },	/* read */
76*53536Sheideman 	{ &vop_write_desc, dead_write },	/* write */
77*53536Sheideman 	{ &vop_ioctl_desc, dead_ioctl },	/* ioctl */
78*53536Sheideman 	{ &vop_select_desc, dead_select },	/* select */
79*53536Sheideman 	{ &vop_mmap_desc, dead_mmap },	/* mmap */
80*53536Sheideman 	{ &vop_fsync_desc, dead_fsync },	/* fsync */
81*53536Sheideman 	{ &vop_seek_desc, dead_seek },	/* seek */
82*53536Sheideman 	{ &vop_remove_desc, dead_remove },	/* remove */
83*53536Sheideman 	{ &vop_link_desc, dead_link },	/* link */
84*53536Sheideman 	{ &vop_rename_desc, dead_rename },	/* rename */
85*53536Sheideman 	{ &vop_mkdir_desc, dead_mkdir },	/* mkdir */
86*53536Sheideman 	{ &vop_rmdir_desc, dead_rmdir },	/* rmdir */
87*53536Sheideman 	{ &vop_symlink_desc, dead_symlink },	/* symlink */
88*53536Sheideman 	{ &vop_readdir_desc, dead_readdir },	/* readdir */
89*53536Sheideman 	{ &vop_readlink_desc, dead_readlink },	/* readlink */
90*53536Sheideman 	{ &vop_abortop_desc, dead_abortop },	/* abortop */
91*53536Sheideman 	{ &vop_inactive_desc, dead_inactive },	/* inactive */
92*53536Sheideman 	{ &vop_reclaim_desc, dead_reclaim },	/* reclaim */
93*53536Sheideman 	{ &vop_lock_desc, dead_lock },	/* lock */
94*53536Sheideman 	{ &vop_unlock_desc, dead_unlock },	/* unlock */
95*53536Sheideman 	{ &vop_bmap_desc, dead_bmap },	/* bmap */
96*53536Sheideman 	{ &vop_strategy_desc, dead_strategy },	/* strategy */
97*53536Sheideman 	{ &vop_print_desc, dead_print },	/* print */
98*53536Sheideman 	{ &vop_islocked_desc, dead_islocked },	/* islocked */
99*53536Sheideman 	{ &vop_advlock_desc, dead_advlock },	/* advlock */
100*53536Sheideman 	{ &vop_blkatoff_desc, dead_blkatoff },	/* blkatoff */
101*53536Sheideman 	{ &vop_vget_desc, dead_vget },	/* vget */
102*53536Sheideman 	{ &vop_valloc_desc, dead_valloc },	/* valloc */
103*53536Sheideman 	{ &vop_vfree_desc, dead_vfree },	/* vfree */
104*53536Sheideman 	{ &vop_truncate_desc, dead_truncate },	/* truncate */
105*53536Sheideman 	{ &vop_update_desc, dead_update },	/* update */
106*53536Sheideman 	{ &vop_bwrite_desc, dead_bwrite },	/* bwrite */
107*53536Sheideman 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
10839483Smckusick };
109*53536Sheideman struct vnodeopv_desc dead_vnodeop_opv_desc =
110*53536Sheideman 	{ &dead_vnodeop_p, dead_vnodeop_entries };
11139483Smckusick 
11239483Smckusick /*
11339483Smckusick  * Trivial lookup routine that always fails.
11439483Smckusick  */
11548012Smckusick /* ARGSUSED */
11652303Sheideman int
117*53536Sheideman dead_lookup (ap)
118*53536Sheideman 	struct vop_lookup_args *ap;
119*53536Sheideman #define dvp (ap->a_dvp)
120*53536Sheideman #define vpp (ap->a_vpp)
121*53536Sheideman #define cnp (ap->a_cnp)
12239483Smckusick {
12339483Smckusick 
12452303Sheideman 	*vpp = NULL;
12539483Smckusick 	return (ENOTDIR);
12639483Smckusick }
127*53536Sheideman #undef dvp
128*53536Sheideman #undef vpp
129*53536Sheideman #undef cnp
13039483Smckusick 
13139483Smckusick /*
13239483Smckusick  * Open always fails as if device did not exist.
13339483Smckusick  */
13439483Smckusick /* ARGSUSED */
135*53536Sheideman dead_open (ap)
136*53536Sheideman 	struct vop_open_args *ap;
137*53536Sheideman #define vp (ap->a_vp)
138*53536Sheideman #define mode (ap->a_mode)
139*53536Sheideman #define cred (ap->a_cred)
140*53536Sheideman #define p (ap->a_p)
14139483Smckusick {
14239483Smckusick 
14339483Smckusick 	return (ENXIO);
14439483Smckusick }
145*53536Sheideman #undef vp
146*53536Sheideman #undef mode
147*53536Sheideman #undef cred
148*53536Sheideman #undef p
14939483Smckusick 
15039483Smckusick /*
15139483Smckusick  * Vnode op for read
15239483Smckusick  */
15339591Smckusick /* ARGSUSED */
154*53536Sheideman dead_read (ap)
155*53536Sheideman 	struct vop_read_args *ap;
156*53536Sheideman #define vp (ap->a_vp)
157*53536Sheideman #define uio (ap->a_uio)
158*53536Sheideman #define ioflag (ap->a_ioflag)
159*53536Sheideman #define cred (ap->a_cred)
16039483Smckusick {
16139483Smckusick 
16239591Smckusick 	if (chkvnlock(vp))
16339591Smckusick 		panic("dead_read: lock");
16439591Smckusick 	/*
16539591Smckusick 	 * Return EOF for character devices, EIO for others
16639591Smckusick 	 */
16739591Smckusick 	if (vp->v_type != VCHR)
16839483Smckusick 		return (EIO);
16939591Smckusick 	return (0);
17039483Smckusick }
171*53536Sheideman #undef vp
172*53536Sheideman #undef uio
173*53536Sheideman #undef ioflag
174*53536Sheideman #undef cred
17539483Smckusick 
17639483Smckusick /*
17739483Smckusick  * Vnode op for write
17839483Smckusick  */
17939591Smckusick /* ARGSUSED */
180*53536Sheideman dead_write (ap)
181*53536Sheideman 	struct vop_write_args *ap;
182*53536Sheideman #define vp (ap->a_vp)
183*53536Sheideman #define uio (ap->a_uio)
184*53536Sheideman #define ioflag (ap->a_ioflag)
185*53536Sheideman #define cred (ap->a_cred)
18639483Smckusick {
18739483Smckusick 
18839591Smckusick 	if (chkvnlock(vp))
18939591Smckusick 		panic("dead_write: lock");
19039591Smckusick 	return (EIO);
19139483Smckusick }
192*53536Sheideman #undef vp
193*53536Sheideman #undef uio
194*53536Sheideman #undef ioflag
195*53536Sheideman #undef cred
19639483Smckusick 
19739483Smckusick /*
19839483Smckusick  * Device ioctl operation.
19939483Smckusick  */
20039483Smckusick /* ARGSUSED */
201*53536Sheideman dead_ioctl (ap)
202*53536Sheideman 	struct vop_ioctl_args *ap;
203*53536Sheideman #define vp (ap->a_vp)
204*53536Sheideman #define com (ap->a_command)
205*53536Sheideman #define data (ap->a_data)
206*53536Sheideman #define fflag (ap->a_fflag)
207*53536Sheideman #define cred (ap->a_cred)
208*53536Sheideman #define p (ap->a_p)
20939483Smckusick {
210*53536Sheideman 	USES_VOP_IOCTL;
21139483Smckusick 
21239519Smckusick 	if (!chkvnlock(vp))
21339483Smckusick 		return (EBADF);
21448012Smckusick 	return (VOP_IOCTL(vp, com, data, fflag, cred, p));
21539483Smckusick }
216*53536Sheideman #undef vp
217*53536Sheideman #undef com
218*53536Sheideman #undef data
219*53536Sheideman #undef fflag
220*53536Sheideman #undef cred
221*53536Sheideman #undef p
22239483Smckusick 
22339483Smckusick /* ARGSUSED */
224*53536Sheideman dead_select (ap)
225*53536Sheideman 	struct vop_select_args *ap;
226*53536Sheideman #define vp (ap->a_vp)
227*53536Sheideman #define which (ap->a_which)
228*53536Sheideman #define fflags (ap->a_fflags)
229*53536Sheideman #define cred (ap->a_cred)
230*53536Sheideman #define p (ap->a_p)
23139483Smckusick {
23239483Smckusick 
23339483Smckusick 	/*
23439483Smckusick 	 * Let the user find out that the descriptor is gone.
23539483Smckusick 	 */
23639483Smckusick 	return (1);
23739483Smckusick }
238*53536Sheideman #undef vp
239*53536Sheideman #undef which
240*53536Sheideman #undef fflags
241*53536Sheideman #undef cred
242*53536Sheideman #undef p
24339483Smckusick 
24439483Smckusick /*
24539483Smckusick  * Just call the device strategy routine
24639483Smckusick  */
247*53536Sheideman dead_strategy (ap)
248*53536Sheideman 	struct vop_strategy_args *ap;
249*53536Sheideman #define bp (ap->a_bp)
25039483Smckusick {
251*53536Sheideman 	USES_VOP_STRATEGY;
25239483Smckusick 
25339519Smckusick 	if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) {
25439518Smckusick 		bp->b_flags |= B_ERROR;
25539853Smckusick 		biodone(bp);
25639483Smckusick 		return (EIO);
25739518Smckusick 	}
25839483Smckusick 	return (VOP_STRATEGY(bp));
25939483Smckusick }
260*53536Sheideman #undef bp
26139483Smckusick 
26239483Smckusick /*
26339483Smckusick  * Wait until the vnode has finished changing state.
26439483Smckusick  */
265*53536Sheideman dead_lock (ap)
266*53536Sheideman 	struct vop_lock_args *ap;
267*53536Sheideman #define vp (ap->a_vp)
26839483Smckusick {
269*53536Sheideman 	USES_VOP_LOCK;
27039483Smckusick 
27139519Smckusick 	if (!chkvnlock(vp))
27239483Smckusick 		return (0);
27339483Smckusick 	return (VOP_LOCK(vp));
27439483Smckusick }
275*53536Sheideman #undef vp
27639483Smckusick 
27739483Smckusick /*
27839508Smckusick  * Wait until the vnode has finished changing state.
27939508Smckusick  */
280*53536Sheideman dead_bmap (ap)
281*53536Sheideman 	struct vop_bmap_args *ap;
282*53536Sheideman #define vp (ap->a_vp)
283*53536Sheideman #define bn (ap->a_bn)
284*53536Sheideman #define vpp (ap->a_vpp)
285*53536Sheideman #define bnp (ap->a_bnp)
28639508Smckusick {
287*53536Sheideman 	USES_VOP_BMAP;
28839508Smckusick 
28939519Smckusick 	if (!chkvnlock(vp))
29039508Smckusick 		return (EIO);
29139508Smckusick 	return (VOP_BMAP(vp, bn, vpp, bnp));
29239508Smckusick }
293*53536Sheideman #undef vp
294*53536Sheideman #undef bn
295*53536Sheideman #undef vpp
296*53536Sheideman #undef bnp
29739508Smckusick 
29839508Smckusick /*
29939911Smckusick  * Print out the contents of a dead vnode.
30039911Smckusick  */
30145110Smckusick /* ARGSUSED */
302*53536Sheideman dead_print (ap)
303*53536Sheideman 	struct vop_print_args *ap;
304*53536Sheideman #define vp (ap->a_vp)
30539911Smckusick {
30639911Smckusick 
30739911Smckusick 	printf("tag VT_NON, dead vnode\n");
30839911Smckusick }
309*53536Sheideman #undef vp
31039911Smckusick 
31139911Smckusick /*
31239486Smckusick  * Empty vnode failed operation
31339486Smckusick  */
31439486Smckusick dead_ebadf()
31539486Smckusick {
31639486Smckusick 
31739486Smckusick 	return (EBADF);
31839486Smckusick }
31939486Smckusick 
32039486Smckusick /*
32139483Smckusick  * Empty vnode bad operation
32239483Smckusick  */
32339483Smckusick dead_badop()
32439483Smckusick {
32539483Smckusick 
32639483Smckusick 	panic("dead_badop called");
32739483Smckusick 	/* NOTREACHED */
32839483Smckusick }
32939483Smckusick 
33039483Smckusick /*
33139483Smckusick  * Empty vnode null operation
33239483Smckusick  */
33339483Smckusick dead_nullop()
33439483Smckusick {
33539483Smckusick 
33639483Smckusick 	return (0);
33739483Smckusick }
33839519Smckusick 
33939519Smckusick /*
34039519Smckusick  * We have to wait during times when the vnode is
34139519Smckusick  * in a state of change.
34239519Smckusick  */
34339519Smckusick chkvnlock(vp)
34439519Smckusick 	register struct vnode *vp;
34539519Smckusick {
34639519Smckusick 	int locked = 0;
34739519Smckusick 
34839519Smckusick 	while (vp->v_flag & VXLOCK) {
34939519Smckusick 		vp->v_flag |= VXWANT;
35039519Smckusick 		sleep((caddr_t)vp, PINOD);
35139519Smckusick 		locked = 1;
35239519Smckusick 	}
35339519Smckusick 	return (locked);
35439519Smckusick }
355