139483Smckusick /* 239483Smckusick * Copyright (c) 1989 The Regents of the University of California. 339483Smckusick * All rights reserved. 439483Smckusick * 544429Sbostic * %sccs.include.redist.c% 639483Smckusick * 7*45110Smckusick * @(#)dead_vnops.c 7.11 (Berkeley) 08/24/90 839483Smckusick */ 939483Smckusick 1039483Smckusick #include "param.h" 1139483Smckusick #include "time.h" 1239483Smckusick #include "vnode.h" 1339483Smckusick #include "errno.h" 1439483Smckusick #include "namei.h" 1539483Smckusick #include "buf.h" 1639483Smckusick 1739483Smckusick int dead_lookup(), 1839483Smckusick dead_open(), 1939483Smckusick dead_read(), 2039483Smckusick dead_write(), 2139483Smckusick dead_strategy(), 2239483Smckusick dead_ioctl(), 2339483Smckusick dead_select(), 2439483Smckusick dead_lock(), 2539508Smckusick dead_bmap(), 2639911Smckusick dead_print(), 2739486Smckusick dead_ebadf(), 2839483Smckusick dead_badop(), 2939483Smckusick dead_nullop(); 3039483Smckusick 3139483Smckusick struct vnodeops dead_vnodeops = { 3239483Smckusick dead_lookup, /* lookup */ 3339483Smckusick dead_badop, /* create */ 3439483Smckusick dead_badop, /* mknod */ 3539483Smckusick dead_open, /* open */ 3639483Smckusick dead_nullop, /* close */ 3739486Smckusick dead_ebadf, /* access */ 3839486Smckusick dead_ebadf, /* getattr */ 3939486Smckusick dead_ebadf, /* setattr */ 4039483Smckusick dead_read, /* read */ 4139483Smckusick dead_write, /* write */ 4239483Smckusick dead_ioctl, /* ioctl */ 4339483Smckusick dead_select, /* select */ 4439483Smckusick dead_badop, /* mmap */ 4539483Smckusick dead_nullop, /* fsync */ 4639483Smckusick dead_nullop, /* seek */ 4739483Smckusick dead_badop, /* remove */ 4839483Smckusick dead_badop, /* link */ 4939483Smckusick dead_badop, /* rename */ 5039483Smckusick dead_badop, /* mkdir */ 5139483Smckusick dead_badop, /* rmdir */ 5239483Smckusick dead_badop, /* symlink */ 5339486Smckusick dead_ebadf, /* readdir */ 5439486Smckusick dead_ebadf, /* readlink */ 5539483Smckusick dead_badop, /* abortop */ 5639483Smckusick dead_nullop, /* inactive */ 5739483Smckusick dead_nullop, /* reclaim */ 5839483Smckusick dead_lock, /* lock */ 5939483Smckusick dead_nullop, /* unlock */ 6039508Smckusick dead_bmap, /* bmap */ 6139483Smckusick dead_strategy, /* strategy */ 6239911Smckusick dead_print, /* print */ 6339911Smckusick dead_nullop, /* islocked */ 6439483Smckusick }; 6539483Smckusick 6639483Smckusick /* 6739483Smckusick * Trivial lookup routine that always fails. 6839483Smckusick */ 6939483Smckusick dead_lookup(vp, ndp) 7039483Smckusick struct vnode *vp; 7139483Smckusick struct nameidata *ndp; 7239483Smckusick { 7339483Smckusick 7439483Smckusick ndp->ni_dvp = vp; 7539483Smckusick ndp->ni_vp = NULL; 7639483Smckusick return (ENOTDIR); 7739483Smckusick } 7839483Smckusick 7939483Smckusick /* 8039483Smckusick * Open always fails as if device did not exist. 8139483Smckusick */ 8239483Smckusick /* ARGSUSED */ 8339483Smckusick dead_open(vp, mode, cred) 8439483Smckusick struct vnode *vp; 8539483Smckusick int mode; 8639483Smckusick struct ucred *cred; 8739483Smckusick { 8839483Smckusick 8939483Smckusick return (ENXIO); 9039483Smckusick } 9139483Smckusick 9239483Smckusick /* 9339483Smckusick * Vnode op for read 9439483Smckusick */ 9539591Smckusick /* ARGSUSED */ 9639591Smckusick dead_read(vp, uio, ioflag, cred) 9739483Smckusick struct vnode *vp; 9839483Smckusick struct uio *uio; 9939483Smckusick int ioflag; 10039483Smckusick struct ucred *cred; 10139483Smckusick { 10239483Smckusick 10339591Smckusick if (chkvnlock(vp)) 10439591Smckusick panic("dead_read: lock"); 10539591Smckusick /* 10639591Smckusick * Return EOF for character devices, EIO for others 10739591Smckusick */ 10839591Smckusick if (vp->v_type != VCHR) 10939483Smckusick return (EIO); 11039591Smckusick return (0); 11139483Smckusick } 11239483Smckusick 11339483Smckusick /* 11439483Smckusick * Vnode op for write 11539483Smckusick */ 11639591Smckusick /* ARGSUSED */ 11739591Smckusick dead_write(vp, uio, ioflag, cred) 11839483Smckusick register struct vnode *vp; 11939483Smckusick struct uio *uio; 12039483Smckusick int ioflag; 12139483Smckusick struct ucred *cred; 12239483Smckusick { 12339483Smckusick 12439591Smckusick if (chkvnlock(vp)) 12539591Smckusick panic("dead_write: lock"); 12639591Smckusick return (EIO); 12739483Smckusick } 12839483Smckusick 12939483Smckusick /* 13039483Smckusick * Device ioctl operation. 13139483Smckusick */ 13239483Smckusick /* ARGSUSED */ 13339483Smckusick dead_ioctl(vp, com, data, fflag, cred) 13439483Smckusick struct vnode *vp; 13539483Smckusick register int com; 13639483Smckusick caddr_t data; 13739483Smckusick int fflag; 13839483Smckusick struct ucred *cred; 13939483Smckusick { 14039483Smckusick 14139519Smckusick if (!chkvnlock(vp)) 14239483Smckusick return (EBADF); 14339483Smckusick return (VOP_IOCTL(vp, com, data, fflag, cred)); 14439483Smckusick } 14539483Smckusick 14639483Smckusick /* ARGSUSED */ 14740188Smckusick dead_select(vp, which, fflags, cred) 14839483Smckusick struct vnode *vp; 14940188Smckusick int which, fflags; 15039483Smckusick struct ucred *cred; 15139483Smckusick { 15239483Smckusick 15339483Smckusick /* 15439483Smckusick * Let the user find out that the descriptor is gone. 15539483Smckusick */ 15639483Smckusick return (1); 15739483Smckusick } 15839483Smckusick 15939483Smckusick /* 16039483Smckusick * Just call the device strategy routine 16139483Smckusick */ 16239483Smckusick dead_strategy(bp) 16339483Smckusick register struct buf *bp; 16439483Smckusick { 16539483Smckusick 16639519Smckusick if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) { 16739518Smckusick bp->b_flags |= B_ERROR; 16839853Smckusick biodone(bp); 16939483Smckusick return (EIO); 17039518Smckusick } 17139483Smckusick return (VOP_STRATEGY(bp)); 17239483Smckusick } 17339483Smckusick 17439483Smckusick /* 17539483Smckusick * Wait until the vnode has finished changing state. 17639483Smckusick */ 17739483Smckusick dead_lock(vp) 17839483Smckusick struct vnode *vp; 17939483Smckusick { 18039483Smckusick 18139519Smckusick if (!chkvnlock(vp)) 18239483Smckusick return (0); 18339483Smckusick return (VOP_LOCK(vp)); 18439483Smckusick } 18539483Smckusick 18639483Smckusick /* 18739508Smckusick * Wait until the vnode has finished changing state. 18839508Smckusick */ 18939508Smckusick dead_bmap(vp, bn, vpp, bnp) 19039508Smckusick struct vnode *vp; 19139508Smckusick daddr_t bn; 19239508Smckusick struct vnode **vpp; 19339508Smckusick daddr_t *bnp; 19439508Smckusick { 19539508Smckusick 19639519Smckusick if (!chkvnlock(vp)) 19739508Smckusick return (EIO); 19839508Smckusick return (VOP_BMAP(vp, bn, vpp, bnp)); 19939508Smckusick } 20039508Smckusick 20139508Smckusick /* 20239911Smckusick * Print out the contents of a dead vnode. 20339911Smckusick */ 204*45110Smckusick /* ARGSUSED */ 20539911Smckusick dead_print(vp) 20639911Smckusick struct vnode *vp; 20739911Smckusick { 20839911Smckusick 20939911Smckusick printf("tag VT_NON, dead vnode\n"); 21039911Smckusick } 21139911Smckusick 21239911Smckusick /* 21339486Smckusick * Empty vnode failed operation 21439486Smckusick */ 21539486Smckusick dead_ebadf() 21639486Smckusick { 21739486Smckusick 21839486Smckusick return (EBADF); 21939486Smckusick } 22039486Smckusick 22139486Smckusick /* 22239483Smckusick * Empty vnode bad operation 22339483Smckusick */ 22439483Smckusick dead_badop() 22539483Smckusick { 22639483Smckusick 22739483Smckusick panic("dead_badop called"); 22839483Smckusick /* NOTREACHED */ 22939483Smckusick } 23039483Smckusick 23139483Smckusick /* 23239483Smckusick * Empty vnode null operation 23339483Smckusick */ 23439483Smckusick dead_nullop() 23539483Smckusick { 23639483Smckusick 23739483Smckusick return (0); 23839483Smckusick } 23939519Smckusick 24039519Smckusick /* 24139519Smckusick * We have to wait during times when the vnode is 24239519Smckusick * in a state of change. 24339519Smckusick */ 24439519Smckusick chkvnlock(vp) 24539519Smckusick register struct vnode *vp; 24639519Smckusick { 24739519Smckusick int locked = 0; 24839519Smckusick 24939519Smckusick while (vp->v_flag & VXLOCK) { 25039519Smckusick vp->v_flag |= VXWANT; 25139519Smckusick sleep((caddr_t)vp, PINOD); 25239519Smckusick locked = 1; 25339519Smckusick } 25439519Smckusick return (locked); 25539519Smckusick } 256