Annotation of sys/miscfs/deadfs/dead_vnops.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: dead_vnops.c,v 1.18 2007/06/01 23:47:57 deraadt Exp $ */
2: /* $NetBSD: dead_vnops.c,v 1.16 1996/02/13 13:12:48 mycroft Exp $ */
3:
4: /*
5: * Copyright (c) 1989, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. Neither the name of the University nor the names of its contributors
17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: *
32: * @(#)dead_vnops.c 8.2 (Berkeley) 11/21/94
33: */
34:
35: #include <sys/param.h>
36: #include <sys/systm.h>
37: #include <sys/time.h>
38: #include <sys/vnode.h>
39: #include <sys/errno.h>
40: #include <sys/namei.h>
41: #include <sys/buf.h>
42: #include <sys/proc.h>
43: #include <sys/poll.h>
44:
45: /*
46: * Prototypes for dead operations on vnodes.
47: */
48: int dead_badop(void *);
49: int dead_ebadf(void *);
50:
51: int dead_lookup(void *);
52: #define dead_create dead_badop
53: #define dead_mknod dead_badop
54: int dead_open(void *);
55: #define dead_close nullop
56: #define dead_access dead_ebadf
57: #define dead_getattr dead_ebadf
58: #define dead_setattr dead_ebadf
59: int dead_read(void *);
60: int dead_write(void *);
61: int dead_ioctl(void *);
62: int dead_poll(void *);
63: #define dead_fsync nullop
64: #define dead_remove dead_badop
65: #define dead_link dead_badop
66: #define dead_rename dead_badop
67: #define dead_mkdir dead_badop
68: #define dead_rmdir dead_badop
69: #define dead_symlink dead_badop
70: #define dead_readdir dead_ebadf
71: #define dead_readlink dead_ebadf
72: #define dead_abortop dead_badop
73: #define dead_inactive nullop
74: #define dead_reclaim nullop
75: int dead_lock(void *);
76: #define dead_unlock vop_generic_unlock
77: int dead_bmap(void *);
78: int dead_strategy(void *);
79: int dead_print(void *);
80: #define dead_islocked vop_generic_islocked
81: #define dead_pathconf dead_ebadf
82: #define dead_advlock dead_ebadf
83: #define dead_bwrite nullop
84:
85: int chkvnlock(struct vnode *);
86:
87: int (**dead_vnodeop_p)(void *);
88:
89: struct vnodeopv_entry_desc dead_vnodeop_entries[] = {
90: { &vop_default_desc, vn_default_error },
91: { &vop_lookup_desc, dead_lookup }, /* lookup */
92: { &vop_create_desc, dead_create }, /* create */
93: { &vop_mknod_desc, dead_mknod }, /* mknod */
94: { &vop_open_desc, dead_open }, /* open */
95: { &vop_close_desc, dead_close }, /* close */
96: { &vop_access_desc, dead_access }, /* access */
97: { &vop_getattr_desc, dead_getattr }, /* getattr */
98: { &vop_setattr_desc, dead_setattr }, /* setattr */
99: { &vop_read_desc, dead_read }, /* read */
100: { &vop_write_desc, dead_write }, /* write */
101: { &vop_ioctl_desc, dead_ioctl }, /* ioctl */
102: { &vop_poll_desc, dead_poll }, /* poll */
103: { &vop_fsync_desc, dead_fsync }, /* fsync */
104: { &vop_remove_desc, dead_remove }, /* remove */
105: { &vop_link_desc, dead_link }, /* link */
106: { &vop_rename_desc, dead_rename }, /* rename */
107: { &vop_mkdir_desc, dead_mkdir }, /* mkdir */
108: { &vop_rmdir_desc, dead_rmdir }, /* rmdir */
109: { &vop_symlink_desc, dead_symlink }, /* symlink */
110: { &vop_readdir_desc, dead_readdir }, /* readdir */
111: { &vop_readlink_desc, dead_readlink }, /* readlink */
112: { &vop_abortop_desc, dead_abortop }, /* abortop */
113: { &vop_inactive_desc, dead_inactive }, /* inactive */
114: { &vop_reclaim_desc, dead_reclaim }, /* reclaim */
115: { &vop_lock_desc, dead_lock }, /* lock */
116: { &vop_unlock_desc, dead_unlock }, /* unlock */
117: { &vop_bmap_desc, dead_bmap }, /* bmap */
118: { &vop_strategy_desc, dead_strategy }, /* strategy */
119: { &vop_print_desc, dead_print }, /* print */
120: { &vop_islocked_desc, dead_islocked }, /* islocked */
121: { &vop_pathconf_desc, dead_pathconf }, /* pathconf */
122: { &vop_advlock_desc, dead_advlock }, /* advlock */
123: { &vop_bwrite_desc, dead_bwrite }, /* bwrite */
124: { (struct vnodeop_desc*)NULL, (int(*)(void *))NULL }
125: };
126: struct vnodeopv_desc dead_vnodeop_opv_desc =
127: { &dead_vnodeop_p, dead_vnodeop_entries };
128:
129: /*
130: * Trivial lookup routine that always fails.
131: */
132: /* ARGSUSED */
133: int
134: dead_lookup(void *v)
135: {
136: struct vop_lookup_args *ap = v;
137:
138: *ap->a_vpp = NULL;
139: return (ENOTDIR);
140: }
141:
142: /*
143: * Open always fails as if device did not exist.
144: */
145: /* ARGSUSED */
146: int
147: dead_open(void *v)
148: {
149: return (ENXIO);
150: }
151:
152: /*
153: * Vnode op for read
154: */
155: /* ARGSUSED */
156: int
157: dead_read(void *v)
158: {
159: struct vop_read_args *ap = v;
160:
161: if (chkvnlock(ap->a_vp))
162: panic("dead_read: lock");
163: /*
164: * Return EOF for tty devices, EIO for others
165: */
166: if ((ap->a_vp->v_flag & VISTTY) == 0)
167: return (EIO);
168: return (0);
169: }
170:
171: /*
172: * Vnode op for write
173: */
174: /* ARGSUSED */
175: int
176: dead_write(void *v)
177: {
178: struct vop_write_args *ap = v;
179:
180: if (chkvnlock(ap->a_vp))
181: panic("dead_write: lock");
182: return (EIO);
183: }
184:
185: /*
186: * Device ioctl operation.
187: */
188: /* ARGSUSED */
189: int
190: dead_ioctl(void *v)
191: {
192: struct vop_ioctl_args *ap = v;
193:
194: if (!chkvnlock(ap->a_vp))
195: return (EBADF);
196: return (VCALL(ap->a_vp, VOFFSET(vop_ioctl), ap));
197: }
198:
199: /* ARGSUSED */
200: int
201: dead_poll(void *v)
202: {
203: #if 0
204: struct vop_poll_args *ap = v;
205: #endif
206:
207: /*
208: * Let the user find out that the descriptor is gone.
209: */
210: return (POLLHUP);
211: }
212:
213: /*
214: * Just call the device strategy routine
215: */
216: int
217: dead_strategy(void *v)
218: {
219: struct vop_strategy_args *ap = v;
220: int s;
221:
222: if (ap->a_bp->b_vp == NULL || !chkvnlock(ap->a_bp->b_vp)) {
223: ap->a_bp->b_flags |= B_ERROR;
224: s = splbio();
225: biodone(ap->a_bp);
226: splx(s);
227: return (EIO);
228: }
229: return (VOP_STRATEGY(ap->a_bp));
230: }
231:
232: /*
233: * Wait until the vnode has finished changing state.
234: */
235: int
236: dead_lock(void *v)
237: {
238: struct vop_lock_args *ap = v;
239: struct vnode *vp = ap->a_vp;
240:
241: if (ap->a_flags & LK_DRAIN || !chkvnlock(vp))
242: return (0);
243:
244: return (VCALL(vp, VOFFSET(vop_lock), ap));
245: }
246:
247: /*
248: * Wait until the vnode has finished changing state.
249: */
250: int
251: dead_bmap(void *v)
252: {
253: struct vop_bmap_args *ap = v;
254:
255: if (!chkvnlock(ap->a_vp))
256: return (EIO);
257: return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp, ap->a_runp));
258: }
259:
260: /*
261: * Print out the contents of a dead vnode.
262: */
263: /* ARGSUSED */
264: int
265: dead_print(void *v)
266: {
267: printf("tag VT_NON, dead vnode\n");
268: return 0;
269: }
270:
271: /*
272: * Empty vnode failed operation
273: */
274: /*ARGSUSED*/
275: int
276: dead_ebadf(void *v)
277: {
278: return (EBADF);
279: }
280:
281: /*
282: * Empty vnode bad operation
283: */
284: /*ARGSUSED*/
285: int
286: dead_badop(void *v)
287: {
288: panic("dead_badop called");
289: /* NOTREACHED */
290: }
291:
292: /*
293: * We have to wait during times when the vnode is
294: * in a state of change.
295: */
296: int
297: chkvnlock(struct vnode *vp)
298: {
299: int locked = 0;
300:
301: while (vp->v_flag & VXLOCK) {
302: vp->v_flag |= VXWANT;
303: tsleep(vp, PINOD, "chkvnlock", 0);
304: locked = 1;
305: }
306: return (locked);
307: }
CVSweb