139483Smckusick /* 239483Smckusick * Copyright (c) 1989 The Regents of the University of California. 339483Smckusick * All rights reserved. 439483Smckusick * 544429Sbostic * %sccs.include.redist.c% 639483Smckusick * 7*52303Sheideman * @(#)dead_vnops.c 7.15 (Berkeley) 02/03/92 839483Smckusick */ 939483Smckusick 1039483Smckusick #include "param.h" 1148012Smckusick #include "systm.h" 1239483Smckusick #include "time.h" 1339483Smckusick #include "vnode.h" 1439483Smckusick #include "errno.h" 1539483Smckusick #include "namei.h" 1639483Smckusick #include "buf.h" 1739483Smckusick 1848012Smckusick /* 1948012Smckusick * Prototypes for dead operations on vnodes. 2048012Smckusick */ 2148012Smckusick int dead_badop(), 2248012Smckusick dead_ebadf(); 2348012Smckusick int dead_lookup __P(( 24*52303Sheideman struct vnode *dvp, 25*52303Sheideman struct vnode **vpp, 26*52303Sheideman struct componentname *cnp)); 2748012Smckusick #define dead_create ((int (*) __P(( \ 28*52303Sheideman struct vnode *dvp, \ 29*52303Sheideman struct vnode **vpp, \ 30*52303Sheideman struct componentname *cnp, \ 31*52303Sheideman struct vattr *vap))) dead_badop) 3248012Smckusick #define dead_mknod ((int (*) __P(( \ 33*52303Sheideman struct vnode *dvp, \ 34*52303Sheideman struct vnode **vpp, \ 35*52303Sheideman struct componentname *cnp, \ 36*52303Sheideman struct vattr *vap))) dead_badop) 3748012Smckusick int dead_open __P(( 3848012Smckusick struct vnode *vp, 3948012Smckusick int mode, 4048012Smckusick struct ucred *cred, 4148012Smckusick struct proc *p)); 4248012Smckusick #define dead_close ((int (*) __P(( \ 4348012Smckusick struct vnode *vp, \ 4448012Smckusick int fflag, \ 4548012Smckusick struct ucred *cred, \ 4648012Smckusick struct proc *p))) nullop) 4748012Smckusick #define dead_access ((int (*) __P(( \ 4848012Smckusick struct vnode *vp, \ 4948012Smckusick int mode, \ 5048012Smckusick struct ucred *cred, \ 5148012Smckusick struct proc *p))) dead_ebadf) 5248012Smckusick #define dead_getattr ((int (*) __P(( \ 5348012Smckusick struct vnode *vp, \ 5448012Smckusick struct vattr *vap, \ 5548012Smckusick struct ucred *cred, \ 5648012Smckusick struct proc *p))) dead_ebadf) 5748012Smckusick #define dead_setattr ((int (*) __P(( \ 5848012Smckusick struct vnode *vp, \ 5948012Smckusick struct vattr *vap, \ 6048012Smckusick struct ucred *cred, \ 6148012Smckusick struct proc *p))) dead_ebadf) 6248012Smckusick int dead_read __P(( 6348012Smckusick struct vnode *vp, 6448012Smckusick struct uio *uio, 6548012Smckusick int ioflag, 6648012Smckusick struct ucred *cred)); 6748012Smckusick int dead_write __P(( 6848012Smckusick struct vnode *vp, 6948012Smckusick struct uio *uio, 7048012Smckusick int ioflag, 7148012Smckusick struct ucred *cred)); 7248012Smckusick int dead_ioctl __P(( 7348012Smckusick struct vnode *vp, 7448012Smckusick int command, 7548012Smckusick caddr_t data, 7648012Smckusick int fflag, 7748012Smckusick struct ucred *cred, 7848012Smckusick struct proc *p)); 7948012Smckusick int dead_select __P(( 8048012Smckusick struct vnode *vp, 8148012Smckusick int which, 8248012Smckusick int fflags, 8348012Smckusick struct ucred *cred, 8448012Smckusick struct proc *p)); 8548012Smckusick #define dead_mmap ((int (*) __P(( \ 8648012Smckusick struct vnode *vp, \ 8748012Smckusick int fflags, \ 8848012Smckusick struct ucred *cred, \ 8948012Smckusick struct proc *p))) dead_badop) 9048012Smckusick #define dead_fsync ((int (*) __P(( \ 9148012Smckusick struct vnode *vp, \ 9248012Smckusick int fflags, \ 9348012Smckusick struct ucred *cred, \ 9448012Smckusick int waitfor, \ 9548012Smckusick struct proc *p))) nullop) 9648012Smckusick #define dead_seek ((int (*) __P(( \ 9748012Smckusick struct vnode *vp, \ 9848012Smckusick off_t oldoff, \ 9948012Smckusick off_t newoff, \ 10048012Smckusick struct ucred *cred))) nullop) 10148012Smckusick #define dead_remove ((int (*) __P(( \ 102*52303Sheideman struct vnode *dvp, \ 103*52303Sheideman struct vnode *vp, \ 104*52303Sheideman struct componentname *cnp))) dead_badop) 10548012Smckusick #define dead_link ((int (*) __P(( \ 106*52303Sheideman register struct vnode *vp, \ 107*52303Sheideman struct vnode *tdvp, \ 108*52303Sheideman struct componentname *cnp))) dead_badop) 10948012Smckusick #define dead_rename ((int (*) __P(( \ 110*52303Sheideman struct vnode *fdvp, \ 111*52303Sheideman struct vnode *fvp, \ 112*52303Sheideman struct componentname *fcnp, \ 113*52303Sheideman struct vnode *tdvp, \ 114*52303Sheideman struct vnode *tvp, \ 115*52303Sheideman struct componentname *tcnp))) dead_badop) 11648012Smckusick #define dead_mkdir ((int (*) __P(( \ 117*52303Sheideman struct vnode *dvp, \ 118*52303Sheideman struct vnode **vpp, \ 119*52303Sheideman struct componentname *cnp, \ 120*52303Sheideman struct vattr *vap))) dead_badop) 12148012Smckusick #define dead_rmdir ((int (*) __P(( \ 122*52303Sheideman struct vnode *dvp, \ 123*52303Sheideman struct vnode *vp, \ 124*52303Sheideman struct componentname *cnp))) dead_badop) 12548012Smckusick #define dead_symlink ((int (*) __P(( \ 126*52303Sheideman struct vnode *dvp, \ 127*52303Sheideman struct vnode **vpp, \ 128*52303Sheideman struct componentname *cnp, \ 12948012Smckusick struct vattr *vap, \ 130*52303Sheideman char *target))) dead_badop) 13148012Smckusick #define dead_readdir ((int (*) __P(( \ 13248012Smckusick struct vnode *vp, \ 13348012Smckusick struct uio *uio, \ 13448012Smckusick struct ucred *cred, \ 13548012Smckusick int *eofflagp))) dead_ebadf) 13648012Smckusick #define dead_readlink ((int (*) __P(( \ 13748012Smckusick struct vnode *vp, \ 13848012Smckusick struct uio *uio, \ 13948012Smckusick struct ucred *cred))) dead_ebadf) 14048012Smckusick #define dead_abortop ((int (*) __P(( \ 141*52303Sheideman struct vnode *dvp, \ 142*52303Sheideman struct componentname *cnp))) dead_badop) 14348012Smckusick #define dead_inactive ((int (*) __P(( \ 14448012Smckusick struct vnode *vp, \ 14548012Smckusick struct proc *p))) nullop) 14648012Smckusick #define dead_reclaim ((int (*) __P(( \ 14748012Smckusick struct vnode *vp))) nullop) 14848012Smckusick int dead_lock __P(( 14948012Smckusick struct vnode *vp)); 15048012Smckusick #define dead_unlock ((int (*) __P(( \ 15148012Smckusick struct vnode *vp))) nullop) 15248012Smckusick int dead_bmap __P(( 15348012Smckusick struct vnode *vp, 15448012Smckusick daddr_t bn, 15548012Smckusick struct vnode **vpp, 15648012Smckusick daddr_t *bnp)); 15748012Smckusick int dead_strategy __P(( 15848012Smckusick struct buf *bp)); 15948012Smckusick int dead_print __P(( 16048012Smckusick struct vnode *vp)); 16148012Smckusick #define dead_islocked ((int (*) __P(( \ 16248012Smckusick struct vnode *vp))) nullop) 16348012Smckusick #define dead_advlock ((int (*) __P(( \ 16448012Smckusick struct vnode *vp, \ 16548012Smckusick caddr_t id, \ 16648012Smckusick int op, \ 16748012Smckusick struct flock *fl, \ 16848012Smckusick int flags))) dead_ebadf) 16951565Smckusick #define dead_blkatoff ((int (*) __P(( \ 17051565Smckusick struct vnode *vp, \ 17151565Smckusick off_t offset, \ 17251565Smckusick char **res, \ 17351565Smckusick struct buf **bpp))) dead_badop) 17451565Smckusick #define dead_vget ((int (*) __P(( \ 17551565Smckusick struct mount *mp, \ 17651565Smckusick ino_t ino, \ 17751565Smckusick struct vnode **vpp))) dead_badop) 17851565Smckusick #define dead_valloc ((int (*) __P(( \ 17951565Smckusick struct vnode *pvp, \ 18051565Smckusick int mode, \ 18151565Smckusick struct ucred *cred, \ 18251565Smckusick struct vnode **vpp))) dead_badop) 18351565Smckusick #define dead_vfree ((void (*) __P(( \ 18451565Smckusick struct vnode *pvp, \ 18551565Smckusick ino_t ino, \ 18651565Smckusick int mode))) dead_badop) 18751565Smckusick #define dead_truncate ((int (*) __P(( \ 18851565Smckusick struct vnode *vp, \ 18951565Smckusick u_long length, \ 19051565Smckusick int flags))) nullop) 19151565Smckusick #define dead_update ((int (*) __P(( \ 19251565Smckusick struct vnode *vp, \ 19351565Smckusick struct timeval *ta, \ 19451565Smckusick struct timeval *tm, \ 19551565Smckusick int waitfor))) nullop) 19651565Smckusick #define dead_bwrite ((int (*) __P(( \ 19751565Smckusick struct buf *bp))) nullop) 19839483Smckusick 19939483Smckusick struct vnodeops dead_vnodeops = { 20039483Smckusick dead_lookup, /* lookup */ 20148012Smckusick dead_create, /* create */ 20248012Smckusick dead_mknod, /* mknod */ 20339483Smckusick dead_open, /* open */ 20448012Smckusick dead_close, /* close */ 20548012Smckusick dead_access, /* access */ 20648012Smckusick dead_getattr, /* getattr */ 20748012Smckusick dead_setattr, /* setattr */ 20839483Smckusick dead_read, /* read */ 20939483Smckusick dead_write, /* write */ 21039483Smckusick dead_ioctl, /* ioctl */ 21139483Smckusick dead_select, /* select */ 21248012Smckusick dead_mmap, /* mmap */ 21348012Smckusick dead_fsync, /* fsync */ 21448012Smckusick dead_seek, /* seek */ 21548012Smckusick dead_remove, /* remove */ 21648012Smckusick dead_link, /* link */ 21748012Smckusick dead_rename, /* rename */ 21848012Smckusick dead_mkdir, /* mkdir */ 21948012Smckusick dead_rmdir, /* rmdir */ 22048012Smckusick dead_symlink, /* symlink */ 22148012Smckusick dead_readdir, /* readdir */ 22248012Smckusick dead_readlink, /* readlink */ 22348012Smckusick dead_abortop, /* abortop */ 22448012Smckusick dead_inactive, /* inactive */ 22548012Smckusick dead_reclaim, /* reclaim */ 22639483Smckusick dead_lock, /* lock */ 22748012Smckusick dead_unlock, /* unlock */ 22839508Smckusick dead_bmap, /* bmap */ 22939483Smckusick dead_strategy, /* strategy */ 23039911Smckusick dead_print, /* print */ 23148012Smckusick dead_islocked, /* islocked */ 23248012Smckusick dead_advlock, /* advlock */ 23351565Smckusick dead_blkatoff, /* blkatoff */ 23451565Smckusick dead_vget, /* vget */ 23551565Smckusick dead_valloc, /* valloc */ 23651565Smckusick dead_vfree, /* vfree */ 23751565Smckusick dead_truncate, /* truncate */ 23851565Smckusick dead_update, /* update */ 23951565Smckusick dead_bwrite, /* bwrite */ 24039483Smckusick }; 24139483Smckusick 24239483Smckusick /* 24339483Smckusick * Trivial lookup routine that always fails. 24439483Smckusick */ 24548012Smckusick /* ARGSUSED */ 246*52303Sheideman int 247*52303Sheideman dead_lookup(dvp, vpp, cnp) 248*52303Sheideman struct vnode *dvp; 249*52303Sheideman struct vnode **vpp; 250*52303Sheideman struct componentname *cnp; 25139483Smckusick { 25239483Smckusick 253*52303Sheideman *vpp = NULL; 25439483Smckusick return (ENOTDIR); 25539483Smckusick } 25639483Smckusick 25739483Smckusick /* 25839483Smckusick * Open always fails as if device did not exist. 25939483Smckusick */ 26039483Smckusick /* ARGSUSED */ 26148012Smckusick dead_open(vp, mode, cred, p) 26239483Smckusick struct vnode *vp; 26339483Smckusick int mode; 26439483Smckusick struct ucred *cred; 26548012Smckusick struct proc *p; 26639483Smckusick { 26739483Smckusick 26839483Smckusick return (ENXIO); 26939483Smckusick } 27039483Smckusick 27139483Smckusick /* 27239483Smckusick * Vnode op for read 27339483Smckusick */ 27439591Smckusick /* ARGSUSED */ 27539591Smckusick dead_read(vp, uio, ioflag, cred) 27639483Smckusick struct vnode *vp; 27739483Smckusick struct uio *uio; 27839483Smckusick int ioflag; 27939483Smckusick struct ucred *cred; 28039483Smckusick { 28139483Smckusick 28239591Smckusick if (chkvnlock(vp)) 28339591Smckusick panic("dead_read: lock"); 28439591Smckusick /* 28539591Smckusick * Return EOF for character devices, EIO for others 28639591Smckusick */ 28739591Smckusick if (vp->v_type != VCHR) 28839483Smckusick return (EIO); 28939591Smckusick return (0); 29039483Smckusick } 29139483Smckusick 29239483Smckusick /* 29339483Smckusick * Vnode op for write 29439483Smckusick */ 29539591Smckusick /* ARGSUSED */ 29639591Smckusick dead_write(vp, uio, ioflag, cred) 29739483Smckusick register struct vnode *vp; 29839483Smckusick struct uio *uio; 29939483Smckusick int ioflag; 30039483Smckusick struct ucred *cred; 30139483Smckusick { 30239483Smckusick 30339591Smckusick if (chkvnlock(vp)) 30439591Smckusick panic("dead_write: lock"); 30539591Smckusick return (EIO); 30639483Smckusick } 30739483Smckusick 30839483Smckusick /* 30939483Smckusick * Device ioctl operation. 31039483Smckusick */ 31139483Smckusick /* ARGSUSED */ 31248012Smckusick dead_ioctl(vp, com, data, fflag, cred, p) 31339483Smckusick struct vnode *vp; 31439483Smckusick register int com; 31539483Smckusick caddr_t data; 31639483Smckusick int fflag; 31739483Smckusick struct ucred *cred; 31848012Smckusick struct proc *p; 31939483Smckusick { 32039483Smckusick 32139519Smckusick if (!chkvnlock(vp)) 32239483Smckusick return (EBADF); 32348012Smckusick return (VOP_IOCTL(vp, com, data, fflag, cred, p)); 32439483Smckusick } 32539483Smckusick 32639483Smckusick /* ARGSUSED */ 32748012Smckusick dead_select(vp, which, fflags, cred, p) 32839483Smckusick struct vnode *vp; 32940188Smckusick int which, fflags; 33039483Smckusick struct ucred *cred; 33148012Smckusick struct proc *p; 33239483Smckusick { 33339483Smckusick 33439483Smckusick /* 33539483Smckusick * Let the user find out that the descriptor is gone. 33639483Smckusick */ 33739483Smckusick return (1); 33839483Smckusick } 33939483Smckusick 34039483Smckusick /* 34139483Smckusick * Just call the device strategy routine 34239483Smckusick */ 34339483Smckusick dead_strategy(bp) 34439483Smckusick register struct buf *bp; 34539483Smckusick { 34639483Smckusick 34739519Smckusick if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) { 34839518Smckusick bp->b_flags |= B_ERROR; 34939853Smckusick biodone(bp); 35039483Smckusick return (EIO); 35139518Smckusick } 35239483Smckusick return (VOP_STRATEGY(bp)); 35339483Smckusick } 35439483Smckusick 35539483Smckusick /* 35639483Smckusick * Wait until the vnode has finished changing state. 35739483Smckusick */ 35839483Smckusick dead_lock(vp) 35939483Smckusick struct vnode *vp; 36039483Smckusick { 36139483Smckusick 36239519Smckusick if (!chkvnlock(vp)) 36339483Smckusick return (0); 36439483Smckusick return (VOP_LOCK(vp)); 36539483Smckusick } 36639483Smckusick 36739483Smckusick /* 36839508Smckusick * Wait until the vnode has finished changing state. 36939508Smckusick */ 37039508Smckusick dead_bmap(vp, bn, vpp, bnp) 37139508Smckusick struct vnode *vp; 37239508Smckusick daddr_t bn; 37339508Smckusick struct vnode **vpp; 37439508Smckusick daddr_t *bnp; 37539508Smckusick { 37639508Smckusick 37739519Smckusick if (!chkvnlock(vp)) 37839508Smckusick return (EIO); 37939508Smckusick return (VOP_BMAP(vp, bn, vpp, bnp)); 38039508Smckusick } 38139508Smckusick 38239508Smckusick /* 38339911Smckusick * Print out the contents of a dead vnode. 38439911Smckusick */ 38545110Smckusick /* ARGSUSED */ 38639911Smckusick dead_print(vp) 38739911Smckusick struct vnode *vp; 38839911Smckusick { 38939911Smckusick 39039911Smckusick printf("tag VT_NON, dead vnode\n"); 39139911Smckusick } 39239911Smckusick 39339911Smckusick /* 39439486Smckusick * Empty vnode failed operation 39539486Smckusick */ 39639486Smckusick dead_ebadf() 39739486Smckusick { 39839486Smckusick 39939486Smckusick return (EBADF); 40039486Smckusick } 40139486Smckusick 40239486Smckusick /* 40339483Smckusick * Empty vnode bad operation 40439483Smckusick */ 40539483Smckusick dead_badop() 40639483Smckusick { 40739483Smckusick 40839483Smckusick panic("dead_badop called"); 40939483Smckusick /* NOTREACHED */ 41039483Smckusick } 41139483Smckusick 41239483Smckusick /* 41339483Smckusick * Empty vnode null operation 41439483Smckusick */ 41539483Smckusick dead_nullop() 41639483Smckusick { 41739483Smckusick 41839483Smckusick return (0); 41939483Smckusick } 42039519Smckusick 42139519Smckusick /* 42239519Smckusick * We have to wait during times when the vnode is 42339519Smckusick * in a state of change. 42439519Smckusick */ 42539519Smckusick chkvnlock(vp) 42639519Smckusick register struct vnode *vp; 42739519Smckusick { 42839519Smckusick int locked = 0; 42939519Smckusick 43039519Smckusick while (vp->v_flag & VXLOCK) { 43139519Smckusick vp->v_flag |= VXWANT; 43239519Smckusick sleep((caddr_t)vp, PINOD); 43339519Smckusick locked = 1; 43439519Smckusick } 43539519Smckusick return (locked); 43639519Smckusick } 437