xref: /csrg-svn/sys/miscfs/deadfs/dead_vnops.c (revision 69432)
139483Smckusick /*
263231Sbostic  * Copyright (c) 1989, 1993
363231Sbostic  *	The Regents of the University of California.  All rights reserved.
439483Smckusick  *
544429Sbostic  * %sccs.include.redist.c%
639483Smckusick  *
7*69432Smckusick  *	@(#)dead_vnops.c	8.3 (Berkeley) 05/14/95
839483Smckusick  */
939483Smckusick 
1055014Smckusick #include <sys/param.h>
1155014Smckusick #include <sys/systm.h>
1255014Smckusick #include <sys/time.h>
1355014Smckusick #include <sys/vnode.h>
1455014Smckusick #include <sys/errno.h>
1555014Smckusick #include <sys/namei.h>
1655014Smckusick #include <sys/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 *));
50*69432Smckusick #define dead_unlock ((int (*) __P((struct vop_unlock_args *)))vop_nounlock)
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 *));
54*69432Smckusick #define dead_islocked ((int(*) __P((struct vop_islocked_args *)))vop_noislocked)
5560392Smckusick #define dead_pathconf ((int (*) __P((struct  vop_pathconf_args *)))dead_ebadf)
5653536Sheideman #define dead_advlock ((int (*) __P((struct  vop_advlock_args *)))dead_ebadf)
5753536Sheideman #define dead_blkatoff ((int (*) __P((struct  vop_blkatoff_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 */
70*69432Smckusick 	{ &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 */
75*69432Smckusick 	{ &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 */
79*69432Smckusick 	{ &vop_mmap_desc, dead_mmap },		/* mmap */
8053536Sheideman 	{ &vop_fsync_desc, dead_fsync },	/* fsync */
81*69432Smckusick 	{ &vop_seek_desc, dead_seek },		/* seek */
8253536Sheideman 	{ &vop_remove_desc, dead_remove },	/* remove */
83*69432Smckusick 	{ &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 */
93*69432Smckusick 	{ &vop_lock_desc, dead_lock },		/* lock */
9453536Sheideman 	{ &vop_unlock_desc, dead_unlock },	/* unlock */
95*69432Smckusick 	{ &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 */
9960392Smckusick 	{ &vop_pathconf_desc, dead_pathconf },	/* pathconf */
10053536Sheideman 	{ &vop_advlock_desc, dead_advlock },	/* advlock */
10153536Sheideman 	{ &vop_blkatoff_desc, dead_blkatoff },	/* blkatoff */
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
dead_lookup(ap)11754630Smckusick dead_lookup(ap)
11854630Smckusick 	struct vop_lookup_args /* {
11954630Smckusick 		struct vnode * a_dvp;
12054630Smckusick 		struct vnode ** a_vpp;
12154630Smckusick 		struct componentname * a_cnp;
12254630Smckusick 	} */ *ap;
12339483Smckusick {
12439483Smckusick 
12553595Sheideman 	*ap->a_vpp = NULL;
12639483Smckusick 	return (ENOTDIR);
12739483Smckusick }
12839483Smckusick 
12939483Smckusick /*
13039483Smckusick  * Open always fails as if device did not exist.
13139483Smckusick  */
13239483Smckusick /* ARGSUSED */
13354630Smckusick dead_open(ap)
13454630Smckusick 	struct vop_open_args /* {
13554630Smckusick 		struct vnode *a_vp;
13654630Smckusick 		int  a_mode;
13754630Smckusick 		struct ucred *a_cred;
13854630Smckusick 		struct proc *a_p;
13954630Smckusick 	} */ *ap;
14039483Smckusick {
14139483Smckusick 
14239483Smckusick 	return (ENXIO);
14339483Smckusick }
14439483Smckusick 
14539483Smckusick /*
14639483Smckusick  * Vnode op for read
14739483Smckusick  */
14839591Smckusick /* ARGSUSED */
14954630Smckusick dead_read(ap)
15054630Smckusick 	struct vop_read_args /* {
15154630Smckusick 		struct vnode *a_vp;
15254630Smckusick 		struct uio *a_uio;
15354630Smckusick 		int  a_ioflag;
15454630Smckusick 		struct ucred *a_cred;
15554630Smckusick 	} */ *ap;
15639483Smckusick {
15739483Smckusick 
15853595Sheideman 	if (chkvnlock(ap->a_vp))
15939591Smckusick 		panic("dead_read: lock");
16039591Smckusick 	/*
16167952Smckusick 	 * Return EOF for tty devices, EIO for others
16239591Smckusick 	 */
16367952Smckusick 	if ((ap->a_vp->v_flag & VISTTY) == 0)
16439483Smckusick 		return (EIO);
16539591Smckusick 	return (0);
16639483Smckusick }
16739483Smckusick 
16839483Smckusick /*
16939483Smckusick  * Vnode op for write
17039483Smckusick  */
17139591Smckusick /* ARGSUSED */
17254630Smckusick dead_write(ap)
17354630Smckusick 	struct vop_write_args /* {
17454630Smckusick 		struct vnode *a_vp;
17554630Smckusick 		struct uio *a_uio;
17654630Smckusick 		int  a_ioflag;
17754630Smckusick 		struct ucred *a_cred;
17854630Smckusick 	} */ *ap;
17939483Smckusick {
18039483Smckusick 
18153595Sheideman 	if (chkvnlock(ap->a_vp))
18239591Smckusick 		panic("dead_write: lock");
18339591Smckusick 	return (EIO);
18439483Smckusick }
18539483Smckusick 
18639483Smckusick /*
18739483Smckusick  * Device ioctl operation.
18839483Smckusick  */
18939483Smckusick /* ARGSUSED */
19054630Smckusick dead_ioctl(ap)
19154630Smckusick 	struct vop_ioctl_args /* {
19254630Smckusick 		struct vnode *a_vp;
19354630Smckusick 		int  a_command;
19454630Smckusick 		caddr_t  a_data;
19554630Smckusick 		int  a_fflag;
19654630Smckusick 		struct ucred *a_cred;
19754630Smckusick 		struct proc *a_p;
19854630Smckusick 	} */ *ap;
19939483Smckusick {
20039483Smckusick 
20153595Sheideman 	if (!chkvnlock(ap->a_vp))
20239483Smckusick 		return (EBADF);
20353757Sheideman 	return (VCALL(ap->a_vp, VOFFSET(vop_ioctl), ap));
20439483Smckusick }
20539483Smckusick 
20639483Smckusick /* ARGSUSED */
20754630Smckusick dead_select(ap)
20854630Smckusick 	struct vop_select_args /* {
20954630Smckusick 		struct vnode *a_vp;
21054630Smckusick 		int  a_which;
21154630Smckusick 		int  a_fflags;
21254630Smckusick 		struct ucred *a_cred;
21354630Smckusick 		struct proc *a_p;
21454630Smckusick 	} */ *ap;
21539483Smckusick {
21639483Smckusick 
21739483Smckusick 	/*
21839483Smckusick 	 * Let the user find out that the descriptor is gone.
21939483Smckusick 	 */
22039483Smckusick 	return (1);
22139483Smckusick }
22239483Smckusick 
22339483Smckusick /*
22439483Smckusick  * Just call the device strategy routine
22539483Smckusick  */
22654630Smckusick dead_strategy(ap)
22754630Smckusick 	struct vop_strategy_args /* {
22854630Smckusick 		struct buf *a_bp;
22954630Smckusick 	} */ *ap;
23039483Smckusick {
23139483Smckusick 
23253595Sheideman 	if (ap->a_bp->b_vp == NULL || !chkvnlock(ap->a_bp->b_vp)) {
23353595Sheideman 		ap->a_bp->b_flags |= B_ERROR;
23453595Sheideman 		biodone(ap->a_bp);
23539483Smckusick 		return (EIO);
23639518Smckusick 	}
23753595Sheideman 	return (VOP_STRATEGY(ap->a_bp));
23839483Smckusick }
23939483Smckusick 
24039483Smckusick /*
24139483Smckusick  * Wait until the vnode has finished changing state.
24239483Smckusick  */
24354630Smckusick dead_lock(ap)
24454630Smckusick 	struct vop_lock_args /* {
24554630Smckusick 		struct vnode *a_vp;
246*69432Smckusick 		int a_flags;
247*69432Smckusick 		struct proc *a_p;
24854630Smckusick 	} */ *ap;
24939483Smckusick {
250*69432Smckusick 	struct vnode *vp = ap->a_vp;
25139483Smckusick 
252*69432Smckusick 	/*
253*69432Smckusick 	 * Since we are not using the lock manager, we must clear
254*69432Smckusick 	 * the interlock here.
255*69432Smckusick 	 */
256*69432Smckusick 	if (ap->a_flags & LK_INTERLOCK) {
257*69432Smckusick 		simple_unlock(&vp->v_interlock);
258*69432Smckusick 		ap->a_flags &= ~LK_INTERLOCK;
259*69432Smckusick 	}
260*69432Smckusick 	if (!chkvnlock(vp))
26139483Smckusick 		return (0);
262*69432Smckusick 	return (VCALL(vp, VOFFSET(vop_lock), ap));
26339483Smckusick }
26439483Smckusick 
26539483Smckusick /*
26639508Smckusick  * Wait until the vnode has finished changing state.
26739508Smckusick  */
26854630Smckusick dead_bmap(ap)
26954630Smckusick 	struct vop_bmap_args /* {
27054630Smckusick 		struct vnode *a_vp;
27154630Smckusick 		daddr_t  a_bn;
27254630Smckusick 		struct vnode **a_vpp;
27354630Smckusick 		daddr_t *a_bnp;
27456456Smargo 		int *a_runp;
27554630Smckusick 	} */ *ap;
27639508Smckusick {
27739508Smckusick 
27853595Sheideman 	if (!chkvnlock(ap->a_vp))
27939508Smckusick 		return (EIO);
28056456Smargo 	return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp, ap->a_runp));
28139508Smckusick }
28239508Smckusick 
28339508Smckusick /*
28439911Smckusick  * Print out the contents of a dead vnode.
28539911Smckusick  */
28645110Smckusick /* ARGSUSED */
28754630Smckusick dead_print(ap)
28854630Smckusick 	struct vop_print_args /* {
28954630Smckusick 		struct vnode *a_vp;
29054630Smckusick 	} */ *ap;
29139911Smckusick {
29239911Smckusick 
29339911Smckusick 	printf("tag VT_NON, dead vnode\n");
29439911Smckusick }
29539911Smckusick 
29639911Smckusick /*
29739486Smckusick  * Empty vnode failed operation
29839486Smckusick  */
dead_ebadf()29939486Smckusick dead_ebadf()
30039486Smckusick {
30139486Smckusick 
30239486Smckusick 	return (EBADF);
30339486Smckusick }
30439486Smckusick 
30539486Smckusick /*
30639483Smckusick  * Empty vnode bad operation
30739483Smckusick  */
dead_badop()30839483Smckusick dead_badop()
30939483Smckusick {
31039483Smckusick 
31139483Smckusick 	panic("dead_badop called");
31239483Smckusick 	/* NOTREACHED */
31339483Smckusick }
31439483Smckusick 
31539483Smckusick /*
31639519Smckusick  * We have to wait during times when the vnode is
31739519Smckusick  * in a state of change.
31839519Smckusick  */
chkvnlock(vp)31939519Smckusick chkvnlock(vp)
32039519Smckusick 	register struct vnode *vp;
32139519Smckusick {
32239519Smckusick 	int locked = 0;
32339519Smckusick 
32439519Smckusick 	while (vp->v_flag & VXLOCK) {
32539519Smckusick 		vp->v_flag |= VXWANT;
32639519Smckusick 		sleep((caddr_t)vp, PINOD);
32739519Smckusick 		locked = 1;
32839519Smckusick 	}
32939519Smckusick 	return (locked);
33039519Smckusick }
331