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