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*39518Smckusick * @(#)dead_vnops.c 7.4 (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 int locked = 0; 11039483Smckusick 11139483Smckusick /* 11239483Smckusick * We have to wait during times when the vnode is 11339483Smckusick * in a state of change. 11439483Smckusick */ 11539483Smckusick while (vp->v_flag & VXLOCK) { 11639483Smckusick vp->v_flag |= VXWANT; 11739483Smckusick sleep((caddr_t)vp, PINOD); 11839483Smckusick locked = 1; 11939483Smckusick } 12039483Smckusick if (!locked) 12139483Smckusick return (EIO); 12239483Smckusick return (VOP_READ(vp, uio, offp, ioflag, cred)); 12339483Smckusick } 12439483Smckusick 12539483Smckusick /* 12639483Smckusick * Vnode op for write 12739483Smckusick */ 12839483Smckusick dead_write(vp, uio, offp, ioflag, cred) 12939483Smckusick register struct vnode *vp; 13039483Smckusick struct uio *uio; 13139483Smckusick off_t *offp; 13239483Smckusick int ioflag; 13339483Smckusick struct ucred *cred; 13439483Smckusick { 13539483Smckusick int locked = 0; 13639483Smckusick 13739483Smckusick /* 13839483Smckusick * We have to wait during times when the vnode is 13939483Smckusick * in a state of change. 14039483Smckusick */ 14139483Smckusick while (vp->v_flag & VXLOCK) { 14239483Smckusick vp->v_flag |= VXWANT; 14339483Smckusick sleep((caddr_t)vp, PINOD); 14439483Smckusick locked = 1; 14539483Smckusick } 14639483Smckusick if (!locked) 14739483Smckusick return (EIO); 14839483Smckusick return (VOP_WRITE(vp, uio, offp, ioflag, cred)); 14939483Smckusick } 15039483Smckusick 15139483Smckusick /* 15239483Smckusick * Device ioctl operation. 15339483Smckusick */ 15439483Smckusick /* ARGSUSED */ 15539483Smckusick dead_ioctl(vp, com, data, fflag, cred) 15639483Smckusick struct vnode *vp; 15739483Smckusick register int com; 15839483Smckusick caddr_t data; 15939483Smckusick int fflag; 16039483Smckusick struct ucred *cred; 16139483Smckusick { 16239483Smckusick int locked = 0; 16339483Smckusick 16439483Smckusick /* 16539483Smckusick * We have to wait during times when the vnode is 16639483Smckusick * in a state of change. 16739483Smckusick */ 16839483Smckusick while (vp->v_flag & VXLOCK) { 16939483Smckusick vp->v_flag |= VXWANT; 17039483Smckusick sleep((caddr_t)vp, PINOD); 17139483Smckusick locked = 1; 17239483Smckusick } 17339483Smckusick if (!locked) 17439483Smckusick return (EBADF); 17539483Smckusick return (VOP_IOCTL(vp, com, data, fflag, cred)); 17639483Smckusick } 17739483Smckusick 17839483Smckusick /* ARGSUSED */ 17939483Smckusick dead_select(vp, which, cred) 18039483Smckusick struct vnode *vp; 18139483Smckusick int which; 18239483Smckusick struct ucred *cred; 18339483Smckusick { 18439483Smckusick 18539483Smckusick /* 18639483Smckusick * Let the user find out that the descriptor is gone. 18739483Smckusick */ 18839483Smckusick return (1); 18939483Smckusick } 19039483Smckusick 19139483Smckusick /* 19239483Smckusick * Just call the device strategy routine 19339483Smckusick */ 19439483Smckusick dead_strategy(bp) 19539483Smckusick register struct buf *bp; 19639483Smckusick { 19739483Smckusick int locked = 0; 19839483Smckusick 19939483Smckusick /* 20039483Smckusick * We have to wait during times when the vnode is 20139483Smckusick * in a state of change. 20239483Smckusick */ 20339483Smckusick while (bp->b_vp->v_flag & VXLOCK) { 20439483Smckusick bp->b_vp->v_flag |= VXWANT; 20539483Smckusick sleep((caddr_t)bp->b_vp, PINOD); 20639483Smckusick locked = 1; 20739483Smckusick } 208*39518Smckusick if (!locked) { 209*39518Smckusick bp->b_flags |= B_ERROR; 21039483Smckusick return (EIO); 211*39518Smckusick } 21239483Smckusick return (VOP_STRATEGY(bp)); 21339483Smckusick } 21439483Smckusick 21539483Smckusick /* 21639483Smckusick * Wait until the vnode has finished changing state. 21739483Smckusick */ 21839483Smckusick dead_lock(vp) 21939483Smckusick struct vnode *vp; 22039483Smckusick { 22139483Smckusick int locked = 0; 22239483Smckusick 22339483Smckusick /* 22439483Smckusick * We have to wait during times when the vnode is 22539483Smckusick * in a state of change. 22639483Smckusick */ 22739483Smckusick while (vp->v_flag & VXLOCK) { 22839483Smckusick vp->v_flag |= VXWANT; 22939483Smckusick sleep((caddr_t)vp, PINOD); 23039483Smckusick locked = 1; 23139483Smckusick } 23239483Smckusick if (!locked) 23339483Smckusick return (0); 23439483Smckusick return (VOP_LOCK(vp)); 23539483Smckusick } 23639483Smckusick 23739483Smckusick /* 23839508Smckusick * Wait until the vnode has finished changing state. 23939508Smckusick */ 24039508Smckusick dead_bmap(vp, bn, vpp, bnp) 24139508Smckusick struct vnode *vp; 24239508Smckusick daddr_t bn; 24339508Smckusick struct vnode **vpp; 24439508Smckusick daddr_t *bnp; 24539508Smckusick { 24639508Smckusick int locked = 0; 24739508Smckusick 24839508Smckusick /* 24939508Smckusick * We have to wait during times when the vnode is 25039508Smckusick * in a state of change. 25139508Smckusick */ 25239508Smckusick while (vp->v_flag & VXLOCK) { 25339508Smckusick vp->v_flag |= VXWANT; 25439508Smckusick sleep((caddr_t)vp, PINOD); 25539508Smckusick locked = 1; 25639508Smckusick } 25739508Smckusick if (!locked) 25839508Smckusick return (EIO); 25939508Smckusick return (VOP_BMAP(vp, bn, vpp, bnp)); 26039508Smckusick } 26139508Smckusick 26239508Smckusick /* 26339486Smckusick * Empty vnode failed operation 26439486Smckusick */ 26539486Smckusick dead_ebadf() 26639486Smckusick { 26739486Smckusick 26839486Smckusick return (EBADF); 26939486Smckusick } 27039486Smckusick 27139486Smckusick /* 27239483Smckusick * Empty vnode bad operation 27339483Smckusick */ 27439483Smckusick dead_badop() 27539483Smckusick { 27639483Smckusick 27739483Smckusick panic("dead_badop called"); 27839483Smckusick /* NOTREACHED */ 27939483Smckusick } 28039483Smckusick 28139483Smckusick /* 28239483Smckusick * Empty vnode null operation 28339483Smckusick */ 28439483Smckusick dead_nullop() 28539483Smckusick { 28639483Smckusick 28739483Smckusick return (0); 28839483Smckusick } 289