1 /* $NetBSD: dead_vnops.c,v 1.47 2008/01/25 14:32:15 ad Exp $ */
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * @(#)dead_vnops.c 8.2 (Berkeley) 11/21/94
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: dead_vnops.c,v 1.47 2008/01/25 14:32:15 ad Exp $");
37 #include <sys/param.h>
38 #include <sys/systm.h>
40 #include <sys/vnode.h>
41 #include <sys/errno.h>
42 #include <sys/namei.h>
46 #include <miscfs/genfs/genfs.h>
49 * Prototypes for dead operations on vnodes.
51 int dead_open(void *);
52 #define dead_close genfs_nullop
53 int dead_read(void *);
54 int dead_write(void *);
55 #define dead_fcntl genfs_nullop
56 int dead_ioctl(void *);
57 int dead_poll(void *);
58 #define dead_fsync genfs_nullop
59 #define dead_seek genfs_nullop
60 #define dead_inactive genfs_nullop
61 #define dead_reclaim genfs_nullop
62 int dead_lock(void *);
63 #define dead_unlock genfs_nullop
64 int dead_bmap(void *);
65 int dead_strategy(void *);
66 int dead_print(void *);
67 #define dead_islocked genfs_nullop
68 #define dead_bwrite genfs_nullop
69 #define dead_revoke genfs_nullop
70 int dead_getpages(void *);
71 #define dead_putpages genfs_null_putpages
73 int chkvnlock(struct vnode
*, bool);
74 int dead_default_error(void *);
76 int (**dead_vnodeop_p
)(void *);
78 const struct vnodeopv_entry_desc dead_vnodeop_entries
[] = {
79 { &vop_default_desc
, dead_default_error
},
80 { &vop_open_desc
, dead_open
}, /* open */
81 { &vop_close_desc
, dead_close
}, /* close */
82 { &vop_read_desc
, dead_read
}, /* read */
83 { &vop_write_desc
, dead_write
}, /* write */
84 { &vop_fcntl_desc
, dead_fcntl
}, /* fcntl */
85 { &vop_ioctl_desc
, dead_ioctl
}, /* ioctl */
86 { &vop_poll_desc
, dead_poll
}, /* poll */
87 { &vop_revoke_desc
, dead_revoke
}, /* revoke */
88 { &vop_fsync_desc
, dead_fsync
}, /* fsync */
89 { &vop_seek_desc
, dead_seek
}, /* seek */
90 { &vop_inactive_desc
, dead_inactive
}, /* inactive */
91 { &vop_reclaim_desc
, dead_reclaim
}, /* reclaim */
92 { &vop_lock_desc
, dead_lock
}, /* lock */
93 { &vop_unlock_desc
, dead_unlock
}, /* unlock */
94 { &vop_bmap_desc
, dead_bmap
}, /* bmap */
95 { &vop_strategy_desc
, dead_strategy
}, /* strategy */
96 { &vop_print_desc
, dead_print
}, /* print */
97 { &vop_islocked_desc
, dead_islocked
}, /* islocked */
98 { &vop_bwrite_desc
, dead_bwrite
}, /* bwrite */
99 { &vop_getpages_desc
, dead_getpages
}, /* getpages */
100 { &vop_putpages_desc
, dead_putpages
}, /* putpages */
103 const struct vnodeopv_desc dead_vnodeop_opv_desc
=
104 { &dead_vnodeop_p
, dead_vnodeop_entries
};
107 dead_default_error(void *v
)
114 * Open always fails as if device did not exist.
131 struct vop_read_args
/* {
138 if (chkvnlock(ap
->a_vp
, false))
139 panic("dead_read: lock");
141 * Return EOF for tty devices, EIO for others
143 if ((ap
->a_vp
->v_vflag
& VV_ISTTY
) == 0)
155 struct vop_write_args
/* {
162 if (chkvnlock(ap
->a_vp
, false))
163 panic("dead_write: lock");
168 * Device ioctl operation.
174 struct vop_ioctl_args
/* {
183 if (!chkvnlock(ap
->a_vp
, false))
185 return (VCALL(ap
->a_vp
, VOFFSET(vop_ioctl
), ap
));
192 struct vop_poll_args
/* {
199 * Let the user find out that the descriptor is gone.
201 return (ap
->a_events
);
205 * Just call the device strategy routine
208 dead_strategy(void *v
)
211 struct vop_strategy_args
/* {
216 if (ap
->a_vp
== NULL
|| !chkvnlock(ap
->a_vp
, false)) {
219 bp
->b_resid
= bp
->b_bcount
;
223 return (VOP_STRATEGY(ap
->a_vp
, ap
->a_bp
));
227 * Wait until the vnode has finished changing state.
232 struct vop_lock_args
/* {
239 if (ap
->a_flags
& LK_INTERLOCK
) {
241 ap
->a_flags
&= ~LK_INTERLOCK
;
244 if (!chkvnlock(ap
->a_vp
, interlock
))
246 return (VCALL(ap
->a_vp
, VOFFSET(vop_lock
), ap
));
250 * Wait until the vnode has finished changing state.
255 struct vop_bmap_args
/* {
258 struct vnode **a_vpp;
263 if (!chkvnlock(ap
->a_vp
, false))
265 return (VOP_BMAP(ap
->a_vp
, ap
->a_bn
, ap
->a_vpp
, ap
->a_bnp
, ap
->a_runp
));
269 * Print out the contents of a dead vnode.
275 printf("tag VT_NON, dead vnode\n");
280 dead_getpages(void *v
)
282 struct vop_getpages_args
/* {
285 struct vm_page **a_m;
288 vm_prot_t a_access_type;
293 if ((ap
->a_flags
& PGO_LOCKED
) == 0)
294 mutex_exit(&ap
->a_vp
->v_interlock
);
300 * We have to wait during times when the vnode is
301 * in a state of change.
304 chkvnlock(struct vnode
*vp
, bool interlock
)
309 mutex_enter(&vp
->v_interlock
);
310 while (vp
->v_iflag
& VI_XLOCK
) {
314 mutex_exit(&vp
->v_interlock
);