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