dead_vnops.c revision 72200
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 3450477Speter * $FreeBSD: head/sys/fs/deadfs/dead_vnops.c 72200 2001-02-09 06:11:45Z bmilekic $ 351541Srgrimes */ 361541Srgrimes 371541Srgrimes#include <sys/param.h> 381541Srgrimes#include <sys/systm.h> 392946Swollman#include <sys/kernel.h> 4031561Sbde#include <sys/lock.h> 411541Srgrimes#include <sys/vnode.h> 4231727Swollman#include <sys/poll.h> 431541Srgrimes 4466615Sjasone#include <machine/mutex.h> 4566615Sjasone 463442Sphkstatic int chkvnlock __P((struct vnode *)); 471541Srgrimes/* 481541Srgrimes * Prototypes for dead operations on vnodes. 491541Srgrimes */ 5012570Sphkstatic int dead_badop __P((void)); 5131727Swollmanstatic int dead_bmap __P((struct vop_bmap_args *)); 5231727Swollmanstatic int dead_ioctl __P((struct vop_ioctl_args *)); 5331727Swollmanstatic int dead_lock __P((struct vop_lock_args *)); 5412570Sphkstatic int dead_lookup __P((struct vop_lookup_args *)); 5512570Sphkstatic int dead_open __P((struct vop_open_args *)); 5631727Swollmanstatic int dead_poll __P((struct vop_poll_args *)); 5731727Swollmanstatic int dead_print __P((struct vop_print_args *)); 5812570Sphkstatic int dead_read __P((struct vop_read_args *)); 5912570Sphkstatic int dead_write __P((struct vop_write_args *)); 601541Srgrimes 6112158Sbdevop_t **dead_vnodeop_p; 6212570Sphkstatic struct vnodeopv_entry_desc dead_vnodeop_entries[] = { 6330743Sphk { &vop_default_desc, (vop_t *) vop_defaultop }, 6430743Sphk { &vop_access_desc, (vop_t *) vop_ebadf }, 6530743Sphk { &vop_advlock_desc, (vop_t *) vop_ebadf }, 6630431Sphk { &vop_bmap_desc, (vop_t *) dead_bmap }, 6730474Sphk { &vop_create_desc, (vop_t *) dead_badop }, 6830743Sphk { &vop_getattr_desc, (vop_t *) vop_ebadf }, 6930743Sphk { &vop_inactive_desc, (vop_t *) vop_null }, 7030431Sphk { &vop_ioctl_desc, (vop_t *) dead_ioctl }, 7130474Sphk { &vop_link_desc, (vop_t *) dead_badop }, 7230431Sphk { &vop_lock_desc, (vop_t *) dead_lock }, 7330431Sphk { &vop_lookup_desc, (vop_t *) dead_lookup }, 7430474Sphk { &vop_mkdir_desc, (vop_t *) dead_badop }, 7530474Sphk { &vop_mknod_desc, (vop_t *) dead_badop }, 7630431Sphk { &vop_open_desc, (vop_t *) dead_open }, 7730743Sphk { &vop_pathconf_desc, (vop_t *) vop_ebadf }, /* per pathconf(2) */ 7831727Swollman { &vop_poll_desc, (vop_t *) dead_poll }, 7930431Sphk { &vop_print_desc, (vop_t *) dead_print }, 8030431Sphk { &vop_read_desc, (vop_t *) dead_read }, 8130743Sphk { &vop_readdir_desc, (vop_t *) vop_ebadf }, 8230743Sphk { &vop_readlink_desc, (vop_t *) vop_ebadf }, 8330743Sphk { &vop_reclaim_desc, (vop_t *) vop_null }, 8430474Sphk { &vop_remove_desc, (vop_t *) dead_badop }, 8530474Sphk { &vop_rename_desc, (vop_t *) dead_badop }, 8630474Sphk { &vop_rmdir_desc, (vop_t *) dead_badop }, 8730743Sphk { &vop_setattr_desc, (vop_t *) vop_ebadf }, 8830474Sphk { &vop_symlink_desc, (vop_t *) dead_badop }, 8930431Sphk { &vop_write_desc, (vop_t *) dead_write }, 9012158Sbde { NULL, NULL } 911541Srgrimes}; 9212570Sphkstatic struct vnodeopv_desc dead_vnodeop_opv_desc = 931541Srgrimes { &dead_vnodeop_p, dead_vnodeop_entries }; 941541Srgrimes 952946SwollmanVNODEOP_SET(dead_vnodeop_opv_desc); 962946Swollman 971541Srgrimes/* 981541Srgrimes * Trivial lookup routine that always fails. 991541Srgrimes */ 1001541Srgrimes/* ARGSUSED */ 10112570Sphkstatic int 1021541Srgrimesdead_lookup(ap) 1031541Srgrimes struct vop_lookup_args /* { 1041541Srgrimes struct vnode * a_dvp; 1051541Srgrimes struct vnode ** a_vpp; 1061541Srgrimes struct componentname * a_cnp; 1071541Srgrimes } */ *ap; 1081541Srgrimes{ 1091541Srgrimes 1101541Srgrimes *ap->a_vpp = NULL; 1111541Srgrimes return (ENOTDIR); 1121541Srgrimes} 1131541Srgrimes 1141541Srgrimes/* 1151541Srgrimes * Open always fails as if device did not exist. 1161541Srgrimes */ 1171541Srgrimes/* ARGSUSED */ 11812570Sphkstatic int 1191541Srgrimesdead_open(ap) 1201541Srgrimes struct vop_open_args /* { 1211541Srgrimes struct vnode *a_vp; 1221541Srgrimes int a_mode; 1231541Srgrimes struct ucred *a_cred; 1241541Srgrimes struct proc *a_p; 1251541Srgrimes } */ *ap; 1261541Srgrimes{ 1271541Srgrimes 1281541Srgrimes return (ENXIO); 1291541Srgrimes} 1301541Srgrimes 1311541Srgrimes/* 1321541Srgrimes * Vnode op for read 1331541Srgrimes */ 1341541Srgrimes/* ARGSUSED */ 13512570Sphkstatic int 1361541Srgrimesdead_read(ap) 1371541Srgrimes struct vop_read_args /* { 1381541Srgrimes struct vnode *a_vp; 1391541Srgrimes struct uio *a_uio; 1401541Srgrimes int a_ioflag; 1411541Srgrimes struct ucred *a_cred; 1421541Srgrimes } */ *ap; 1431541Srgrimes{ 1441541Srgrimes 1451541Srgrimes if (chkvnlock(ap->a_vp)) 1461541Srgrimes panic("dead_read: lock"); 1471541Srgrimes /* 14822521Sdyson * Return EOF for tty devices, EIO for others 14922521Sdyson */ 15022521Sdyson if ((ap->a_vp->v_flag & VISTTY) == 0) 15122521Sdyson return (EIO); 1521541Srgrimes return (0); 1531541Srgrimes} 1541541Srgrimes 1551541Srgrimes/* 1561541Srgrimes * Vnode op for write 1571541Srgrimes */ 1581541Srgrimes/* ARGSUSED */ 15912570Sphkstatic int 1601541Srgrimesdead_write(ap) 1611541Srgrimes struct vop_write_args /* { 1621541Srgrimes struct vnode *a_vp; 1631541Srgrimes struct uio *a_uio; 1641541Srgrimes int a_ioflag; 1651541Srgrimes struct ucred *a_cred; 1661541Srgrimes } */ *ap; 1671541Srgrimes{ 1681541Srgrimes 1691541Srgrimes if (chkvnlock(ap->a_vp)) 1701541Srgrimes panic("dead_write: lock"); 1711541Srgrimes return (EIO); 1721541Srgrimes} 1731541Srgrimes 1741541Srgrimes/* 1751541Srgrimes * Device ioctl operation. 1761541Srgrimes */ 1771541Srgrimes/* ARGSUSED */ 17812570Sphkstatic int 1791541Srgrimesdead_ioctl(ap) 1801541Srgrimes struct vop_ioctl_args /* { 1811541Srgrimes struct vnode *a_vp; 1821541Srgrimes int a_command; 1831541Srgrimes caddr_t a_data; 1841541Srgrimes int a_fflag; 1851541Srgrimes struct ucred *a_cred; 1861541Srgrimes struct proc *a_p; 1871541Srgrimes } */ *ap; 1881541Srgrimes{ 1891541Srgrimes 1901541Srgrimes if (!chkvnlock(ap->a_vp)) 19141287Sbde return (ENOTTY); 1921541Srgrimes return (VCALL(ap->a_vp, VOFFSET(vop_ioctl), ap)); 1931541Srgrimes} 1941541Srgrimes 1951541Srgrimes 1961541Srgrimes/* 1971541Srgrimes * Wait until the vnode has finished changing state. 1981541Srgrimes */ 19912570Sphkstatic int 2001541Srgrimesdead_lock(ap) 2011541Srgrimes struct vop_lock_args /* { 2021541Srgrimes struct vnode *a_vp; 20322521Sdyson int a_flags; 20422521Sdyson struct proc *a_p; 2051541Srgrimes } */ *ap; 2061541Srgrimes{ 20722521Sdyson struct vnode *vp = ap->a_vp; 2081541Srgrimes 20922521Sdyson /* 21022521Sdyson * Since we are not using the lock manager, we must clear 21122521Sdyson * the interlock here. 21222521Sdyson */ 21322521Sdyson if (ap->a_flags & LK_INTERLOCK) { 21472200Sbmilekic mtx_unlock(&vp->v_interlock); 21522521Sdyson ap->a_flags &= ~LK_INTERLOCK; 21622521Sdyson } 21722521Sdyson if (!chkvnlock(vp)) 2181541Srgrimes return (0); 21922521Sdyson return (VCALL(vp, VOFFSET(vop_lock), ap)); 2201541Srgrimes} 2211541Srgrimes 2221541Srgrimes/* 2231541Srgrimes * Wait until the vnode has finished changing state. 2241541Srgrimes */ 22512570Sphkstatic int 2261541Srgrimesdead_bmap(ap) 2271541Srgrimes struct vop_bmap_args /* { 2281541Srgrimes struct vnode *a_vp; 2291541Srgrimes daddr_t a_bn; 2301541Srgrimes struct vnode **a_vpp; 2311541Srgrimes daddr_t *a_bnp; 2321541Srgrimes int *a_runp; 23310551Sdyson int *a_runb; 2341541Srgrimes } */ *ap; 2351541Srgrimes{ 2361541Srgrimes 2371541Srgrimes if (!chkvnlock(ap->a_vp)) 2381541Srgrimes return (EIO); 23910551Sdyson return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp, ap->a_runp, ap->a_runb)); 2401541Srgrimes} 2411541Srgrimes 2421541Srgrimes/* 2431541Srgrimes * Print out the contents of a dead vnode. 2441541Srgrimes */ 2451541Srgrimes/* ARGSUSED */ 24612570Sphkstatic int 2471541Srgrimesdead_print(ap) 2481541Srgrimes struct vop_print_args /* { 2491541Srgrimes struct vnode *a_vp; 2501541Srgrimes } */ *ap; 2511541Srgrimes{ 2521541Srgrimes 2531541Srgrimes printf("tag VT_NON, dead vnode\n"); 2541549Srgrimes return (0); 2551541Srgrimes} 2561541Srgrimes 2571541Srgrimes/* 2581541Srgrimes * Empty vnode bad operation 2591541Srgrimes */ 26012570Sphkstatic int 2611541Srgrimesdead_badop() 2621541Srgrimes{ 2631541Srgrimes 2641541Srgrimes panic("dead_badop called"); 2651541Srgrimes /* NOTREACHED */ 2661541Srgrimes} 2671541Srgrimes 2681541Srgrimes/* 2691541Srgrimes * We have to wait during times when the vnode is 2701541Srgrimes * in a state of change. 2711541Srgrimes */ 2721549Srgrimesint 2731541Srgrimeschkvnlock(vp) 2741541Srgrimes register struct vnode *vp; 2751541Srgrimes{ 2761541Srgrimes int locked = 0; 2771541Srgrimes 2781541Srgrimes while (vp->v_flag & VXLOCK) { 2791541Srgrimes vp->v_flag |= VXWANT; 2803396Sdg (void) tsleep((caddr_t)vp, PINOD, "ckvnlk", 0); 2811541Srgrimes locked = 1; 2821541Srgrimes } 2831541Srgrimes return (locked); 2841541Srgrimes} 28531727Swollman 28631727Swollman/* 28731727Swollman * Trivial poll routine that always returns POLLHUP. 28831727Swollman * This is necessary so that a process which is polling a file 28931727Swollman * gets notified when that file is revoke()d. 29031727Swollman */ 29131727Swollmanstatic int 29231727Swollmandead_poll(ap) 29331727Swollman struct vop_poll_args *ap; 29431727Swollman{ 29531727Swollman return (POLLHUP); 29631727Swollman} 297