139483Smckusick /* 239483Smckusick * Copyright (c) 1989 The Regents of the University of California. 339483Smckusick * All rights reserved. 439483Smckusick * 544429Sbostic * %sccs.include.redist.c% 639483Smckusick * 7*60392Smckusick * @(#)dead_vnops.c 7.25 (Berkeley) 05/25/93 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 *)); 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) 55*60392Smckusick #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 */ 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 */ 99*60392Smckusick { &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 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 /* 16139591Smckusick * Return EOF for character devices, EIO for others 16239591Smckusick */ 16353595Sheideman if (ap->a_vp->v_type != VCHR) 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; 24654630Smckusick } */ *ap; 24739483Smckusick { 24839483Smckusick 24953595Sheideman if (!chkvnlock(ap->a_vp)) 25039483Smckusick return (0); 25153757Sheideman return (VCALL(ap->a_vp, VOFFSET(vop_lock), ap)); 25239483Smckusick } 25339483Smckusick 25439483Smckusick /* 25539508Smckusick * Wait until the vnode has finished changing state. 25639508Smckusick */ 25754630Smckusick dead_bmap(ap) 25854630Smckusick struct vop_bmap_args /* { 25954630Smckusick struct vnode *a_vp; 26054630Smckusick daddr_t a_bn; 26154630Smckusick struct vnode **a_vpp; 26254630Smckusick daddr_t *a_bnp; 26356456Smargo int *a_runp; 26454630Smckusick } */ *ap; 26539508Smckusick { 26639508Smckusick 26753595Sheideman if (!chkvnlock(ap->a_vp)) 26839508Smckusick return (EIO); 26956456Smargo return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp, ap->a_runp)); 27039508Smckusick } 27139508Smckusick 27239508Smckusick /* 27339911Smckusick * Print out the contents of a dead vnode. 27439911Smckusick */ 27545110Smckusick /* ARGSUSED */ 27654630Smckusick dead_print(ap) 27754630Smckusick struct vop_print_args /* { 27854630Smckusick struct vnode *a_vp; 27954630Smckusick } */ *ap; 28039911Smckusick { 28139911Smckusick 28239911Smckusick printf("tag VT_NON, dead vnode\n"); 28339911Smckusick } 28439911Smckusick 28539911Smckusick /* 28639486Smckusick * Empty vnode failed operation 28739486Smckusick */ 28839486Smckusick dead_ebadf() 28939486Smckusick { 29039486Smckusick 29139486Smckusick return (EBADF); 29239486Smckusick } 29339486Smckusick 29439486Smckusick /* 29539483Smckusick * Empty vnode bad operation 29639483Smckusick */ 29739483Smckusick dead_badop() 29839483Smckusick { 29939483Smckusick 30039483Smckusick panic("dead_badop called"); 30139483Smckusick /* NOTREACHED */ 30239483Smckusick } 30339483Smckusick 30439483Smckusick /* 30539483Smckusick * Empty vnode null operation 30639483Smckusick */ 30739483Smckusick dead_nullop() 30839483Smckusick { 30939483Smckusick 31039483Smckusick return (0); 31139483Smckusick } 31239519Smckusick 31339519Smckusick /* 31439519Smckusick * We have to wait during times when the vnode is 31539519Smckusick * in a state of change. 31639519Smckusick */ 31739519Smckusick chkvnlock(vp) 31839519Smckusick register struct vnode *vp; 31939519Smckusick { 32039519Smckusick int locked = 0; 32139519Smckusick 32239519Smckusick while (vp->v_flag & VXLOCK) { 32339519Smckusick vp->v_flag |= VXWANT; 32439519Smckusick sleep((caddr_t)vp, PINOD); 32539519Smckusick locked = 1; 32639519Smckusick } 32739519Smckusick return (locked); 32839519Smckusick } 329