xref: /csrg-svn/sys/miscfs/deadfs/dead_vnops.c (revision 53595)
139483Smckusick /*
239483Smckusick  * Copyright (c) 1989 The Regents of the University of California.
339483Smckusick  * All rights reserved.
439483Smckusick  *
544429Sbostic  * %sccs.include.redist.c%
639483Smckusick  *
7*53595Sheideman  *	@(#)dead_vnops.c	7.19 (Berkeley) 05/15/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_vget ((int (*) __P((struct  vop_vget_args *)))dead_badop)
5853536Sheideman #define dead_valloc ((int (*) __P((struct  vop_valloc_args *)))dead_badop)
5953536Sheideman #define dead_vfree ((int (*) __P((struct  vop_vfree_args *)))dead_badop)
6053536Sheideman #define dead_truncate ((int (*) __P((struct  vop_truncate_args *)))nullop)
6153536Sheideman #define dead_update ((int (*) __P((struct  vop_update_args *)))nullop)
6253536Sheideman #define dead_bwrite ((int (*) __P((struct  vop_bwrite_args *)))nullop)
6339483Smckusick 
6453536Sheideman int (**dead_vnodeop_p)();
6553536Sheideman struct vnodeopv_entry_desc dead_vnodeop_entries[] = {
6653536Sheideman 	{ &vop_default_desc, vn_default_error },
6753536Sheideman 	{ &vop_lookup_desc, dead_lookup },	/* lookup */
6853536Sheideman 	{ &vop_create_desc, dead_create },	/* create */
6953536Sheideman 	{ &vop_mknod_desc, dead_mknod },	/* mknod */
7053536Sheideman 	{ &vop_open_desc, dead_open },	/* open */
7153536Sheideman 	{ &vop_close_desc, dead_close },	/* close */
7253536Sheideman 	{ &vop_access_desc, dead_access },	/* access */
7353536Sheideman 	{ &vop_getattr_desc, dead_getattr },	/* getattr */
7453536Sheideman 	{ &vop_setattr_desc, dead_setattr },	/* setattr */
7553536Sheideman 	{ &vop_read_desc, dead_read },	/* read */
7653536Sheideman 	{ &vop_write_desc, dead_write },	/* write */
7753536Sheideman 	{ &vop_ioctl_desc, dead_ioctl },	/* ioctl */
7853536Sheideman 	{ &vop_select_desc, dead_select },	/* select */
7953536Sheideman 	{ &vop_mmap_desc, dead_mmap },	/* mmap */
8053536Sheideman 	{ &vop_fsync_desc, dead_fsync },	/* fsync */
8153536Sheideman 	{ &vop_seek_desc, dead_seek },	/* seek */
8253536Sheideman 	{ &vop_remove_desc, dead_remove },	/* remove */
8353536Sheideman 	{ &vop_link_desc, dead_link },	/* link */
8453536Sheideman 	{ &vop_rename_desc, dead_rename },	/* rename */
8553536Sheideman 	{ &vop_mkdir_desc, dead_mkdir },	/* mkdir */
8653536Sheideman 	{ &vop_rmdir_desc, dead_rmdir },	/* rmdir */
8753536Sheideman 	{ &vop_symlink_desc, dead_symlink },	/* symlink */
8853536Sheideman 	{ &vop_readdir_desc, dead_readdir },	/* readdir */
8953536Sheideman 	{ &vop_readlink_desc, dead_readlink },	/* readlink */
9053536Sheideman 	{ &vop_abortop_desc, dead_abortop },	/* abortop */
9153536Sheideman 	{ &vop_inactive_desc, dead_inactive },	/* inactive */
9253536Sheideman 	{ &vop_reclaim_desc, dead_reclaim },	/* reclaim */
9353536Sheideman 	{ &vop_lock_desc, dead_lock },	/* lock */
9453536Sheideman 	{ &vop_unlock_desc, dead_unlock },	/* unlock */
9553536Sheideman 	{ &vop_bmap_desc, dead_bmap },	/* bmap */
9653536Sheideman 	{ &vop_strategy_desc, dead_strategy },	/* strategy */
9753536Sheideman 	{ &vop_print_desc, dead_print },	/* print */
9853536Sheideman 	{ &vop_islocked_desc, dead_islocked },	/* islocked */
9953536Sheideman 	{ &vop_advlock_desc, dead_advlock },	/* advlock */
10053536Sheideman 	{ &vop_blkatoff_desc, dead_blkatoff },	/* blkatoff */
10153536Sheideman 	{ &vop_vget_desc, dead_vget },	/* vget */
10253536Sheideman 	{ &vop_valloc_desc, dead_valloc },	/* valloc */
10353536Sheideman 	{ &vop_vfree_desc, dead_vfree },	/* vfree */
10453536Sheideman 	{ &vop_truncate_desc, dead_truncate },	/* truncate */
10553536Sheideman 	{ &vop_update_desc, dead_update },	/* update */
10653536Sheideman 	{ &vop_bwrite_desc, dead_bwrite },	/* bwrite */
10753536Sheideman 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
10839483Smckusick };
10953536Sheideman struct vnodeopv_desc dead_vnodeop_opv_desc =
11053536Sheideman 	{ &dead_vnodeop_p, dead_vnodeop_entries };
11139483Smckusick 
11239483Smckusick /*
11339483Smckusick  * Trivial lookup routine that always fails.
11439483Smckusick  */
11548012Smckusick /* ARGSUSED */
11652303Sheideman int
11753536Sheideman dead_lookup (ap)
11853536Sheideman 	struct vop_lookup_args *ap;
11939483Smckusick {
12039483Smckusick 
121*53595Sheideman 	*ap->a_vpp = NULL;
12239483Smckusick 	return (ENOTDIR);
12339483Smckusick }
12439483Smckusick 
12539483Smckusick /*
12639483Smckusick  * Open always fails as if device did not exist.
12739483Smckusick  */
12839483Smckusick /* ARGSUSED */
12953536Sheideman dead_open (ap)
13053536Sheideman 	struct vop_open_args *ap;
13139483Smckusick {
13239483Smckusick 
13339483Smckusick 	return (ENXIO);
13439483Smckusick }
13539483Smckusick 
13639483Smckusick /*
13739483Smckusick  * Vnode op for read
13839483Smckusick  */
13939591Smckusick /* ARGSUSED */
14053536Sheideman dead_read (ap)
14153536Sheideman 	struct vop_read_args *ap;
14239483Smckusick {
14339483Smckusick 
144*53595Sheideman 	if (chkvnlock(ap->a_vp))
14539591Smckusick 		panic("dead_read: lock");
14639591Smckusick 	/*
14739591Smckusick 	 * Return EOF for character devices, EIO for others
14839591Smckusick 	 */
149*53595Sheideman 	if (ap->a_vp->v_type != VCHR)
15039483Smckusick 		return (EIO);
15139591Smckusick 	return (0);
15239483Smckusick }
15339483Smckusick 
15439483Smckusick /*
15539483Smckusick  * Vnode op for write
15639483Smckusick  */
15739591Smckusick /* ARGSUSED */
15853536Sheideman dead_write (ap)
15953536Sheideman 	struct vop_write_args *ap;
16039483Smckusick {
16139483Smckusick 
162*53595Sheideman 	if (chkvnlock(ap->a_vp))
16339591Smckusick 		panic("dead_write: lock");
16439591Smckusick 	return (EIO);
16539483Smckusick }
16639483Smckusick 
16739483Smckusick /*
16839483Smckusick  * Device ioctl operation.
16939483Smckusick  */
17039483Smckusick /* ARGSUSED */
17153536Sheideman dead_ioctl (ap)
17253536Sheideman 	struct vop_ioctl_args *ap;
17339483Smckusick {
17453536Sheideman 	USES_VOP_IOCTL;
17539483Smckusick 
176*53595Sheideman 	if (!chkvnlock(ap->a_vp))
17739483Smckusick 		return (EBADF);
178*53595Sheideman 	return (VOP_IOCTL(ap->a_vp, ap->a_command, ap->a_data, ap->a_fflag, ap->a_cred, ap->a_p));
17939483Smckusick }
18039483Smckusick 
18139483Smckusick /* ARGSUSED */
18253536Sheideman dead_select (ap)
18353536Sheideman 	struct vop_select_args *ap;
18439483Smckusick {
18539483Smckusick 
18639483Smckusick 	/*
18739483Smckusick 	 * Let the user find out that the descriptor is gone.
18839483Smckusick 	 */
18939483Smckusick 	return (1);
19039483Smckusick }
19139483Smckusick 
19239483Smckusick /*
19339483Smckusick  * Just call the device strategy routine
19439483Smckusick  */
19553536Sheideman dead_strategy (ap)
19653536Sheideman 	struct vop_strategy_args *ap;
19739483Smckusick {
19853536Sheideman 	USES_VOP_STRATEGY;
19939483Smckusick 
200*53595Sheideman 	if (ap->a_bp->b_vp == NULL || !chkvnlock(ap->a_bp->b_vp)) {
201*53595Sheideman 		ap->a_bp->b_flags |= B_ERROR;
202*53595Sheideman 		biodone(ap->a_bp);
20339483Smckusick 		return (EIO);
20439518Smckusick 	}
205*53595Sheideman 	return (VOP_STRATEGY(ap->a_bp));
20639483Smckusick }
20739483Smckusick 
20839483Smckusick /*
20939483Smckusick  * Wait until the vnode has finished changing state.
21039483Smckusick  */
21153536Sheideman dead_lock (ap)
21253536Sheideman 	struct vop_lock_args *ap;
21339483Smckusick {
21453536Sheideman 	USES_VOP_LOCK;
21539483Smckusick 
216*53595Sheideman 	if (!chkvnlock(ap->a_vp))
21739483Smckusick 		return (0);
218*53595Sheideman 	return (VOP_LOCK(ap->a_vp));
21939483Smckusick }
22039483Smckusick 
22139483Smckusick /*
22239508Smckusick  * Wait until the vnode has finished changing state.
22339508Smckusick  */
22453536Sheideman dead_bmap (ap)
22553536Sheideman 	struct vop_bmap_args *ap;
22639508Smckusick {
22753536Sheideman 	USES_VOP_BMAP;
22839508Smckusick 
229*53595Sheideman 	if (!chkvnlock(ap->a_vp))
23039508Smckusick 		return (EIO);
231*53595Sheideman 	return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp));
23239508Smckusick }
23339508Smckusick 
23439508Smckusick /*
23539911Smckusick  * Print out the contents of a dead vnode.
23639911Smckusick  */
23745110Smckusick /* ARGSUSED */
23853536Sheideman dead_print (ap)
23953536Sheideman 	struct vop_print_args *ap;
24039911Smckusick {
24139911Smckusick 
24239911Smckusick 	printf("tag VT_NON, dead vnode\n");
24339911Smckusick }
24439911Smckusick 
24539911Smckusick /*
24639486Smckusick  * Empty vnode failed operation
24739486Smckusick  */
24839486Smckusick dead_ebadf()
24939486Smckusick {
25039486Smckusick 
25139486Smckusick 	return (EBADF);
25239486Smckusick }
25339486Smckusick 
25439486Smckusick /*
25539483Smckusick  * Empty vnode bad operation
25639483Smckusick  */
25739483Smckusick dead_badop()
25839483Smckusick {
25939483Smckusick 
26039483Smckusick 	panic("dead_badop called");
26139483Smckusick 	/* NOTREACHED */
26239483Smckusick }
26339483Smckusick 
26439483Smckusick /*
26539483Smckusick  * Empty vnode null operation
26639483Smckusick  */
26739483Smckusick dead_nullop()
26839483Smckusick {
26939483Smckusick 
27039483Smckusick 	return (0);
27139483Smckusick }
27239519Smckusick 
27339519Smckusick /*
27439519Smckusick  * We have to wait during times when the vnode is
27539519Smckusick  * in a state of change.
27639519Smckusick  */
27739519Smckusick chkvnlock(vp)
27839519Smckusick 	register struct vnode *vp;
27939519Smckusick {
28039519Smckusick 	int locked = 0;
28139519Smckusick 
28239519Smckusick 	while (vp->v_flag & VXLOCK) {
28339519Smckusick 		vp->v_flag |= VXWANT;
28439519Smckusick 		sleep((caddr_t)vp, PINOD);
28539519Smckusick 		locked = 1;
28639519Smckusick 	}
28739519Smckusick 	return (locked);
28839519Smckusick }
289