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*39591Smckusick * @(#)dead_vnops.c 7.6 (Berkeley) 11/22/89 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(), 3639486Smckusick dead_ebadf(), 3739483Smckusick dead_badop(), 3839483Smckusick dead_nullop(); 3939483Smckusick 4039483Smckusick struct vnodeops dead_vnodeops = { 4139483Smckusick dead_lookup, /* lookup */ 4239483Smckusick dead_badop, /* create */ 4339483Smckusick dead_badop, /* mknod */ 4439483Smckusick dead_open, /* open */ 4539483Smckusick dead_nullop, /* close */ 4639486Smckusick dead_ebadf, /* access */ 4739486Smckusick dead_ebadf, /* getattr */ 4839486Smckusick dead_ebadf, /* setattr */ 4939483Smckusick dead_read, /* read */ 5039483Smckusick dead_write, /* write */ 5139483Smckusick dead_ioctl, /* ioctl */ 5239483Smckusick dead_select, /* select */ 5339483Smckusick dead_badop, /* mmap */ 5439483Smckusick dead_nullop, /* fsync */ 5539483Smckusick dead_nullop, /* seek */ 5639483Smckusick dead_badop, /* remove */ 5739483Smckusick dead_badop, /* link */ 5839483Smckusick dead_badop, /* rename */ 5939483Smckusick dead_badop, /* mkdir */ 6039483Smckusick dead_badop, /* rmdir */ 6139483Smckusick dead_badop, /* symlink */ 6239486Smckusick dead_ebadf, /* readdir */ 6339486Smckusick dead_ebadf, /* readlink */ 6439483Smckusick dead_badop, /* abortop */ 6539483Smckusick dead_nullop, /* inactive */ 6639483Smckusick dead_nullop, /* reclaim */ 6739483Smckusick dead_lock, /* lock */ 6839483Smckusick dead_nullop, /* unlock */ 6939508Smckusick dead_bmap, /* bmap */ 7039483Smckusick dead_strategy, /* strategy */ 7139483Smckusick }; 7239483Smckusick 7339483Smckusick /* 7439483Smckusick * Trivial lookup routine that always fails. 7539483Smckusick */ 7639483Smckusick dead_lookup(vp, ndp) 7739483Smckusick struct vnode *vp; 7839483Smckusick struct nameidata *ndp; 7939483Smckusick { 8039483Smckusick 8139483Smckusick ndp->ni_dvp = vp; 8239483Smckusick ndp->ni_vp = NULL; 8339483Smckusick return (ENOTDIR); 8439483Smckusick } 8539483Smckusick 8639483Smckusick /* 8739483Smckusick * Open always fails as if device did not exist. 8839483Smckusick */ 8939483Smckusick /* ARGSUSED */ 9039483Smckusick dead_open(vp, mode, cred) 9139483Smckusick struct vnode *vp; 9239483Smckusick int mode; 9339483Smckusick struct ucred *cred; 9439483Smckusick { 9539483Smckusick 9639483Smckusick return (ENXIO); 9739483Smckusick } 9839483Smckusick 9939483Smckusick /* 10039483Smckusick * Vnode op for read 10139483Smckusick */ 102*39591Smckusick /* ARGSUSED */ 103*39591Smckusick dead_read(vp, uio, ioflag, cred) 10439483Smckusick struct vnode *vp; 10539483Smckusick struct uio *uio; 10639483Smckusick int ioflag; 10739483Smckusick struct ucred *cred; 10839483Smckusick { 10939483Smckusick 110*39591Smckusick if (chkvnlock(vp)) 111*39591Smckusick panic("dead_read: lock"); 112*39591Smckusick /* 113*39591Smckusick * Return EOF for character devices, EIO for others 114*39591Smckusick */ 115*39591Smckusick if (vp->v_type != VCHR) 11639483Smckusick return (EIO); 117*39591Smckusick return (0); 11839483Smckusick } 11939483Smckusick 12039483Smckusick /* 12139483Smckusick * Vnode op for write 12239483Smckusick */ 123*39591Smckusick /* ARGSUSED */ 124*39591Smckusick dead_write(vp, uio, ioflag, cred) 12539483Smckusick register struct vnode *vp; 12639483Smckusick struct uio *uio; 12739483Smckusick int ioflag; 12839483Smckusick struct ucred *cred; 12939483Smckusick { 13039483Smckusick 131*39591Smckusick if (chkvnlock(vp)) 132*39591Smckusick panic("dead_write: lock"); 133*39591Smckusick return (EIO); 13439483Smckusick } 13539483Smckusick 13639483Smckusick /* 13739483Smckusick * Device ioctl operation. 13839483Smckusick */ 13939483Smckusick /* ARGSUSED */ 14039483Smckusick dead_ioctl(vp, com, data, fflag, cred) 14139483Smckusick struct vnode *vp; 14239483Smckusick register int com; 14339483Smckusick caddr_t data; 14439483Smckusick int fflag; 14539483Smckusick struct ucred *cred; 14639483Smckusick { 14739483Smckusick 14839519Smckusick if (!chkvnlock(vp)) 14939483Smckusick return (EBADF); 15039483Smckusick return (VOP_IOCTL(vp, com, data, fflag, cred)); 15139483Smckusick } 15239483Smckusick 15339483Smckusick /* ARGSUSED */ 15439483Smckusick dead_select(vp, which, cred) 15539483Smckusick struct vnode *vp; 15639483Smckusick int which; 15739483Smckusick struct ucred *cred; 15839483Smckusick { 15939483Smckusick 16039483Smckusick /* 16139483Smckusick * Let the user find out that the descriptor is gone. 16239483Smckusick */ 16339483Smckusick return (1); 16439483Smckusick } 16539483Smckusick 16639483Smckusick /* 16739483Smckusick * Just call the device strategy routine 16839483Smckusick */ 16939483Smckusick dead_strategy(bp) 17039483Smckusick register struct buf *bp; 17139483Smckusick { 17239483Smckusick 17339519Smckusick if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) { 17439518Smckusick bp->b_flags |= B_ERROR; 17539483Smckusick return (EIO); 17639518Smckusick } 17739483Smckusick return (VOP_STRATEGY(bp)); 17839483Smckusick } 17939483Smckusick 18039483Smckusick /* 18139483Smckusick * Wait until the vnode has finished changing state. 18239483Smckusick */ 18339483Smckusick dead_lock(vp) 18439483Smckusick struct vnode *vp; 18539483Smckusick { 18639483Smckusick 18739519Smckusick if (!chkvnlock(vp)) 18839483Smckusick return (0); 18939483Smckusick return (VOP_LOCK(vp)); 19039483Smckusick } 19139483Smckusick 19239483Smckusick /* 19339508Smckusick * Wait until the vnode has finished changing state. 19439508Smckusick */ 19539508Smckusick dead_bmap(vp, bn, vpp, bnp) 19639508Smckusick struct vnode *vp; 19739508Smckusick daddr_t bn; 19839508Smckusick struct vnode **vpp; 19939508Smckusick daddr_t *bnp; 20039508Smckusick { 20139508Smckusick 20239519Smckusick if (!chkvnlock(vp)) 20339508Smckusick return (EIO); 20439508Smckusick return (VOP_BMAP(vp, bn, vpp, bnp)); 20539508Smckusick } 20639508Smckusick 20739508Smckusick /* 20839486Smckusick * Empty vnode failed operation 20939486Smckusick */ 21039486Smckusick dead_ebadf() 21139486Smckusick { 21239486Smckusick 21339486Smckusick return (EBADF); 21439486Smckusick } 21539486Smckusick 21639486Smckusick /* 21739483Smckusick * Empty vnode bad operation 21839483Smckusick */ 21939483Smckusick dead_badop() 22039483Smckusick { 22139483Smckusick 22239483Smckusick panic("dead_badop called"); 22339483Smckusick /* NOTREACHED */ 22439483Smckusick } 22539483Smckusick 22639483Smckusick /* 22739483Smckusick * Empty vnode null operation 22839483Smckusick */ 22939483Smckusick dead_nullop() 23039483Smckusick { 23139483Smckusick 23239483Smckusick return (0); 23339483Smckusick } 23439519Smckusick 23539519Smckusick /* 23639519Smckusick * We have to wait during times when the vnode is 23739519Smckusick * in a state of change. 23839519Smckusick */ 23939519Smckusick chkvnlock(vp) 24039519Smckusick register struct vnode *vp; 24139519Smckusick { 24239519Smckusick int locked = 0; 24339519Smckusick 24439519Smckusick while (vp->v_flag & VXLOCK) { 24539519Smckusick vp->v_flag |= VXWANT; 24639519Smckusick sleep((caddr_t)vp, PINOD); 24739519Smckusick locked = 1; 24839519Smckusick } 24939519Smckusick return (locked); 25039519Smckusick } 251