139483Smckusick /* 239483Smckusick * Copyright (c) 1989 The Regents of the University of California. 339483Smckusick * All rights reserved. 439483Smckusick * 539483Smckusick * Redistribution and use in source and binary forms are permitted 639483Smckusick * provided that the above copyright notice and this paragraph are 739483Smckusick * duplicated in all such forms and that any documentation, 839483Smckusick * advertising materials, and other materials related to such 939483Smckusick * distribution and use acknowledge that the software was developed 1039483Smckusick * by the University of California, Berkeley. The name of the 1139483Smckusick * University may not be used to endorse or promote products derived 1239483Smckusick * from this software without specific prior written permission. 1339483Smckusick * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1439483Smckusick * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1539483Smckusick * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1639483Smckusick * 17*40188Smckusick * @(#)dead_vnops.c 7.9 (Berkeley) 02/21/90 1839483Smckusick */ 1939483Smckusick 2039483Smckusick #include "param.h" 2139483Smckusick #include "time.h" 2239483Smckusick #include "vnode.h" 2339483Smckusick #include "errno.h" 2439483Smckusick #include "namei.h" 2539483Smckusick #include "buf.h" 2639483Smckusick 2739483Smckusick int dead_lookup(), 2839483Smckusick dead_open(), 2939483Smckusick dead_read(), 3039483Smckusick dead_write(), 3139483Smckusick dead_strategy(), 3239483Smckusick dead_ioctl(), 3339483Smckusick dead_select(), 3439483Smckusick dead_lock(), 3539508Smckusick dead_bmap(), 3639911Smckusick dead_print(), 3739486Smckusick dead_ebadf(), 3839483Smckusick dead_badop(), 3939483Smckusick dead_nullop(); 4039483Smckusick 4139483Smckusick struct vnodeops dead_vnodeops = { 4239483Smckusick dead_lookup, /* lookup */ 4339483Smckusick dead_badop, /* create */ 4439483Smckusick dead_badop, /* mknod */ 4539483Smckusick dead_open, /* open */ 4639483Smckusick dead_nullop, /* close */ 4739486Smckusick dead_ebadf, /* access */ 4839486Smckusick dead_ebadf, /* getattr */ 4939486Smckusick dead_ebadf, /* setattr */ 5039483Smckusick dead_read, /* read */ 5139483Smckusick dead_write, /* write */ 5239483Smckusick dead_ioctl, /* ioctl */ 5339483Smckusick dead_select, /* select */ 5439483Smckusick dead_badop, /* mmap */ 5539483Smckusick dead_nullop, /* fsync */ 5639483Smckusick dead_nullop, /* seek */ 5739483Smckusick dead_badop, /* remove */ 5839483Smckusick dead_badop, /* link */ 5939483Smckusick dead_badop, /* rename */ 6039483Smckusick dead_badop, /* mkdir */ 6139483Smckusick dead_badop, /* rmdir */ 6239483Smckusick dead_badop, /* symlink */ 6339486Smckusick dead_ebadf, /* readdir */ 6439486Smckusick dead_ebadf, /* readlink */ 6539483Smckusick dead_badop, /* abortop */ 6639483Smckusick dead_nullop, /* inactive */ 6739483Smckusick dead_nullop, /* reclaim */ 6839483Smckusick dead_lock, /* lock */ 6939483Smckusick dead_nullop, /* unlock */ 7039508Smckusick dead_bmap, /* bmap */ 7139483Smckusick dead_strategy, /* strategy */ 7239911Smckusick dead_print, /* print */ 7339911Smckusick dead_nullop, /* islocked */ 7439483Smckusick }; 7539483Smckusick 7639483Smckusick /* 7739483Smckusick * Trivial lookup routine that always fails. 7839483Smckusick */ 7939483Smckusick dead_lookup(vp, ndp) 8039483Smckusick struct vnode *vp; 8139483Smckusick struct nameidata *ndp; 8239483Smckusick { 8339483Smckusick 8439483Smckusick ndp->ni_dvp = vp; 8539483Smckusick ndp->ni_vp = NULL; 8639483Smckusick return (ENOTDIR); 8739483Smckusick } 8839483Smckusick 8939483Smckusick /* 9039483Smckusick * Open always fails as if device did not exist. 9139483Smckusick */ 9239483Smckusick /* ARGSUSED */ 9339483Smckusick dead_open(vp, mode, cred) 9439483Smckusick struct vnode *vp; 9539483Smckusick int mode; 9639483Smckusick struct ucred *cred; 9739483Smckusick { 9839483Smckusick 9939483Smckusick return (ENXIO); 10039483Smckusick } 10139483Smckusick 10239483Smckusick /* 10339483Smckusick * Vnode op for read 10439483Smckusick */ 10539591Smckusick /* ARGSUSED */ 10639591Smckusick dead_read(vp, uio, ioflag, cred) 10739483Smckusick struct vnode *vp; 10839483Smckusick struct uio *uio; 10939483Smckusick int ioflag; 11039483Smckusick struct ucred *cred; 11139483Smckusick { 11239483Smckusick 11339591Smckusick if (chkvnlock(vp)) 11439591Smckusick panic("dead_read: lock"); 11539591Smckusick /* 11639591Smckusick * Return EOF for character devices, EIO for others 11739591Smckusick */ 11839591Smckusick if (vp->v_type != VCHR) 11939483Smckusick return (EIO); 12039591Smckusick return (0); 12139483Smckusick } 12239483Smckusick 12339483Smckusick /* 12439483Smckusick * Vnode op for write 12539483Smckusick */ 12639591Smckusick /* ARGSUSED */ 12739591Smckusick dead_write(vp, uio, ioflag, cred) 12839483Smckusick register struct vnode *vp; 12939483Smckusick struct uio *uio; 13039483Smckusick int ioflag; 13139483Smckusick struct ucred *cred; 13239483Smckusick { 13339483Smckusick 13439591Smckusick if (chkvnlock(vp)) 13539591Smckusick panic("dead_write: lock"); 13639591Smckusick return (EIO); 13739483Smckusick } 13839483Smckusick 13939483Smckusick /* 14039483Smckusick * Device ioctl operation. 14139483Smckusick */ 14239483Smckusick /* ARGSUSED */ 14339483Smckusick dead_ioctl(vp, com, data, fflag, cred) 14439483Smckusick struct vnode *vp; 14539483Smckusick register int com; 14639483Smckusick caddr_t data; 14739483Smckusick int fflag; 14839483Smckusick struct ucred *cred; 14939483Smckusick { 15039483Smckusick 15139519Smckusick if (!chkvnlock(vp)) 15239483Smckusick return (EBADF); 15339483Smckusick return (VOP_IOCTL(vp, com, data, fflag, cred)); 15439483Smckusick } 15539483Smckusick 15639483Smckusick /* ARGSUSED */ 157*40188Smckusick dead_select(vp, which, fflags, cred) 15839483Smckusick struct vnode *vp; 159*40188Smckusick int which, fflags; 16039483Smckusick struct ucred *cred; 16139483Smckusick { 16239483Smckusick 16339483Smckusick /* 16439483Smckusick * Let the user find out that the descriptor is gone. 16539483Smckusick */ 16639483Smckusick return (1); 16739483Smckusick } 16839483Smckusick 16939483Smckusick /* 17039483Smckusick * Just call the device strategy routine 17139483Smckusick */ 17239483Smckusick dead_strategy(bp) 17339483Smckusick register struct buf *bp; 17439483Smckusick { 17539483Smckusick 17639519Smckusick if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) { 17739518Smckusick bp->b_flags |= B_ERROR; 17839853Smckusick biodone(bp); 17939483Smckusick return (EIO); 18039518Smckusick } 18139483Smckusick return (VOP_STRATEGY(bp)); 18239483Smckusick } 18339483Smckusick 18439483Smckusick /* 18539483Smckusick * Wait until the vnode has finished changing state. 18639483Smckusick */ 18739483Smckusick dead_lock(vp) 18839483Smckusick struct vnode *vp; 18939483Smckusick { 19039483Smckusick 19139519Smckusick if (!chkvnlock(vp)) 19239483Smckusick return (0); 19339483Smckusick return (VOP_LOCK(vp)); 19439483Smckusick } 19539483Smckusick 19639483Smckusick /* 19739508Smckusick * Wait until the vnode has finished changing state. 19839508Smckusick */ 19939508Smckusick dead_bmap(vp, bn, vpp, bnp) 20039508Smckusick struct vnode *vp; 20139508Smckusick daddr_t bn; 20239508Smckusick struct vnode **vpp; 20339508Smckusick daddr_t *bnp; 20439508Smckusick { 20539508Smckusick 20639519Smckusick if (!chkvnlock(vp)) 20739508Smckusick return (EIO); 20839508Smckusick return (VOP_BMAP(vp, bn, vpp, bnp)); 20939508Smckusick } 21039508Smckusick 21139508Smckusick /* 21239911Smckusick * Print out the contents of a dead vnode. 21339911Smckusick */ 21439911Smckusick dead_print(vp) 21539911Smckusick struct vnode *vp; 21639911Smckusick { 21739911Smckusick 21839911Smckusick printf("tag VT_NON, dead vnode\n"); 21939911Smckusick } 22039911Smckusick 22139911Smckusick /* 22239486Smckusick * Empty vnode failed operation 22339486Smckusick */ 22439486Smckusick dead_ebadf() 22539486Smckusick { 22639486Smckusick 22739486Smckusick return (EBADF); 22839486Smckusick } 22939486Smckusick 23039486Smckusick /* 23139483Smckusick * Empty vnode bad operation 23239483Smckusick */ 23339483Smckusick dead_badop() 23439483Smckusick { 23539483Smckusick 23639483Smckusick panic("dead_badop called"); 23739483Smckusick /* NOTREACHED */ 23839483Smckusick } 23939483Smckusick 24039483Smckusick /* 24139483Smckusick * Empty vnode null operation 24239483Smckusick */ 24339483Smckusick dead_nullop() 24439483Smckusick { 24539483Smckusick 24639483Smckusick return (0); 24739483Smckusick } 24839519Smckusick 24939519Smckusick /* 25039519Smckusick * We have to wait during times when the vnode is 25139519Smckusick * in a state of change. 25239519Smckusick */ 25339519Smckusick chkvnlock(vp) 25439519Smckusick register struct vnode *vp; 25539519Smckusick { 25639519Smckusick int locked = 0; 25739519Smckusick 25839519Smckusick while (vp->v_flag & VXLOCK) { 25939519Smckusick vp->v_flag |= VXWANT; 26039519Smckusick sleep((caddr_t)vp, PINOD); 26139519Smckusick locked = 1; 26239519Smckusick } 26339519Smckusick return (locked); 26439519Smckusick } 265