139483Smckusick /* 239483Smckusick * Copyright (c) 1989 The Regents of the University of California. 339483Smckusick * All rights reserved. 439483Smckusick * 544429Sbostic * %sccs.include.redist.c% 639483Smckusick * 7*48012Smckusick * @(#)dead_vnops.c 7.13 (Berkeley) 04/15/91 839483Smckusick */ 939483Smckusick 1039483Smckusick #include "param.h" 11*48012Smckusick #include "systm.h" 1239483Smckusick #include "time.h" 1339483Smckusick #include "vnode.h" 1439483Smckusick #include "errno.h" 1539483Smckusick #include "namei.h" 1639483Smckusick #include "buf.h" 1739483Smckusick 18*48012Smckusick /* 19*48012Smckusick * Prototypes for dead operations on vnodes. 20*48012Smckusick */ 21*48012Smckusick int dead_badop(), 22*48012Smckusick dead_ebadf(); 23*48012Smckusick int dead_lookup __P(( 24*48012Smckusick struct vnode *vp, 25*48012Smckusick struct nameidata *ndp, 26*48012Smckusick struct proc *p)); 27*48012Smckusick #define dead_create ((int (*) __P(( \ 28*48012Smckusick struct nameidata *ndp, \ 29*48012Smckusick struct vattr *vap, \ 30*48012Smckusick struct proc *p))) dead_badop) 31*48012Smckusick #define dead_mknod ((int (*) __P(( \ 32*48012Smckusick struct nameidata *ndp, \ 33*48012Smckusick struct vattr *vap, \ 34*48012Smckusick struct ucred *cred, \ 35*48012Smckusick struct proc *p))) dead_badop) 36*48012Smckusick int dead_open __P(( 37*48012Smckusick struct vnode *vp, 38*48012Smckusick int mode, 39*48012Smckusick struct ucred *cred, 40*48012Smckusick struct proc *p)); 41*48012Smckusick #define dead_close ((int (*) __P(( \ 42*48012Smckusick struct vnode *vp, \ 43*48012Smckusick int fflag, \ 44*48012Smckusick struct ucred *cred, \ 45*48012Smckusick struct proc *p))) nullop) 46*48012Smckusick #define dead_access ((int (*) __P(( \ 47*48012Smckusick struct vnode *vp, \ 48*48012Smckusick int mode, \ 49*48012Smckusick struct ucred *cred, \ 50*48012Smckusick struct proc *p))) dead_ebadf) 51*48012Smckusick #define dead_getattr ((int (*) __P(( \ 52*48012Smckusick struct vnode *vp, \ 53*48012Smckusick struct vattr *vap, \ 54*48012Smckusick struct ucred *cred, \ 55*48012Smckusick struct proc *p))) dead_ebadf) 56*48012Smckusick #define dead_setattr ((int (*) __P(( \ 57*48012Smckusick struct vnode *vp, \ 58*48012Smckusick struct vattr *vap, \ 59*48012Smckusick struct ucred *cred, \ 60*48012Smckusick struct proc *p))) dead_ebadf) 61*48012Smckusick int dead_read __P(( 62*48012Smckusick struct vnode *vp, 63*48012Smckusick struct uio *uio, 64*48012Smckusick int ioflag, 65*48012Smckusick struct ucred *cred)); 66*48012Smckusick int dead_write __P(( 67*48012Smckusick struct vnode *vp, 68*48012Smckusick struct uio *uio, 69*48012Smckusick int ioflag, 70*48012Smckusick struct ucred *cred)); 71*48012Smckusick int dead_ioctl __P(( 72*48012Smckusick struct vnode *vp, 73*48012Smckusick int command, 74*48012Smckusick caddr_t data, 75*48012Smckusick int fflag, 76*48012Smckusick struct ucred *cred, 77*48012Smckusick struct proc *p)); 78*48012Smckusick int dead_select __P(( 79*48012Smckusick struct vnode *vp, 80*48012Smckusick int which, 81*48012Smckusick int fflags, 82*48012Smckusick struct ucred *cred, 83*48012Smckusick struct proc *p)); 84*48012Smckusick #define dead_mmap ((int (*) __P(( \ 85*48012Smckusick struct vnode *vp, \ 86*48012Smckusick int fflags, \ 87*48012Smckusick struct ucred *cred, \ 88*48012Smckusick struct proc *p))) dead_badop) 89*48012Smckusick #define dead_fsync ((int (*) __P(( \ 90*48012Smckusick struct vnode *vp, \ 91*48012Smckusick int fflags, \ 92*48012Smckusick struct ucred *cred, \ 93*48012Smckusick int waitfor, \ 94*48012Smckusick struct proc *p))) nullop) 95*48012Smckusick #define dead_seek ((int (*) __P(( \ 96*48012Smckusick struct vnode *vp, \ 97*48012Smckusick off_t oldoff, \ 98*48012Smckusick off_t newoff, \ 99*48012Smckusick struct ucred *cred))) nullop) 100*48012Smckusick #define dead_remove ((int (*) __P(( \ 101*48012Smckusick struct nameidata *ndp, \ 102*48012Smckusick struct proc *p))) dead_badop) 103*48012Smckusick #define dead_link ((int (*) __P(( \ 104*48012Smckusick struct vnode *vp, \ 105*48012Smckusick struct nameidata *ndp, \ 106*48012Smckusick struct proc *p))) dead_badop) 107*48012Smckusick #define dead_rename ((int (*) __P(( \ 108*48012Smckusick struct nameidata *fndp, \ 109*48012Smckusick struct nameidata *tdnp, \ 110*48012Smckusick struct proc *p))) dead_badop) 111*48012Smckusick #define dead_mkdir ((int (*) __P(( \ 112*48012Smckusick struct nameidata *ndp, \ 113*48012Smckusick struct vattr *vap, \ 114*48012Smckusick struct proc *p))) dead_badop) 115*48012Smckusick #define dead_rmdir ((int (*) __P(( \ 116*48012Smckusick struct nameidata *ndp, \ 117*48012Smckusick struct proc *p))) dead_badop) 118*48012Smckusick #define dead_symlink ((int (*) __P(( \ 119*48012Smckusick struct nameidata *ndp, \ 120*48012Smckusick struct vattr *vap, \ 121*48012Smckusick char *target, \ 122*48012Smckusick struct proc *p))) dead_badop) 123*48012Smckusick #define dead_readdir ((int (*) __P(( \ 124*48012Smckusick struct vnode *vp, \ 125*48012Smckusick struct uio *uio, \ 126*48012Smckusick struct ucred *cred, \ 127*48012Smckusick int *eofflagp))) dead_ebadf) 128*48012Smckusick #define dead_readlink ((int (*) __P(( \ 129*48012Smckusick struct vnode *vp, \ 130*48012Smckusick struct uio *uio, \ 131*48012Smckusick struct ucred *cred))) dead_ebadf) 132*48012Smckusick #define dead_abortop ((int (*) __P(( \ 133*48012Smckusick struct nameidata *ndp))) dead_badop) 134*48012Smckusick #define dead_inactive ((int (*) __P(( \ 135*48012Smckusick struct vnode *vp, \ 136*48012Smckusick struct proc *p))) nullop) 137*48012Smckusick #define dead_reclaim ((int (*) __P(( \ 138*48012Smckusick struct vnode *vp))) nullop) 139*48012Smckusick int dead_lock __P(( 140*48012Smckusick struct vnode *vp)); 141*48012Smckusick #define dead_unlock ((int (*) __P(( \ 142*48012Smckusick struct vnode *vp))) nullop) 143*48012Smckusick int dead_bmap __P(( 144*48012Smckusick struct vnode *vp, 145*48012Smckusick daddr_t bn, 146*48012Smckusick struct vnode **vpp, 147*48012Smckusick daddr_t *bnp)); 148*48012Smckusick int dead_strategy __P(( 149*48012Smckusick struct buf *bp)); 150*48012Smckusick int dead_print __P(( 151*48012Smckusick struct vnode *vp)); 152*48012Smckusick #define dead_islocked ((int (*) __P(( \ 153*48012Smckusick struct vnode *vp))) nullop) 154*48012Smckusick #define dead_advlock ((int (*) __P(( \ 155*48012Smckusick struct vnode *vp, \ 156*48012Smckusick caddr_t id, \ 157*48012Smckusick int op, \ 158*48012Smckusick struct flock *fl, \ 159*48012Smckusick int flags))) dead_ebadf) 16039483Smckusick 16139483Smckusick struct vnodeops dead_vnodeops = { 16239483Smckusick dead_lookup, /* lookup */ 163*48012Smckusick dead_create, /* create */ 164*48012Smckusick dead_mknod, /* mknod */ 16539483Smckusick dead_open, /* open */ 166*48012Smckusick dead_close, /* close */ 167*48012Smckusick dead_access, /* access */ 168*48012Smckusick dead_getattr, /* getattr */ 169*48012Smckusick dead_setattr, /* setattr */ 17039483Smckusick dead_read, /* read */ 17139483Smckusick dead_write, /* write */ 17239483Smckusick dead_ioctl, /* ioctl */ 17339483Smckusick dead_select, /* select */ 174*48012Smckusick dead_mmap, /* mmap */ 175*48012Smckusick dead_fsync, /* fsync */ 176*48012Smckusick dead_seek, /* seek */ 177*48012Smckusick dead_remove, /* remove */ 178*48012Smckusick dead_link, /* link */ 179*48012Smckusick dead_rename, /* rename */ 180*48012Smckusick dead_mkdir, /* mkdir */ 181*48012Smckusick dead_rmdir, /* rmdir */ 182*48012Smckusick dead_symlink, /* symlink */ 183*48012Smckusick dead_readdir, /* readdir */ 184*48012Smckusick dead_readlink, /* readlink */ 185*48012Smckusick dead_abortop, /* abortop */ 186*48012Smckusick dead_inactive, /* inactive */ 187*48012Smckusick dead_reclaim, /* reclaim */ 18839483Smckusick dead_lock, /* lock */ 189*48012Smckusick dead_unlock, /* unlock */ 19039508Smckusick dead_bmap, /* bmap */ 19139483Smckusick dead_strategy, /* strategy */ 19239911Smckusick dead_print, /* print */ 193*48012Smckusick dead_islocked, /* islocked */ 194*48012Smckusick dead_advlock, /* advlock */ 19539483Smckusick }; 19639483Smckusick 19739483Smckusick /* 19839483Smckusick * Trivial lookup routine that always fails. 19939483Smckusick */ 200*48012Smckusick /* ARGSUSED */ 201*48012Smckusick dead_lookup(vp, ndp, p) 20239483Smckusick struct vnode *vp; 20339483Smckusick struct nameidata *ndp; 204*48012Smckusick struct proc *p; 20539483Smckusick { 20639483Smckusick 20739483Smckusick ndp->ni_dvp = vp; 20839483Smckusick ndp->ni_vp = NULL; 20939483Smckusick return (ENOTDIR); 21039483Smckusick } 21139483Smckusick 21239483Smckusick /* 21339483Smckusick * Open always fails as if device did not exist. 21439483Smckusick */ 21539483Smckusick /* ARGSUSED */ 216*48012Smckusick dead_open(vp, mode, cred, p) 21739483Smckusick struct vnode *vp; 21839483Smckusick int mode; 21939483Smckusick struct ucred *cred; 220*48012Smckusick struct proc *p; 22139483Smckusick { 22239483Smckusick 22339483Smckusick return (ENXIO); 22439483Smckusick } 22539483Smckusick 22639483Smckusick /* 22739483Smckusick * Vnode op for read 22839483Smckusick */ 22939591Smckusick /* ARGSUSED */ 23039591Smckusick dead_read(vp, uio, ioflag, cred) 23139483Smckusick struct vnode *vp; 23239483Smckusick struct uio *uio; 23339483Smckusick int ioflag; 23439483Smckusick struct ucred *cred; 23539483Smckusick { 23639483Smckusick 23739591Smckusick if (chkvnlock(vp)) 23839591Smckusick panic("dead_read: lock"); 23939591Smckusick /* 24039591Smckusick * Return EOF for character devices, EIO for others 24139591Smckusick */ 24239591Smckusick if (vp->v_type != VCHR) 24339483Smckusick return (EIO); 24439591Smckusick return (0); 24539483Smckusick } 24639483Smckusick 24739483Smckusick /* 24839483Smckusick * Vnode op for write 24939483Smckusick */ 25039591Smckusick /* ARGSUSED */ 25139591Smckusick dead_write(vp, uio, ioflag, cred) 25239483Smckusick register struct vnode *vp; 25339483Smckusick struct uio *uio; 25439483Smckusick int ioflag; 25539483Smckusick struct ucred *cred; 25639483Smckusick { 25739483Smckusick 25839591Smckusick if (chkvnlock(vp)) 25939591Smckusick panic("dead_write: lock"); 26039591Smckusick return (EIO); 26139483Smckusick } 26239483Smckusick 26339483Smckusick /* 26439483Smckusick * Device ioctl operation. 26539483Smckusick */ 26639483Smckusick /* ARGSUSED */ 267*48012Smckusick dead_ioctl(vp, com, data, fflag, cred, p) 26839483Smckusick struct vnode *vp; 26939483Smckusick register int com; 27039483Smckusick caddr_t data; 27139483Smckusick int fflag; 27239483Smckusick struct ucred *cred; 273*48012Smckusick struct proc *p; 27439483Smckusick { 27539483Smckusick 27639519Smckusick if (!chkvnlock(vp)) 27739483Smckusick return (EBADF); 278*48012Smckusick return (VOP_IOCTL(vp, com, data, fflag, cred, p)); 27939483Smckusick } 28039483Smckusick 28139483Smckusick /* ARGSUSED */ 282*48012Smckusick dead_select(vp, which, fflags, cred, p) 28339483Smckusick struct vnode *vp; 28440188Smckusick int which, fflags; 28539483Smckusick struct ucred *cred; 286*48012Smckusick struct proc *p; 28739483Smckusick { 28839483Smckusick 28939483Smckusick /* 29039483Smckusick * Let the user find out that the descriptor is gone. 29139483Smckusick */ 29239483Smckusick return (1); 29339483Smckusick } 29439483Smckusick 29539483Smckusick /* 29639483Smckusick * Just call the device strategy routine 29739483Smckusick */ 29839483Smckusick dead_strategy(bp) 29939483Smckusick register struct buf *bp; 30039483Smckusick { 30139483Smckusick 30239519Smckusick if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) { 30339518Smckusick bp->b_flags |= B_ERROR; 30439853Smckusick biodone(bp); 30539483Smckusick return (EIO); 30639518Smckusick } 30739483Smckusick return (VOP_STRATEGY(bp)); 30839483Smckusick } 30939483Smckusick 31039483Smckusick /* 31139483Smckusick * Wait until the vnode has finished changing state. 31239483Smckusick */ 31339483Smckusick dead_lock(vp) 31439483Smckusick struct vnode *vp; 31539483Smckusick { 31639483Smckusick 31739519Smckusick if (!chkvnlock(vp)) 31839483Smckusick return (0); 31939483Smckusick return (VOP_LOCK(vp)); 32039483Smckusick } 32139483Smckusick 32239483Smckusick /* 32339508Smckusick * Wait until the vnode has finished changing state. 32439508Smckusick */ 32539508Smckusick dead_bmap(vp, bn, vpp, bnp) 32639508Smckusick struct vnode *vp; 32739508Smckusick daddr_t bn; 32839508Smckusick struct vnode **vpp; 32939508Smckusick daddr_t *bnp; 33039508Smckusick { 33139508Smckusick 33239519Smckusick if (!chkvnlock(vp)) 33339508Smckusick return (EIO); 33439508Smckusick return (VOP_BMAP(vp, bn, vpp, bnp)); 33539508Smckusick } 33639508Smckusick 33739508Smckusick /* 33839911Smckusick * Print out the contents of a dead vnode. 33939911Smckusick */ 34045110Smckusick /* ARGSUSED */ 34139911Smckusick dead_print(vp) 34239911Smckusick struct vnode *vp; 34339911Smckusick { 34439911Smckusick 34539911Smckusick printf("tag VT_NON, dead vnode\n"); 34639911Smckusick } 34739911Smckusick 34839911Smckusick /* 34939486Smckusick * Empty vnode failed operation 35039486Smckusick */ 35139486Smckusick dead_ebadf() 35239486Smckusick { 35339486Smckusick 35439486Smckusick return (EBADF); 35539486Smckusick } 35639486Smckusick 35739486Smckusick /* 35839483Smckusick * Empty vnode bad operation 35939483Smckusick */ 36039483Smckusick dead_badop() 36139483Smckusick { 36239483Smckusick 36339483Smckusick panic("dead_badop called"); 36439483Smckusick /* NOTREACHED */ 36539483Smckusick } 36639483Smckusick 36739483Smckusick /* 36839483Smckusick * Empty vnode null operation 36939483Smckusick */ 37039483Smckusick dead_nullop() 37139483Smckusick { 37239483Smckusick 37339483Smckusick return (0); 37439483Smckusick } 37539519Smckusick 37639519Smckusick /* 37739519Smckusick * We have to wait during times when the vnode is 37839519Smckusick * in a state of change. 37939519Smckusick */ 38039519Smckusick chkvnlock(vp) 38139519Smckusick register struct vnode *vp; 38239519Smckusick { 38339519Smckusick int locked = 0; 38439519Smckusick 38539519Smckusick while (vp->v_flag & VXLOCK) { 38639519Smckusick vp->v_flag |= VXWANT; 38739519Smckusick sleep((caddr_t)vp, PINOD); 38839519Smckusick locked = 1; 38939519Smckusick } 39039519Smckusick return (locked); 39139519Smckusick } 392