139483Smckusick /* 239483Smckusick * Copyright (c) 1989 The Regents of the University of California. 339483Smckusick * All rights reserved. 439483Smckusick * 544429Sbostic * %sccs.include.redist.c% 639483Smckusick * 7*55014Smckusick * @(#)dead_vnops.c 7.23 (Berkeley) 07/12/92 839483Smckusick */ 939483Smckusick 10*55014Smckusick #include <sys/param.h> 11*55014Smckusick #include <sys/systm.h> 12*55014Smckusick #include <sys/time.h> 13*55014Smckusick #include <sys/vnode.h> 14*55014Smckusick #include <sys/errno.h> 15*55014Smckusick #include <sys/namei.h> 16*55014Smckusick #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 *)); 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_valloc ((int (*) __P((struct vop_valloc_args *)))dead_badop) 5853536Sheideman #define dead_vfree ((int (*) __P((struct vop_vfree_args *)))dead_badop) 5953536Sheideman #define dead_truncate ((int (*) __P((struct vop_truncate_args *)))nullop) 6053536Sheideman #define dead_update ((int (*) __P((struct vop_update_args *)))nullop) 6153536Sheideman #define dead_bwrite ((int (*) __P((struct vop_bwrite_args *)))nullop) 6239483Smckusick 6353536Sheideman int (**dead_vnodeop_p)(); 6453536Sheideman struct vnodeopv_entry_desc dead_vnodeop_entries[] = { 6553536Sheideman { &vop_default_desc, vn_default_error }, 6653536Sheideman { &vop_lookup_desc, dead_lookup }, /* lookup */ 6753536Sheideman { &vop_create_desc, dead_create }, /* create */ 6853536Sheideman { &vop_mknod_desc, dead_mknod }, /* mknod */ 6953536Sheideman { &vop_open_desc, dead_open }, /* open */ 7053536Sheideman { &vop_close_desc, dead_close }, /* close */ 7153536Sheideman { &vop_access_desc, dead_access }, /* access */ 7253536Sheideman { &vop_getattr_desc, dead_getattr }, /* getattr */ 7353536Sheideman { &vop_setattr_desc, dead_setattr }, /* setattr */ 7453536Sheideman { &vop_read_desc, dead_read }, /* read */ 7553536Sheideman { &vop_write_desc, dead_write }, /* write */ 7653536Sheideman { &vop_ioctl_desc, dead_ioctl }, /* ioctl */ 7753536Sheideman { &vop_select_desc, dead_select }, /* select */ 7853536Sheideman { &vop_mmap_desc, dead_mmap }, /* mmap */ 7953536Sheideman { &vop_fsync_desc, dead_fsync }, /* fsync */ 8053536Sheideman { &vop_seek_desc, dead_seek }, /* seek */ 8153536Sheideman { &vop_remove_desc, dead_remove }, /* remove */ 8253536Sheideman { &vop_link_desc, dead_link }, /* link */ 8353536Sheideman { &vop_rename_desc, dead_rename }, /* rename */ 8453536Sheideman { &vop_mkdir_desc, dead_mkdir }, /* mkdir */ 8553536Sheideman { &vop_rmdir_desc, dead_rmdir }, /* rmdir */ 8653536Sheideman { &vop_symlink_desc, dead_symlink }, /* symlink */ 8753536Sheideman { &vop_readdir_desc, dead_readdir }, /* readdir */ 8853536Sheideman { &vop_readlink_desc, dead_readlink }, /* readlink */ 8953536Sheideman { &vop_abortop_desc, dead_abortop }, /* abortop */ 9053536Sheideman { &vop_inactive_desc, dead_inactive }, /* inactive */ 9153536Sheideman { &vop_reclaim_desc, dead_reclaim }, /* reclaim */ 9253536Sheideman { &vop_lock_desc, dead_lock }, /* lock */ 9353536Sheideman { &vop_unlock_desc, dead_unlock }, /* unlock */ 9453536Sheideman { &vop_bmap_desc, dead_bmap }, /* bmap */ 9553536Sheideman { &vop_strategy_desc, dead_strategy }, /* strategy */ 9653536Sheideman { &vop_print_desc, dead_print }, /* print */ 9753536Sheideman { &vop_islocked_desc, dead_islocked }, /* islocked */ 9853536Sheideman { &vop_advlock_desc, dead_advlock }, /* advlock */ 9953536Sheideman { &vop_blkatoff_desc, dead_blkatoff }, /* blkatoff */ 10053536Sheideman { &vop_valloc_desc, dead_valloc }, /* valloc */ 10153536Sheideman { &vop_vfree_desc, dead_vfree }, /* vfree */ 10253536Sheideman { &vop_truncate_desc, dead_truncate }, /* truncate */ 10353536Sheideman { &vop_update_desc, dead_update }, /* update */ 10453536Sheideman { &vop_bwrite_desc, dead_bwrite }, /* bwrite */ 10553536Sheideman { (struct vnodeop_desc*)NULL, (int(*)())NULL } 10639483Smckusick }; 10753536Sheideman struct vnodeopv_desc dead_vnodeop_opv_desc = 10853536Sheideman { &dead_vnodeop_p, dead_vnodeop_entries }; 10939483Smckusick 11039483Smckusick /* 11139483Smckusick * Trivial lookup routine that always fails. 11239483Smckusick */ 11348012Smckusick /* ARGSUSED */ 11452303Sheideman int 11554630Smckusick dead_lookup(ap) 11654630Smckusick struct vop_lookup_args /* { 11754630Smckusick struct vnode * a_dvp; 11854630Smckusick struct vnode ** a_vpp; 11954630Smckusick struct componentname * a_cnp; 12054630Smckusick } */ *ap; 12139483Smckusick { 12239483Smckusick 12353595Sheideman *ap->a_vpp = NULL; 12439483Smckusick return (ENOTDIR); 12539483Smckusick } 12639483Smckusick 12739483Smckusick /* 12839483Smckusick * Open always fails as if device did not exist. 12939483Smckusick */ 13039483Smckusick /* ARGSUSED */ 13154630Smckusick dead_open(ap) 13254630Smckusick struct vop_open_args /* { 13354630Smckusick struct vnode *a_vp; 13454630Smckusick int a_mode; 13554630Smckusick struct ucred *a_cred; 13654630Smckusick struct proc *a_p; 13754630Smckusick } */ *ap; 13839483Smckusick { 13939483Smckusick 14039483Smckusick return (ENXIO); 14139483Smckusick } 14239483Smckusick 14339483Smckusick /* 14439483Smckusick * Vnode op for read 14539483Smckusick */ 14639591Smckusick /* ARGSUSED */ 14754630Smckusick dead_read(ap) 14854630Smckusick struct vop_read_args /* { 14954630Smckusick struct vnode *a_vp; 15054630Smckusick struct uio *a_uio; 15154630Smckusick int a_ioflag; 15254630Smckusick struct ucred *a_cred; 15354630Smckusick } */ *ap; 15439483Smckusick { 15539483Smckusick 15653595Sheideman if (chkvnlock(ap->a_vp)) 15739591Smckusick panic("dead_read: lock"); 15839591Smckusick /* 15939591Smckusick * Return EOF for character devices, EIO for others 16039591Smckusick */ 16153595Sheideman if (ap->a_vp->v_type != VCHR) 16239483Smckusick return (EIO); 16339591Smckusick return (0); 16439483Smckusick } 16539483Smckusick 16639483Smckusick /* 16739483Smckusick * Vnode op for write 16839483Smckusick */ 16939591Smckusick /* ARGSUSED */ 17054630Smckusick dead_write(ap) 17154630Smckusick struct vop_write_args /* { 17254630Smckusick struct vnode *a_vp; 17354630Smckusick struct uio *a_uio; 17454630Smckusick int a_ioflag; 17554630Smckusick struct ucred *a_cred; 17654630Smckusick } */ *ap; 17739483Smckusick { 17839483Smckusick 17953595Sheideman if (chkvnlock(ap->a_vp)) 18039591Smckusick panic("dead_write: lock"); 18139591Smckusick return (EIO); 18239483Smckusick } 18339483Smckusick 18439483Smckusick /* 18539483Smckusick * Device ioctl operation. 18639483Smckusick */ 18739483Smckusick /* ARGSUSED */ 18854630Smckusick dead_ioctl(ap) 18954630Smckusick struct vop_ioctl_args /* { 19054630Smckusick struct vnode *a_vp; 19154630Smckusick int a_command; 19254630Smckusick caddr_t a_data; 19354630Smckusick int a_fflag; 19454630Smckusick struct ucred *a_cred; 19554630Smckusick struct proc *a_p; 19654630Smckusick } */ *ap; 19739483Smckusick { 19839483Smckusick 19953595Sheideman if (!chkvnlock(ap->a_vp)) 20039483Smckusick return (EBADF); 20153757Sheideman return (VCALL(ap->a_vp, VOFFSET(vop_ioctl), ap)); 20239483Smckusick } 20339483Smckusick 20439483Smckusick /* ARGSUSED */ 20554630Smckusick dead_select(ap) 20654630Smckusick struct vop_select_args /* { 20754630Smckusick struct vnode *a_vp; 20854630Smckusick int a_which; 20954630Smckusick int a_fflags; 21054630Smckusick struct ucred *a_cred; 21154630Smckusick struct proc *a_p; 21254630Smckusick } */ *ap; 21339483Smckusick { 21439483Smckusick 21539483Smckusick /* 21639483Smckusick * Let the user find out that the descriptor is gone. 21739483Smckusick */ 21839483Smckusick return (1); 21939483Smckusick } 22039483Smckusick 22139483Smckusick /* 22239483Smckusick * Just call the device strategy routine 22339483Smckusick */ 22454630Smckusick dead_strategy(ap) 22554630Smckusick struct vop_strategy_args /* { 22654630Smckusick struct buf *a_bp; 22754630Smckusick } */ *ap; 22839483Smckusick { 22939483Smckusick 23053595Sheideman if (ap->a_bp->b_vp == NULL || !chkvnlock(ap->a_bp->b_vp)) { 23153595Sheideman ap->a_bp->b_flags |= B_ERROR; 23253595Sheideman biodone(ap->a_bp); 23339483Smckusick return (EIO); 23439518Smckusick } 23553595Sheideman return (VOP_STRATEGY(ap->a_bp)); 23639483Smckusick } 23739483Smckusick 23839483Smckusick /* 23939483Smckusick * Wait until the vnode has finished changing state. 24039483Smckusick */ 24154630Smckusick dead_lock(ap) 24254630Smckusick struct vop_lock_args /* { 24354630Smckusick struct vnode *a_vp; 24454630Smckusick } */ *ap; 24539483Smckusick { 24639483Smckusick 24753595Sheideman if (!chkvnlock(ap->a_vp)) 24839483Smckusick return (0); 24953757Sheideman return (VCALL(ap->a_vp, VOFFSET(vop_lock), ap)); 25039483Smckusick } 25139483Smckusick 25239483Smckusick /* 25339508Smckusick * Wait until the vnode has finished changing state. 25439508Smckusick */ 25554630Smckusick dead_bmap(ap) 25654630Smckusick struct vop_bmap_args /* { 25754630Smckusick struct vnode *a_vp; 25854630Smckusick daddr_t a_bn; 25954630Smckusick struct vnode **a_vpp; 26054630Smckusick daddr_t *a_bnp; 26154630Smckusick } */ *ap; 26239508Smckusick { 26339508Smckusick 26453595Sheideman if (!chkvnlock(ap->a_vp)) 26539508Smckusick return (EIO); 26653595Sheideman return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp)); 26739508Smckusick } 26839508Smckusick 26939508Smckusick /* 27039911Smckusick * Print out the contents of a dead vnode. 27139911Smckusick */ 27245110Smckusick /* ARGSUSED */ 27354630Smckusick dead_print(ap) 27454630Smckusick struct vop_print_args /* { 27554630Smckusick struct vnode *a_vp; 27654630Smckusick } */ *ap; 27739911Smckusick { 27839911Smckusick 27939911Smckusick printf("tag VT_NON, dead vnode\n"); 28039911Smckusick } 28139911Smckusick 28239911Smckusick /* 28339486Smckusick * Empty vnode failed operation 28439486Smckusick */ 28539486Smckusick dead_ebadf() 28639486Smckusick { 28739486Smckusick 28839486Smckusick return (EBADF); 28939486Smckusick } 29039486Smckusick 29139486Smckusick /* 29239483Smckusick * Empty vnode bad operation 29339483Smckusick */ 29439483Smckusick dead_badop() 29539483Smckusick { 29639483Smckusick 29739483Smckusick panic("dead_badop called"); 29839483Smckusick /* NOTREACHED */ 29939483Smckusick } 30039483Smckusick 30139483Smckusick /* 30239483Smckusick * Empty vnode null operation 30339483Smckusick */ 30439483Smckusick dead_nullop() 30539483Smckusick { 30639483Smckusick 30739483Smckusick return (0); 30839483Smckusick } 30939519Smckusick 31039519Smckusick /* 31139519Smckusick * We have to wait during times when the vnode is 31239519Smckusick * in a state of change. 31339519Smckusick */ 31439519Smckusick chkvnlock(vp) 31539519Smckusick register struct vnode *vp; 31639519Smckusick { 31739519Smckusick int locked = 0; 31839519Smckusick 31939519Smckusick while (vp->v_flag & VXLOCK) { 32039519Smckusick vp->v_flag |= VXWANT; 32139519Smckusick sleep((caddr_t)vp, PINOD); 32239519Smckusick locked = 1; 32339519Smckusick } 32439519Smckusick return (locked); 32539519Smckusick } 326