]> git.saurik.com Git - apple/xnu.git/blame - bsd/miscfs/deadfs/dead_vnops.c
xnu-344.21.73.tar.gz
[apple/xnu.git] / bsd / miscfs / deadfs / dead_vnops.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
d7e50217 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
d7e50217
A
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
d7e50217
A
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
1c79356b
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
26/*
27 * Copyright (c) 1989, 1993
28 * The Regents of the University of California. All rights reserved.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by the University of
41 * California, Berkeley and its contributors.
42 * 4. Neither the name of the University nor the names of its contributors
43 * may be used to endorse or promote products derived from this software
44 * without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 *
58 * @(#)dead_vnops.c 8.3 (Berkeley) 5/14/95
59 */
60
61#include <sys/param.h>
62#include <sys/systm.h>
63#include <sys/time.h>
64#include <sys/vnode.h>
65#include <sys/errno.h>
66#include <sys/namei.h>
67#include <sys/buf.h>
68#include <vfs/vfs_support.h>
69
70/*
71 * Prototypes for dead operations on vnodes.
72 */
73int dead_badop(),
74 dead_ebadf();
75int dead_lookup __P((struct vop_lookup_args *));
76#define dead_create ((int (*) __P((struct vop_create_args *)))dead_badop)
77#define dead_mknod ((int (*) __P((struct vop_mknod_args *)))dead_badop)
78int dead_open __P((struct vop_open_args *));
79#define dead_close ((int (*) __P((struct vop_close_args *)))nullop)
80#define dead_access ((int (*) __P((struct vop_access_args *)))dead_ebadf)
81#define dead_getattr ((int (*) __P((struct vop_getattr_args *)))dead_ebadf)
82#define dead_setattr ((int (*) __P((struct vop_setattr_args *)))dead_ebadf)
83int dead_read __P((struct vop_read_args *));
84int dead_write __P((struct vop_write_args *));
85int dead_ioctl __P((struct vop_ioctl_args *));
86int dead_select __P((struct vop_select_args *));
87#define dead_mmap ((int (*) __P((struct vop_mmap_args *)))dead_badop)
88#define dead_fsync ((int (*) __P((struct vop_fsync_args *)))nullop)
89#define dead_seek ((int (*) __P((struct vop_seek_args *)))nullop)
90#define dead_remove ((int (*) __P((struct vop_remove_args *)))dead_badop)
91#define dead_link ((int (*) __P((struct vop_link_args *)))dead_badop)
92#define dead_rename ((int (*) __P((struct vop_rename_args *)))dead_badop)
93#define dead_mkdir ((int (*) __P((struct vop_mkdir_args *)))dead_badop)
94#define dead_rmdir ((int (*) __P((struct vop_rmdir_args *)))dead_badop)
95#define dead_symlink ((int (*) __P((struct vop_symlink_args *)))dead_badop)
96#define dead_readdir ((int (*) __P((struct vop_readdir_args *)))dead_ebadf)
97#define dead_readlink ((int (*) __P((struct vop_readlink_args *)))dead_ebadf)
98#define dead_abortop ((int (*) __P((struct vop_abortop_args *)))dead_badop)
99#define dead_inactive ((int (*) __P((struct vop_inactive_args *)))nullop)
100#define dead_reclaim ((int (*) __P((struct vop_reclaim_args *)))nullop)
101int dead_lock __P((struct vop_lock_args *));
102#define dead_unlock ((int (*) __P((struct vop_unlock_args *)))nullop)
103int dead_bmap __P((struct vop_bmap_args *));
104int dead_strategy __P((struct vop_strategy_args *));
105int dead_print __P((struct vop_print_args *));
106#define dead_islocked ((int (*) __P((struct vop_islocked_args *)))nullop)
107#define dead_pathconf ((int (*) __P((struct vop_pathconf_args *)))dead_ebadf)
108#define dead_advlock ((int (*) __P((struct vop_advlock_args *)))dead_ebadf)
109#define dead_blkatoff ((int (*) __P((struct vop_blkatoff_args *)))dead_badop)
110#define dead_valloc ((int (*) __P((struct vop_valloc_args *)))dead_badop)
111#define dead_vfree ((int (*) __P((struct vop_vfree_args *)))dead_badop)
112#define dead_truncate ((int (*) __P((struct vop_truncate_args *)))nullop)
113#define dead_update ((int (*) __P((struct vop_update_args *)))nullop)
114#define dead_bwrite ((int (*) __P((struct vop_bwrite_args *)))nullop)
115int dead_pagein __P((struct vop_pagein_args *));
116int dead_pageout __P((struct vop_pageout_args *));
117int dead_blktooff __P((struct vop_blktooff_args *));
118int dead_offtoblk __P((struct vop_offtoblk_args *));
119int dead_cmap __P((struct vop_cmap_args *));
120
121#define VOPFUNC int (*)(void *)
122int (**dead_vnodeop_p)(void *);
123struct vnodeopv_entry_desc dead_vnodeop_entries[] = {
124 { &vop_default_desc, (VOPFUNC)vn_default_error },
125 { &vop_lookup_desc, (VOPFUNC)dead_lookup }, /* lookup */
126 { &vop_create_desc, (VOPFUNC)dead_create }, /* create */
127 { &vop_mknod_desc, (VOPFUNC)dead_mknod }, /* mknod */
128 { &vop_open_desc, (VOPFUNC)dead_open }, /* open */
129 { &vop_close_desc, (VOPFUNC)dead_close }, /* close */
130 { &vop_access_desc, (VOPFUNC)dead_access }, /* access */
131 { &vop_getattr_desc, (VOPFUNC)dead_getattr }, /* getattr */
132 { &vop_setattr_desc, (VOPFUNC)dead_setattr }, /* setattr */
133 { &vop_read_desc, (VOPFUNC)dead_read }, /* read */
134 { &vop_write_desc, (VOPFUNC)dead_write }, /* write */
135 { &vop_ioctl_desc, (VOPFUNC)dead_ioctl }, /* ioctl */
136 { &vop_select_desc, (VOPFUNC)dead_select }, /* select */
137 { &vop_mmap_desc, (VOPFUNC)dead_mmap }, /* mmap */
138 { &vop_fsync_desc, (VOPFUNC)dead_fsync }, /* fsync */
139 { &vop_seek_desc, (VOPFUNC)dead_seek }, /* seek */
140 { &vop_remove_desc, (VOPFUNC)dead_remove }, /* remove */
141 { &vop_link_desc, (VOPFUNC)dead_link }, /* link */
142 { &vop_rename_desc, (VOPFUNC)dead_rename }, /* rename */
143 { &vop_mkdir_desc, (VOPFUNC)dead_mkdir }, /* mkdir */
144 { &vop_rmdir_desc, (VOPFUNC)dead_rmdir }, /* rmdir */
145 { &vop_symlink_desc, (VOPFUNC)dead_symlink }, /* symlink */
146 { &vop_readdir_desc, (VOPFUNC)dead_readdir }, /* readdir */
147 { &vop_readlink_desc, (VOPFUNC)dead_readlink }, /* readlink */
148 { &vop_abortop_desc, (VOPFUNC)dead_abortop }, /* abortop */
149 { &vop_inactive_desc, (VOPFUNC)dead_inactive }, /* inactive */
150 { &vop_reclaim_desc, (VOPFUNC)dead_reclaim }, /* reclaim */
151 { &vop_lock_desc, (VOPFUNC)dead_lock }, /* lock */
152 { &vop_unlock_desc, (VOPFUNC)dead_unlock }, /* unlock */
153 { &vop_bmap_desc, (VOPFUNC)dead_bmap }, /* bmap */
154 { &vop_strategy_desc, (VOPFUNC)dead_strategy }, /* strategy */
155 { &vop_print_desc, (VOPFUNC)dead_print }, /* print */
156 { &vop_islocked_desc, (VOPFUNC)dead_islocked }, /* islocked */
157 { &vop_pathconf_desc, (VOPFUNC)dead_pathconf }, /* pathconf */
158 { &vop_advlock_desc, (VOPFUNC)dead_advlock }, /* advlock */
159 { &vop_blkatoff_desc, (VOPFUNC)dead_blkatoff }, /* blkatoff */
160 { &vop_valloc_desc, (VOPFUNC)dead_valloc }, /* valloc */
161 { &vop_vfree_desc, (VOPFUNC)dead_vfree }, /* vfree */
162 { &vop_truncate_desc, (VOPFUNC)dead_truncate }, /* truncate */
163 { &vop_update_desc, (VOPFUNC)dead_update }, /* update */
164 { &vop_bwrite_desc, (VOPFUNC)dead_bwrite }, /* bwrite */
165 { &vop_pagein_desc, (VOPFUNC)err_pagein }, /* Pagein */
166 { &vop_pageout_desc, (VOPFUNC)err_pageout }, /* Pageout */
167 { &vop_copyfile_desc, (VOPFUNC)err_copyfile }, /* Copyfile */
168 { &vop_blktooff_desc, (VOPFUNC)dead_blktooff }, /* blktooff */
169 { &vop_offtoblk_desc, (VOPFUNC)dead_offtoblk }, /* offtoblk */
170 { &vop_cmap_desc, (VOPFUNC)dead_cmap }, /* cmap */
171 { (struct vnodeop_desc*)NULL, (VOPFUNC)NULL }
172};
173struct vnodeopv_desc dead_vnodeop_opv_desc =
174 { &dead_vnodeop_p, dead_vnodeop_entries };
175
176/*
177 * Trivial lookup routine that always fails.
178 */
179/* ARGSUSED */
180int
181dead_lookup(ap)
182 struct vop_lookup_args /* {
183 struct vnode * a_dvp;
184 struct vnode ** a_vpp;
185 struct componentname * a_cnp;
186 } */ *ap;
187{
188
189 *ap->a_vpp = NULL;
190 return (ENOTDIR);
191}
192
193/*
194 * Open always fails as if device did not exist.
195 */
196/* ARGSUSED */
197int
198dead_open(ap)
199 struct vop_open_args /* {
200 struct vnode *a_vp;
201 int a_mode;
202 struct ucred *a_cred;
203 struct proc *a_p;
204 } */ *ap;
205{
206
207 return (ENXIO);
208}
209
210/*
211 * Vnode op for read
212 */
213/* ARGSUSED */
214int
215dead_read(ap)
216 struct vop_read_args /* {
217 struct vnode *a_vp;
218 struct uio *a_uio;
219 int a_ioflag;
220 struct ucred *a_cred;
221 } */ *ap;
222{
223
224 if (chkvnlock(ap->a_vp))
225 panic("dead_read: lock");
226 /*
227 * Return EOF for character devices, EIO for others
228 */
229 if (ap->a_vp->v_type != VCHR)
230 return (EIO);
231 return (0);
232}
233
234/*
235 * Vnode op for write
236 */
237/* ARGSUSED */
238int
239dead_write(ap)
240 struct vop_write_args /* {
241 struct vnode *a_vp;
242 struct uio *a_uio;
243 int a_ioflag;
244 struct ucred *a_cred;
245 } */ *ap;
246{
247
248 if (chkvnlock(ap->a_vp))
249 panic("dead_write: lock");
250 return (EIO);
251}
252
253/*
254 * Device ioctl operation.
255 */
256/* ARGSUSED */
257int
258dead_ioctl(ap)
259 struct vop_ioctl_args /* {
260 struct vnode *a_vp;
261 u_long a_command;
262 caddr_t a_data;
263 int a_fflag;
264 struct ucred *a_cred;
265 struct proc *a_p;
266 } */ *ap;
267{
268
269 if (!chkvnlock(ap->a_vp))
270 return (EBADF);
271 return (VCALL(ap->a_vp, VOFFSET(vop_ioctl), ap));
272}
273
274/* ARGSUSED */
275int
276dead_select(ap)
277 struct vop_select_args /* {
278 struct vnode *a_vp;
279 int a_which;
280 int a_fflags;
281 struct ucred *a_cred;
0b4e3aa0 282 void *a_wql;
1c79356b
A
283 struct proc *a_p;
284 } */ *ap;
285{
286
287 /*
288 * Let the user find out that the descriptor is gone.
289 */
290 return (1);
291}
292
293/*
294 * Just call the device strategy routine
295 */
296int
297dead_strategy(ap)
298 struct vop_strategy_args /* {
299 struct buf *a_bp;
300 } */ *ap;
301{
302
303 if (ap->a_bp->b_vp == NULL || !chkvnlock(ap->a_bp->b_vp)) {
304 ap->a_bp->b_flags |= B_ERROR;
305 biodone(ap->a_bp);
306 return (EIO);
307 }
308 return (VOP_STRATEGY(ap->a_bp));
309}
310
311/*
312 * Wait until the vnode has finished changing state.
313 */
314int
315dead_lock(ap)
316 struct vop_lock_args /* {
317 struct vnode *a_vp;
318 } */ *ap;
319{
320
321 struct vnode *vp = ap->a_vp;
322
323 /*
324 * Since we are not using the lock manager, we must clear
325 * the interlock here.
326 */
327 if (ap->a_flags & LK_INTERLOCK) {
328 simple_unlock(&vp->v_interlock);
329 ap->a_flags &= ~LK_INTERLOCK;
330 }
331 if (!chkvnlock(ap->a_vp))
332 return (0);
333 return (VCALL(ap->a_vp, VOFFSET(vop_lock), ap));
334}
335
336/*
337 * Wait until the vnode has finished changing state.
338 */
339int
340dead_bmap(ap)
341 struct vop_bmap_args /* {
342 struct vnode *a_vp;
343 daddr_t a_bn;
344 struct vnode **a_vpp;
345 daddr_t *a_bnp;
346 int *a_runp;
347 } */ *ap;
348{
349
350 if (!chkvnlock(ap->a_vp))
351 return (EIO);
352 return (VOP_BMAP(ap->a_vp, ap->a_bn, ap->a_vpp, ap->a_bnp, ap->a_runp));
353}
354
355/*
356 * Wait until the vnode has finished changing state.
357 */
358int
359dead_cmap(ap)
360 struct vop_cmap_args /* {
361 struct vnode *a_vp;
362 off_t a_foffset;
363 size_t a_size;
364 daddr_t *a_bpn;
365 size_t *a_run;
366 void *a_poff;
367 } */ *ap;
368{
369
370 if (!chkvnlock(ap->a_vp))
371 return (EIO);
372 return (VOP_CMAP(ap->a_vp, ap->a_foffset, ap->a_size, ap->a_bpn, ap->a_run, ap->a_poff));
373}
374
375/*
376 * Print out the contents of a dead vnode.
377 */
378/* ARGSUSED */
379int
380dead_print(ap)
381 struct vop_print_args /* {
382 struct vnode *a_vp;
383 } */ *ap;
384{
385
386 printf("tag VT_NON, dead vnode\n");
387}
388
389/*
390 * Empty vnode failed operation
391 */
392int
393dead_ebadf()
394{
395
396 return (EBADF);
397}
398
399/*
400 * Empty vnode bad operation
401 */
402int
403dead_badop()
404{
405
406 panic("dead_badop called");
407 /* NOTREACHED */
408}
409
410/*
411 * Empty vnode null operation
412 */
413int
414dead_nullop()
415{
416
417 return (0);
418}
419
420/*
421 * We have to wait during times when the vnode is
422 * in a state of change.
423 */
424int
425chkvnlock(vp)
426 register struct vnode *vp;
427{
428 int locked = 0;
429
430 while (vp->v_flag & VXLOCK) {
431 vp->v_flag |= VXWANT;
432 sleep((caddr_t)vp, PINOD);
433 locked = 1;
434 }
435 return (locked);
436}
437
438
439/* Blktooff */
440int
441dead_blktooff(ap)
442 struct vop_blktooff_args /* {
443 struct vnode *a_vp;
444 daddr_t a_lblkno;
445 off_t *a_offset;
446 } */ *ap;
447{
448 if (!chkvnlock(ap->a_vp))
449 return (EIO);
450
451 *ap->a_offset = (off_t)-1; /* failure */
452 return (0);
453}
454/* Blktooff */
455int
456dead_offtoblk(ap)
457struct vop_offtoblk_args /* {
458 struct vnode *a_vp;
459 off_t a_offset;
460 daddr_t *a_lblkno;
461 } */ *ap;
462{
463 if (!chkvnlock(ap->a_vp))
464 return (EIO);
465
466 *ap->a_lblkno = (daddr_t)-1; /* failure */
467 return (0);
468}