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*39853Smckusick * @(#)dead_vnops.c 7.7 (Berkeley) 01/02/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(), 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 */ 10239591Smckusick /* ARGSUSED */ 10339591Smckusick dead_read(vp, uio, ioflag, cred) 10439483Smckusick struct vnode *vp; 10539483Smckusick struct uio *uio; 10639483Smckusick int ioflag; 10739483Smckusick struct ucred *cred; 10839483Smckusick { 10939483Smckusick 11039591Smckusick if (chkvnlock(vp)) 11139591Smckusick panic("dead_read: lock"); 11239591Smckusick /* 11339591Smckusick * Return EOF for character devices, EIO for others 11439591Smckusick */ 11539591Smckusick if (vp->v_type != VCHR) 11639483Smckusick return (EIO); 11739591Smckusick return (0); 11839483Smckusick } 11939483Smckusick 12039483Smckusick /* 12139483Smckusick * Vnode op for write 12239483Smckusick */ 12339591Smckusick /* ARGSUSED */ 12439591Smckusick dead_write(vp, uio, ioflag, cred) 12539483Smckusick register struct vnode *vp; 12639483Smckusick struct uio *uio; 12739483Smckusick int ioflag; 12839483Smckusick struct ucred *cred; 12939483Smckusick { 13039483Smckusick 13139591Smckusick if (chkvnlock(vp)) 13239591Smckusick panic("dead_write: lock"); 13339591Smckusick 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; 175*39853Smckusick biodone(bp); 17639483Smckusick return (EIO); 17739518Smckusick } 17839483Smckusick return (VOP_STRATEGY(bp)); 17939483Smckusick } 18039483Smckusick 18139483Smckusick /* 18239483Smckusick * Wait until the vnode has finished changing state. 18339483Smckusick */ 18439483Smckusick dead_lock(vp) 18539483Smckusick struct vnode *vp; 18639483Smckusick { 18739483Smckusick 18839519Smckusick if (!chkvnlock(vp)) 18939483Smckusick return (0); 19039483Smckusick return (VOP_LOCK(vp)); 19139483Smckusick } 19239483Smckusick 19339483Smckusick /* 19439508Smckusick * Wait until the vnode has finished changing state. 19539508Smckusick */ 19639508Smckusick dead_bmap(vp, bn, vpp, bnp) 19739508Smckusick struct vnode *vp; 19839508Smckusick daddr_t bn; 19939508Smckusick struct vnode **vpp; 20039508Smckusick daddr_t *bnp; 20139508Smckusick { 20239508Smckusick 20339519Smckusick if (!chkvnlock(vp)) 20439508Smckusick return (EIO); 20539508Smckusick return (VOP_BMAP(vp, bn, vpp, bnp)); 20639508Smckusick } 20739508Smckusick 20839508Smckusick /* 20939486Smckusick * Empty vnode failed operation 21039486Smckusick */ 21139486Smckusick dead_ebadf() 21239486Smckusick { 21339486Smckusick 21439486Smckusick return (EBADF); 21539486Smckusick } 21639486Smckusick 21739486Smckusick /* 21839483Smckusick * Empty vnode bad operation 21939483Smckusick */ 22039483Smckusick dead_badop() 22139483Smckusick { 22239483Smckusick 22339483Smckusick panic("dead_badop called"); 22439483Smckusick /* NOTREACHED */ 22539483Smckusick } 22639483Smckusick 22739483Smckusick /* 22839483Smckusick * Empty vnode null operation 22939483Smckusick */ 23039483Smckusick dead_nullop() 23139483Smckusick { 23239483Smckusick 23339483Smckusick return (0); 23439483Smckusick } 23539519Smckusick 23639519Smckusick /* 23739519Smckusick * We have to wait during times when the vnode is 23839519Smckusick * in a state of change. 23939519Smckusick */ 24039519Smckusick chkvnlock(vp) 24139519Smckusick register struct vnode *vp; 24239519Smckusick { 24339519Smckusick int locked = 0; 24439519Smckusick 24539519Smckusick while (vp->v_flag & VXLOCK) { 24639519Smckusick vp->v_flag |= VXWANT; 24739519Smckusick sleep((caddr_t)vp, PINOD); 24839519Smckusick locked = 1; 24939519Smckusick } 25039519Smckusick return (locked); 25139519Smckusick } 252