dead_vnops.c revision 3396
11541Srgrimes/* 21541Srgrimes * Copyright (c) 1989, 1993 31541Srgrimes * The Regents of the University of California. All rights reserved. 41541Srgrimes * 51541Srgrimes * Redistribution and use in source and binary forms, with or without 61541Srgrimes * modification, are permitted provided that the following conditions 71541Srgrimes * are met: 81541Srgrimes * 1. Redistributions of source code must retain the above copyright 91541Srgrimes * notice, this list of conditions and the following disclaimer. 101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer in the 121541Srgrimes * documentation and/or other materials provided with the distribution. 131541Srgrimes * 3. All advertising materials mentioning features or use of this software 141541Srgrimes * must display the following acknowledgement: 151541Srgrimes * This product includes software developed by the University of 161541Srgrimes * California, Berkeley and its contributors. 171541Srgrimes * 4. Neither the name of the University nor the names of its contributors 181541Srgrimes * may be used to endorse or promote products derived from this software 191541Srgrimes * without specific prior written permission. 201541Srgrimes * 211541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311541Srgrimes * SUCH DAMAGE. 321541Srgrimes * 331541Srgrimes * @(#)dead_vnops.c 8.1 (Berkeley) 6/10/93 343396Sdg * $Id: dead_vnops.c,v 1.4 1994/09/21 03:46:52 wollman Exp $ 351541Srgrimes */ 361541Srgrimes 371541Srgrimes#include <sys/param.h> 381541Srgrimes#include <sys/systm.h> 391541Srgrimes#include <sys/time.h> 402946Swollman#include <sys/kernel.h> 411541Srgrimes#include <sys/vnode.h> 421541Srgrimes#include <sys/errno.h> 431541Srgrimes#include <sys/namei.h> 441541Srgrimes#include <sys/buf.h> 451541Srgrimes 461541Srgrimes/* 471541Srgrimes * Prototypes for dead operations on vnodes. 481541Srgrimes */ 491541Srgrimesint dead_badop(), 501541Srgrimes dead_ebadf(); 511541Srgrimesint dead_lookup __P((struct vop_lookup_args *)); 521541Srgrimes#define dead_create ((int (*) __P((struct vop_create_args *)))dead_badop) 531541Srgrimes#define dead_mknod ((int (*) __P((struct vop_mknod_args *)))dead_badop) 541541Srgrimesint dead_open __P((struct vop_open_args *)); 551541Srgrimes#define dead_close ((int (*) __P((struct vop_close_args *)))nullop) 561541Srgrimes#define dead_access ((int (*) __P((struct vop_access_args *)))dead_ebadf) 571541Srgrimes#define dead_getattr ((int (*) __P((struct vop_getattr_args *)))dead_ebadf) 581541Srgrimes#define dead_setattr ((int (*) __P((struct vop_setattr_args *)))dead_ebadf) 591541Srgrimesint dead_read __P((struct vop_read_args *)); 601541Srgrimesint dead_write __P((struct vop_write_args *)); 611541Srgrimesint dead_ioctl __P((struct vop_ioctl_args *)); 621541Srgrimesint dead_select __P((struct vop_select_args *)); 631541Srgrimes#define dead_mmap ((int (*) __P((struct vop_mmap_args *)))dead_badop) 641541Srgrimes#define dead_fsync ((int (*) __P((struct vop_fsync_args *)))nullop) 651541Srgrimes#define dead_seek ((int (*) __P((struct vop_seek_args *)))nullop) 661541Srgrimes#define dead_remove ((int (*) __P((struct vop_remove_args *)))dead_badop) 671541Srgrimes#define dead_link ((int (*) __P((struct vop_link_args *)))dead_badop) 681541Srgrimes#define dead_rename ((int (*) __P((struct vop_rename_args *)))dead_badop) 691541Srgrimes#define dead_mkdir ((int (*) __P((struct vop_mkdir_args *)))dead_badop) 701541Srgrimes#define dead_rmdir ((int (*) __P((struct vop_rmdir_args *)))dead_badop) 711541Srgrimes#define dead_symlink ((int (*) __P((struct vop_symlink_args *)))dead_badop) 721541Srgrimes#define dead_readdir ((int (*) __P((struct vop_readdir_args *)))dead_ebadf) 731541Srgrimes#define dead_readlink ((int (*) __P((struct vop_readlink_args *)))dead_ebadf) 741541Srgrimes#define dead_abortop ((int (*) __P((struct vop_abortop_args *)))dead_badop) 751541Srgrimes#define dead_inactive ((int (*) __P((struct vop_inactive_args *)))nullop) 761541Srgrimes#define dead_reclaim ((int (*) __P((struct vop_reclaim_args *)))nullop) 771541Srgrimesint dead_lock __P((struct vop_lock_args *)); 781541Srgrimes#define dead_unlock ((int (*) __P((struct vop_unlock_args *)))nullop) 791541Srgrimesint dead_bmap __P((struct vop_bmap_args *)); 801541Srgrimesint dead_strategy __P((struct vop_strategy_args *)); 811541Srgrimesint dead_print __P((struct vop_print_args *)); 821541Srgrimes#define dead_islocked ((int (*) __P((struct vop_islocked_args *)))nullop) 831541Srgrimes#define dead_pathconf ((int (*) __P((struct vop_pathconf_args *)))dead_ebadf) 841541Srgrimes#define dead_advlock ((int (*) __P((struct vop_advlock_args *)))dead_ebadf) 851541Srgrimes#define dead_blkatoff ((int (*) __P((struct vop_blkatoff_args *)))dead_badop) 861541Srgrimes#define dead_valloc ((int (*) __P((struct vop_valloc_args *)))dead_badop) 871541Srgrimes#define dead_vfree ((int (*) __P((struct vop_vfree_args *)))dead_badop) 881541Srgrimes#define dead_truncate ((int (*) __P((struct vop_truncate_args *)))nullop) 891541Srgrimes#define dead_update ((int (*) __P((struct vop_update_args *)))nullop) 901541Srgrimes#define dead_bwrite ((int (*) __P((struct vop_bwrite_args *)))nullop) 911541Srgrimes 921541Srgrimesint (**dead_vnodeop_p)(); 931541Srgrimesstruct vnodeopv_entry_desc dead_vnodeop_entries[] = { 941541Srgrimes { &vop_default_desc, vn_default_error }, 951541Srgrimes { &vop_lookup_desc, dead_lookup }, /* lookup */ 961541Srgrimes { &vop_create_desc, dead_create }, /* create */ 971541Srgrimes { &vop_mknod_desc, dead_mknod }, /* mknod */ 981541Srgrimes { &vop_open_desc, dead_open }, /* open */ 991541Srgrimes { &vop_close_desc, dead_close }, /* close */ 1001541Srgrimes { &vop_access_desc, dead_access }, /* access */ 1011541Srgrimes { &vop_getattr_desc, dead_getattr }, /* getattr */ 1021541Srgrimes { &vop_setattr_desc, dead_setattr }, /* setattr */ 1031541Srgrimes { &vop_read_desc, dead_read }, /* read */ 1041541Srgrimes { &vop_write_desc, dead_write }, /* write */ 1051541Srgrimes { &vop_ioctl_desc, dead_ioctl }, /* ioctl */ 1061541Srgrimes { &vop_select_desc, dead_select }, /* select */ 1071541Srgrimes { &vop_mmap_desc, dead_mmap }, /* mmap */ 1081541Srgrimes { &vop_fsync_desc, dead_fsync }, /* fsync */ 1091541Srgrimes { &vop_seek_desc, dead_seek }, /* seek */ 1101541Srgrimes { &vop_remove_desc, dead_remove }, /* remove */ 1111541Srgrimes { &vop_link_desc, dead_link }, /* link */ 1121541Srgrimes { &vop_rename_desc, dead_rename }, /* rename */ 1131541Srgrimes { &vop_mkdir_desc, dead_mkdir }, /* mkdir */ 1141541Srgrimes { &vop_rmdir_desc, dead_rmdir }, /* rmdir */ 1151541Srgrimes { &vop_symlink_desc, dead_symlink }, /* symlink */ 1161541Srgrimes { &vop_readdir_desc, dead_readdir }, /* readdir */ 1171541Srgrimes { &vop_readlink_desc, dead_readlink }, /* readlink */ 1181541Srgrimes { &vop_abortop_desc, dead_abortop }, /* abortop */ 1191541Srgrimes { &vop_inactive_desc, dead_inactive }, /* inactive */ 1201541Srgrimes { &vop_reclaim_desc, dead_reclaim }, /* reclaim */ 1211541Srgrimes { &vop_lock_desc, dead_lock }, /* lock */ 1221541Srgrimes { &vop_unlock_desc, dead_unlock }, /* unlock */ 1231541Srgrimes { &vop_bmap_desc, dead_bmap }, /* bmap */ 1241541Srgrimes { &vop_strategy_desc, dead_strategy }, /* strategy */ 1251541Srgrimes { &vop_print_desc, dead_print }, /* print */ 1261541Srgrimes { &vop_islocked_desc, dead_islocked }, /* islocked */ 1271541Srgrimes { &vop_pathconf_desc, dead_pathconf }, /* pathconf */ 1281541Srgrimes { &vop_advlock_desc, dead_advlock }, /* advlock */ 1291541Srgrimes { &vop_blkatoff_desc, dead_blkatoff }, /* blkatoff */ 1301541Srgrimes { &vop_valloc_desc, dead_valloc }, /* valloc */ 1311541Srgrimes { &vop_vfree_desc, dead_vfree }, /* vfree */ 1321541Srgrimes { &vop_truncate_desc, dead_truncate }, /* truncate */ 1331541Srgrimes { &vop_update_desc, dead_update }, /* update */ 1341541Srgrimes { &vop_bwrite_desc, dead_bwrite }, /* bwrite */ 1351541Srgrimes { (struct vnodeop_desc*)NULL, (int(*)())NULL } 1361541Srgrimes}; 1371541Srgrimesstruct vnodeopv_desc dead_vnodeop_opv_desc = 1381541Srgrimes { &dead_vnodeop_p, dead_vnodeop_entries }; 1391541Srgrimes 1402946SwollmanVNODEOP_SET(dead_vnodeop_opv_desc); 1412946Swollman 1421541Srgrimes/* 1431541Srgrimes * Trivial lookup routine that always fails. 1441541Srgrimes */ 1451541Srgrimes/* ARGSUSED */ 1461541Srgrimesint 1471541Srgrimesdead_lookup(ap) 1481541Srgrimes struct vop_lookup_args /* { 1491541Srgrimes struct vnode * a_dvp; 1501541Srgrimes struct vnode ** a_vpp; 1511541Srgrimes struct componentname * a_cnp; 1521541Srgrimes } */ *ap; 1531541Srgrimes{ 1541541Srgrimes 1551541Srgrimes *ap->a_vpp = NULL; 1561541Srgrimes return (ENOTDIR); 1571541Srgrimes} 1581541Srgrimes 1591541Srgrimes/* 1601541Srgrimes * Open always fails as if device did not exist. 1611541Srgrimes */ 1621541Srgrimes/* ARGSUSED */ 1631549Srgrimesint 1641541Srgrimesdead_open(ap) 1651541Srgrimes struct vop_open_args /* { 1661541Srgrimes struct vnode *a_vp; 1671541Srgrimes int a_mode; 1681541Srgrimes struct ucred *a_cred; 1691541Srgrimes struct proc *a_p; 1701541Srgrimes } */ *ap; 1711541Srgrimes{ 1721541Srgrimes 1731541Srgrimes return (ENXIO); 1741541Srgrimes} 1751541Srgrimes 1761541Srgrimes/* 1771541Srgrimes * Vnode op for read 1781541Srgrimes */ 1791541Srgrimes/* ARGSUSED */ 1801549Srgrimesint 1811541Srgrimesdead_read(ap) 1821541Srgrimes struct vop_read_args /* { 1831541Srgrimes struct vnode *a_vp; 1841541Srgrimes struct uio *a_uio; 1851541Srgrimes int a_ioflag; 1861541Srgrimes struct ucred *a_cred; 1871541Srgrimes } */ *ap; 1881541Srgrimes{ 1891541Srgrimes 1901541Srgrimes if (chkvnlock(ap->a_vp)) 1911541Srgrimes panic("dead_read: lock"); 1921541Srgrimes /* 1931541Srgrimes * Return EOF for character devices, EIO for others 1941541Srgrimes */ 1951541Srgrimes if (ap->a_vp->v_type != VCHR) 1961541Srgrimes return (EIO); 1971541Srgrimes return (0); 1981541Srgrimes} 1991541Srgrimes 2001541Srgrimes/* 2011541Srgrimes * Vnode op for write 2021541Srgrimes */ 2031541Srgrimes/* ARGSUSED */ 2041549Srgrimesint 2051541Srgrimesdead_write(ap) 2061541Srgrimes struct vop_write_args /* { 2071541Srgrimes struct vnode *a_vp; 2081541Srgrimes struct uio *a_uio; 2091541Srgrimes int a_ioflag; 2101541Srgrimes struct ucred *a_cred; 2111541Srgrimes } */ *ap; 2121541Srgrimes{ 2131541Srgrimes 2141541Srgrimes if (chkvnlock(ap->a_vp)) 2151541Srgrimes panic("dead_write: lock"); 2161541Srgrimes return (EIO); 2171541Srgrimes} 2181541Srgrimes 2191541Srgrimes/* 2201541Srgrimes * Device ioctl operation. 2211541Srgrimes */ 2221541Srgrimes/* ARGSUSED */ 2231549Srgrimesint 2241541Srgrimesdead_ioctl(ap) 2251541Srgrimes struct vop_ioctl_args /* { 2261541Srgrimes struct vnode *a_vp; 2271541Srgrimes int a_command; 2281541Srgrimes caddr_t a_data; 2291541Srgrimes int a_fflag; 2301541Srgrimes struct ucred *a_cred; 2311541Srgrimes struct proc *a_p; 2321541Srgrimes } */ *ap; 2331541Srgrimes{ 2341541Srgrimes 2351541Srgrimes if (!chkvnlock(ap->a_vp)) 2361541Srgrimes return (EBADF); 2371541Srgrimes return (VCALL(ap->a_vp, VOFFSET(vop_ioctl), ap)); 2381541Srgrimes} 2391541Srgrimes 2401541Srgrimes/* ARGSUSED */ 2411549Srgrimesint 2421541Srgrimesdead_select(ap) 2431541Srgrimes struct vop_select_args /* { 2441541Srgrimes struct vnode *a_vp; 2451541Srgrimes int a_which; 2461541Srgrimes int a_fflags; 2471541Srgrimes struct ucred *a_cred; 2481541Srgrimes struct proc *a_p; 2491541Srgrimes } */ *ap; 2501541Srgrimes{ 2511541Srgrimes 2521541Srgrimes /* 2531541Srgrimes * Let the user find out that the descriptor is gone. 2541541Srgrimes */ 2551541Srgrimes return (1); 2561541Srgrimes} 2571541Srgrimes 2581541Srgrimes/* 2591541Srgrimes * Just call the device strategy routine 2601541Srgrimes */ 2611549Srgrimesint 2621541Srgrimesdead_strategy(ap) 2631541Srgrimes struct vop_strategy_args /* { 2641541Srgrimes struct buf *a_bp; 2651541Srgrimes } */ *ap; 2661541Srgrimes{ 2671541Srgrimes 2681541Srgrimes if (ap->a_bp->b_vp == NULL || !chkvnlock(ap->a_bp->b_vp)) { 2691541Srgrimes ap->a_bp->b_flags |= B_ERROR; 2701541Srgrimes biodone(ap->a_bp); 2711541Srgrimes return (EIO); 2721541Srgrimes } 2731541Srgrimes return (VOP_STRATEGY(ap->a_bp)); 2741541Srgrimes} 2751541Srgrimes 2761541Srgrimes/* 2771541Srgrimes * Wait until the vnode has finished changing state. 2781541Srgrimes */ 2791549Srgrimesint 2801541Srgrimesdead_lock(ap) 2811541Srgrimes struct vop_lock_args /* { 2821541Srgrimes struct vnode *a_vp; 2831541Srgrimes } */ *ap; 2841541Srgrimes{ 2851541Srgrimes 2861541Srgrimes if (!chkvnlock(ap->a_vp)) 2871541Srgrimes return (0); 2881541Srgrimes return (VCALL(ap->a_vp, VOFFSET(vop_lock), ap)); 2891541Srgrimes} 2901541Srgrimes 2911541Srgrimes/* 2921541Srgrimes * Wait until the vnode has finished changing state. 2931541Srgrimes */ 2941549Srgrimesint 2951541Srgrimesdead_bmap(ap) 2961541Srgrimes struct vop_bmap_args /* { 2971541Srgrimes struct vnode *a_vp; 2981541Srgrimes daddr_t a_bn; 2991541Srgrimes struct vnode **a_vpp; 3001541Srgrimes daddr_t *a_bnp; 3011541Srgrimes int *a_runp; 3021541Srgrimes } */ *ap; 3031541Srgrimes{ 3041541Srgrimes 3051541Srgrimes if (!chkvnlock(ap->a_vp)) 3061541Srgrimes return (EIO); 3071541Srgrimes return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp, ap->a_runp)); 3081541Srgrimes} 3091541Srgrimes 3101541Srgrimes/* 3111541Srgrimes * Print out the contents of a dead vnode. 3121541Srgrimes */ 3131541Srgrimes/* ARGSUSED */ 3141549Srgrimesint 3151541Srgrimesdead_print(ap) 3161541Srgrimes struct vop_print_args /* { 3171541Srgrimes struct vnode *a_vp; 3181541Srgrimes } */ *ap; 3191541Srgrimes{ 3201541Srgrimes 3211541Srgrimes printf("tag VT_NON, dead vnode\n"); 3221549Srgrimes return (0); 3231541Srgrimes} 3241541Srgrimes 3251541Srgrimes/* 3261541Srgrimes * Empty vnode failed operation 3271541Srgrimes */ 3281549Srgrimesint 3291541Srgrimesdead_ebadf() 3301541Srgrimes{ 3311541Srgrimes 3321541Srgrimes return (EBADF); 3331541Srgrimes} 3341541Srgrimes 3351541Srgrimes/* 3361541Srgrimes * Empty vnode bad operation 3371541Srgrimes */ 3381549Srgrimesint 3391541Srgrimesdead_badop() 3401541Srgrimes{ 3411541Srgrimes 3421541Srgrimes panic("dead_badop called"); 3431541Srgrimes /* NOTREACHED */ 3441541Srgrimes} 3451541Srgrimes 3461541Srgrimes/* 3471541Srgrimes * Empty vnode null operation 3481541Srgrimes */ 3491549Srgrimesint 3501541Srgrimesdead_nullop() 3511541Srgrimes{ 3521541Srgrimes 3531541Srgrimes return (0); 3541541Srgrimes} 3551541Srgrimes 3561541Srgrimes/* 3571541Srgrimes * We have to wait during times when the vnode is 3581541Srgrimes * in a state of change. 3591541Srgrimes */ 3601549Srgrimesint 3611541Srgrimeschkvnlock(vp) 3621541Srgrimes register struct vnode *vp; 3631541Srgrimes{ 3641541Srgrimes int locked = 0; 3651541Srgrimes 3661541Srgrimes while (vp->v_flag & VXLOCK) { 3671541Srgrimes vp->v_flag |= VXWANT; 3683396Sdg (void) tsleep((caddr_t)vp, PINOD, "ckvnlk", 0); 3691541Srgrimes locked = 1; 3701541Srgrimes } 3711541Srgrimes return (locked); 3721541Srgrimes} 373