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*39519Smckusick * @(#)dead_vnops.c 7.5 (Berkeley) 11/12/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 */ 10239483Smckusick dead_read(vp, uio, offp, ioflag, cred) 10339483Smckusick struct vnode *vp; 10439483Smckusick struct uio *uio; 10539483Smckusick off_t *offp; 10639483Smckusick int ioflag; 10739483Smckusick struct ucred *cred; 10839483Smckusick { 10939483Smckusick 110*39519Smckusick if (!chkvnlock(vp)) 11139483Smckusick return (EIO); 11239483Smckusick return (VOP_READ(vp, uio, offp, ioflag, cred)); 11339483Smckusick } 11439483Smckusick 11539483Smckusick /* 11639483Smckusick * Vnode op for write 11739483Smckusick */ 11839483Smckusick dead_write(vp, uio, offp, ioflag, cred) 11939483Smckusick register struct vnode *vp; 12039483Smckusick struct uio *uio; 12139483Smckusick off_t *offp; 12239483Smckusick int ioflag; 12339483Smckusick struct ucred *cred; 12439483Smckusick { 12539483Smckusick 126*39519Smckusick if (!chkvnlock(vp)) 12739483Smckusick return (EIO); 12839483Smckusick return (VOP_WRITE(vp, uio, offp, ioflag, cred)); 12939483Smckusick } 13039483Smckusick 13139483Smckusick /* 13239483Smckusick * Device ioctl operation. 13339483Smckusick */ 13439483Smckusick /* ARGSUSED */ 13539483Smckusick dead_ioctl(vp, com, data, fflag, cred) 13639483Smckusick struct vnode *vp; 13739483Smckusick register int com; 13839483Smckusick caddr_t data; 13939483Smckusick int fflag; 14039483Smckusick struct ucred *cred; 14139483Smckusick { 14239483Smckusick 143*39519Smckusick if (!chkvnlock(vp)) 14439483Smckusick return (EBADF); 14539483Smckusick return (VOP_IOCTL(vp, com, data, fflag, cred)); 14639483Smckusick } 14739483Smckusick 14839483Smckusick /* ARGSUSED */ 14939483Smckusick dead_select(vp, which, cred) 15039483Smckusick struct vnode *vp; 15139483Smckusick int which; 15239483Smckusick struct ucred *cred; 15339483Smckusick { 15439483Smckusick 15539483Smckusick /* 15639483Smckusick * Let the user find out that the descriptor is gone. 15739483Smckusick */ 15839483Smckusick return (1); 15939483Smckusick } 16039483Smckusick 16139483Smckusick /* 16239483Smckusick * Just call the device strategy routine 16339483Smckusick */ 16439483Smckusick dead_strategy(bp) 16539483Smckusick register struct buf *bp; 16639483Smckusick { 16739483Smckusick 168*39519Smckusick if (bp->b_vp == NULL || !chkvnlock(bp->b_vp)) { 16939518Smckusick bp->b_flags |= B_ERROR; 17039483Smckusick return (EIO); 17139518Smckusick } 17239483Smckusick return (VOP_STRATEGY(bp)); 17339483Smckusick } 17439483Smckusick 17539483Smckusick /* 17639483Smckusick * Wait until the vnode has finished changing state. 17739483Smckusick */ 17839483Smckusick dead_lock(vp) 17939483Smckusick struct vnode *vp; 18039483Smckusick { 18139483Smckusick 182*39519Smckusick if (!chkvnlock(vp)) 18339483Smckusick return (0); 18439483Smckusick return (VOP_LOCK(vp)); 18539483Smckusick } 18639483Smckusick 18739483Smckusick /* 18839508Smckusick * Wait until the vnode has finished changing state. 18939508Smckusick */ 19039508Smckusick dead_bmap(vp, bn, vpp, bnp) 19139508Smckusick struct vnode *vp; 19239508Smckusick daddr_t bn; 19339508Smckusick struct vnode **vpp; 19439508Smckusick daddr_t *bnp; 19539508Smckusick { 19639508Smckusick 197*39519Smckusick if (!chkvnlock(vp)) 19839508Smckusick return (EIO); 19939508Smckusick return (VOP_BMAP(vp, bn, vpp, bnp)); 20039508Smckusick } 20139508Smckusick 20239508Smckusick /* 20339486Smckusick * Empty vnode failed operation 20439486Smckusick */ 20539486Smckusick dead_ebadf() 20639486Smckusick { 20739486Smckusick 20839486Smckusick return (EBADF); 20939486Smckusick } 21039486Smckusick 21139486Smckusick /* 21239483Smckusick * Empty vnode bad operation 21339483Smckusick */ 21439483Smckusick dead_badop() 21539483Smckusick { 21639483Smckusick 21739483Smckusick panic("dead_badop called"); 21839483Smckusick /* NOTREACHED */ 21939483Smckusick } 22039483Smckusick 22139483Smckusick /* 22239483Smckusick * Empty vnode null operation 22339483Smckusick */ 22439483Smckusick dead_nullop() 22539483Smckusick { 22639483Smckusick 22739483Smckusick return (0); 22839483Smckusick } 229*39519Smckusick 230*39519Smckusick /* 231*39519Smckusick * We have to wait during times when the vnode is 232*39519Smckusick * in a state of change. 233*39519Smckusick */ 234*39519Smckusick chkvnlock(vp) 235*39519Smckusick register struct vnode *vp; 236*39519Smckusick { 237*39519Smckusick int locked = 0; 238*39519Smckusick 239*39519Smckusick while (vp->v_flag & VXLOCK) { 240*39519Smckusick vp->v_flag |= VXWANT; 241*39519Smckusick sleep((caddr_t)vp, PINOD); 242*39519Smckusick locked = 1; 243*39519Smckusick } 244*39519Smckusick return (locked); 245*39519Smckusick } 246