dead_vnops.c revision 76166
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 76166 2001-05-01 08:13:21Z markm $ 351541Srgrimes */ 361541Srgrimes 371541Srgrimes#include <sys/param.h> 381541Srgrimes#include <sys/systm.h> 392946Swollman#include <sys/kernel.h> 4031561Sbde#include <sys/lock.h> 4176166Smarkm#include <sys/mutex.h> 4276166Smarkm#include <sys/poll.h> 431541Srgrimes#include <sys/vnode.h> 441541Srgrimes 453442Sphkstatic int chkvnlock __P((struct vnode *)); 461541Srgrimes/* 471541Srgrimes * Prototypes for dead operations on vnodes. 481541Srgrimes */ 4912570Sphkstatic int dead_badop __P((void)); 5031727Swollmanstatic int dead_bmap __P((struct vop_bmap_args *)); 5131727Swollmanstatic int dead_ioctl __P((struct vop_ioctl_args *)); 5231727Swollmanstatic int dead_lock __P((struct vop_lock_args *)); 5312570Sphkstatic int dead_lookup __P((struct vop_lookup_args *)); 5412570Sphkstatic int dead_open __P((struct vop_open_args *)); 5531727Swollmanstatic int dead_poll __P((struct vop_poll_args *)); 5631727Swollmanstatic int dead_print __P((struct vop_print_args *)); 5712570Sphkstatic int dead_read __P((struct vop_read_args *)); 5812570Sphkstatic int dead_write __P((struct vop_write_args *)); 591541Srgrimes 6012158Sbdevop_t **dead_vnodeop_p; 6112570Sphkstatic struct vnodeopv_entry_desc dead_vnodeop_entries[] = { 6230743Sphk { &vop_default_desc, (vop_t *) vop_defaultop }, 6330743Sphk { &vop_access_desc, (vop_t *) vop_ebadf }, 6430743Sphk { &vop_advlock_desc, (vop_t *) vop_ebadf }, 6530431Sphk { &vop_bmap_desc, (vop_t *) dead_bmap }, 6630474Sphk { &vop_create_desc, (vop_t *) dead_badop }, 6730743Sphk { &vop_getattr_desc, (vop_t *) vop_ebadf }, 6830743Sphk { &vop_inactive_desc, (vop_t *) vop_null }, 6930431Sphk { &vop_ioctl_desc, (vop_t *) dead_ioctl }, 7030474Sphk { &vop_link_desc, (vop_t *) dead_badop }, 7130431Sphk { &vop_lock_desc, (vop_t *) dead_lock }, 7230431Sphk { &vop_lookup_desc, (vop_t *) dead_lookup }, 7330474Sphk { &vop_mkdir_desc, (vop_t *) dead_badop }, 7430474Sphk { &vop_mknod_desc, (vop_t *) dead_badop }, 7530431Sphk { &vop_open_desc, (vop_t *) dead_open }, 7630743Sphk { &vop_pathconf_desc, (vop_t *) vop_ebadf }, /* per pathconf(2) */ 7731727Swollman { &vop_poll_desc, (vop_t *) dead_poll }, 7830431Sphk { &vop_print_desc, (vop_t *) dead_print }, 7930431Sphk { &vop_read_desc, (vop_t *) dead_read }, 8030743Sphk { &vop_readdir_desc, (vop_t *) vop_ebadf }, 8130743Sphk { &vop_readlink_desc, (vop_t *) vop_ebadf }, 8230743Sphk { &vop_reclaim_desc, (vop_t *) vop_null }, 8330474Sphk { &vop_remove_desc, (vop_t *) dead_badop }, 8430474Sphk { &vop_rename_desc, (vop_t *) dead_badop }, 8530474Sphk { &vop_rmdir_desc, (vop_t *) dead_badop }, 8630743Sphk { &vop_setattr_desc, (vop_t *) vop_ebadf }, 8730474Sphk { &vop_symlink_desc, (vop_t *) dead_badop }, 8830431Sphk { &vop_write_desc, (vop_t *) dead_write }, 8912158Sbde { NULL, NULL } 901541Srgrimes}; 9112570Sphkstatic struct vnodeopv_desc dead_vnodeop_opv_desc = 921541Srgrimes { &dead_vnodeop_p, dead_vnodeop_entries }; 931541Srgrimes 942946SwollmanVNODEOP_SET(dead_vnodeop_opv_desc); 952946Swollman 961541Srgrimes/* 971541Srgrimes * Trivial lookup routine that always fails. 981541Srgrimes */ 991541Srgrimes/* ARGSUSED */ 10012570Sphkstatic int 1011541Srgrimesdead_lookup(ap) 1021541Srgrimes struct vop_lookup_args /* { 1031541Srgrimes struct vnode * a_dvp; 1041541Srgrimes struct vnode ** a_vpp; 1051541Srgrimes struct componentname * a_cnp; 1061541Srgrimes } */ *ap; 1071541Srgrimes{ 1081541Srgrimes 1091541Srgrimes *ap->a_vpp = NULL; 1101541Srgrimes return (ENOTDIR); 1111541Srgrimes} 1121541Srgrimes 1131541Srgrimes/* 1141541Srgrimes * Open always fails as if device did not exist. 1151541Srgrimes */ 1161541Srgrimes/* ARGSUSED */ 11712570Sphkstatic int 1181541Srgrimesdead_open(ap) 1191541Srgrimes struct vop_open_args /* { 1201541Srgrimes struct vnode *a_vp; 1211541Srgrimes int a_mode; 1221541Srgrimes struct ucred *a_cred; 1231541Srgrimes struct proc *a_p; 1241541Srgrimes } */ *ap; 1251541Srgrimes{ 1261541Srgrimes 1271541Srgrimes return (ENXIO); 1281541Srgrimes} 1291541Srgrimes 1301541Srgrimes/* 1311541Srgrimes * Vnode op for read 1321541Srgrimes */ 1331541Srgrimes/* ARGSUSED */ 13412570Sphkstatic int 1351541Srgrimesdead_read(ap) 1361541Srgrimes struct vop_read_args /* { 1371541Srgrimes struct vnode *a_vp; 1381541Srgrimes struct uio *a_uio; 1391541Srgrimes int a_ioflag; 1401541Srgrimes struct ucred *a_cred; 1411541Srgrimes } */ *ap; 1421541Srgrimes{ 1431541Srgrimes 1441541Srgrimes if (chkvnlock(ap->a_vp)) 1451541Srgrimes panic("dead_read: lock"); 1461541Srgrimes /* 14722521Sdyson * Return EOF for tty devices, EIO for others 14822521Sdyson */ 14922521Sdyson if ((ap->a_vp->v_flag & VISTTY) == 0) 15022521Sdyson return (EIO); 1511541Srgrimes return (0); 1521541Srgrimes} 1531541Srgrimes 1541541Srgrimes/* 1551541Srgrimes * Vnode op for write 1561541Srgrimes */ 1571541Srgrimes/* ARGSUSED */ 15812570Sphkstatic int 1591541Srgrimesdead_write(ap) 1601541Srgrimes struct vop_write_args /* { 1611541Srgrimes struct vnode *a_vp; 1621541Srgrimes struct uio *a_uio; 1631541Srgrimes int a_ioflag; 1641541Srgrimes struct ucred *a_cred; 1651541Srgrimes } */ *ap; 1661541Srgrimes{ 1671541Srgrimes 1681541Srgrimes if (chkvnlock(ap->a_vp)) 1691541Srgrimes panic("dead_write: lock"); 1701541Srgrimes return (EIO); 1711541Srgrimes} 1721541Srgrimes 1731541Srgrimes/* 1741541Srgrimes * Device ioctl operation. 1751541Srgrimes */ 1761541Srgrimes/* ARGSUSED */ 17712570Sphkstatic int 1781541Srgrimesdead_ioctl(ap) 1791541Srgrimes struct vop_ioctl_args /* { 1801541Srgrimes struct vnode *a_vp; 1811541Srgrimes int a_command; 1821541Srgrimes caddr_t a_data; 1831541Srgrimes int a_fflag; 1841541Srgrimes struct ucred *a_cred; 1851541Srgrimes struct proc *a_p; 1861541Srgrimes } */ *ap; 1871541Srgrimes{ 1881541Srgrimes 1891541Srgrimes if (!chkvnlock(ap->a_vp)) 19041287Sbde return (ENOTTY); 1911541Srgrimes return (VCALL(ap->a_vp, VOFFSET(vop_ioctl), ap)); 1921541Srgrimes} 1931541Srgrimes 1941541Srgrimes 1951541Srgrimes/* 1961541Srgrimes * Wait until the vnode has finished changing state. 1971541Srgrimes */ 19812570Sphkstatic int 1991541Srgrimesdead_lock(ap) 2001541Srgrimes struct vop_lock_args /* { 2011541Srgrimes struct vnode *a_vp; 20222521Sdyson int a_flags; 20322521Sdyson struct proc *a_p; 2041541Srgrimes } */ *ap; 2051541Srgrimes{ 20622521Sdyson struct vnode *vp = ap->a_vp; 2071541Srgrimes 20822521Sdyson /* 20922521Sdyson * Since we are not using the lock manager, we must clear 21022521Sdyson * the interlock here. 21122521Sdyson */ 21222521Sdyson if (ap->a_flags & LK_INTERLOCK) { 21372200Sbmilekic mtx_unlock(&vp->v_interlock); 21422521Sdyson ap->a_flags &= ~LK_INTERLOCK; 21522521Sdyson } 21622521Sdyson if (!chkvnlock(vp)) 2171541Srgrimes return (0); 21822521Sdyson return (VCALL(vp, VOFFSET(vop_lock), ap)); 2191541Srgrimes} 2201541Srgrimes 2211541Srgrimes/* 2221541Srgrimes * Wait until the vnode has finished changing state. 2231541Srgrimes */ 22412570Sphkstatic int 2251541Srgrimesdead_bmap(ap) 2261541Srgrimes struct vop_bmap_args /* { 2271541Srgrimes struct vnode *a_vp; 2281541Srgrimes daddr_t a_bn; 2291541Srgrimes struct vnode **a_vpp; 2301541Srgrimes daddr_t *a_bnp; 2311541Srgrimes int *a_runp; 23210551Sdyson int *a_runb; 2331541Srgrimes } */ *ap; 2341541Srgrimes{ 2351541Srgrimes 2361541Srgrimes if (!chkvnlock(ap->a_vp)) 2371541Srgrimes return (EIO); 23810551Sdyson return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp, ap->a_runp, ap->a_runb)); 2391541Srgrimes} 2401541Srgrimes 2411541Srgrimes/* 2421541Srgrimes * Print out the contents of a dead vnode. 2431541Srgrimes */ 2441541Srgrimes/* ARGSUSED */ 24512570Sphkstatic int 2461541Srgrimesdead_print(ap) 2471541Srgrimes struct vop_print_args /* { 2481541Srgrimes struct vnode *a_vp; 2491541Srgrimes } */ *ap; 2501541Srgrimes{ 2511541Srgrimes 2521541Srgrimes printf("tag VT_NON, dead vnode\n"); 2531549Srgrimes return (0); 2541541Srgrimes} 2551541Srgrimes 2561541Srgrimes/* 2571541Srgrimes * Empty vnode bad operation 2581541Srgrimes */ 25912570Sphkstatic int 2601541Srgrimesdead_badop() 2611541Srgrimes{ 2621541Srgrimes 2631541Srgrimes panic("dead_badop called"); 2641541Srgrimes /* NOTREACHED */ 2651541Srgrimes} 2661541Srgrimes 2671541Srgrimes/* 2681541Srgrimes * We have to wait during times when the vnode is 2691541Srgrimes * in a state of change. 2701541Srgrimes */ 2711549Srgrimesint 2721541Srgrimeschkvnlock(vp) 2731541Srgrimes register struct vnode *vp; 2741541Srgrimes{ 2751541Srgrimes int locked = 0; 2761541Srgrimes 2771541Srgrimes while (vp->v_flag & VXLOCK) { 2781541Srgrimes vp->v_flag |= VXWANT; 2793396Sdg (void) tsleep((caddr_t)vp, PINOD, "ckvnlk", 0); 2801541Srgrimes locked = 1; 2811541Srgrimes } 2821541Srgrimes return (locked); 2831541Srgrimes} 28431727Swollman 28531727Swollman/* 28631727Swollman * Trivial poll routine that always returns POLLHUP. 28731727Swollman * This is necessary so that a process which is polling a file 28831727Swollman * gets notified when that file is revoke()d. 28931727Swollman */ 29031727Swollmanstatic int 29131727Swollmandead_poll(ap) 29231727Swollman struct vop_poll_args *ap; 29331727Swollman{ 29431727Swollman return (POLLHUP); 29531727Swollman} 296