avoid core dump on $> with no argument; fix sameaddr to avoid
[unix-history] / usr / src / sys / miscfs / kernfs / kernfs_vnops.c
CommitLineData
341568e0 1/*
99315dca
KB
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
341568e0
JSP
4 * All rights reserved.
5 *
6 * This code is derived from software donated to Berkeley by
7 * Jan-Simon Pendry.
8 *
9 * %sccs.include.redist.c%
10 *
99315dca 11 * @(#)kernfs_vnops.c 8.1 (Berkeley) %G%
341568e0
JSP
12 */
13
14/*
15 * Kernel parameter filesystem (/kern)
16 */
17
18#include <sys/param.h>
19#include <sys/systm.h>
20#include <sys/kernel.h>
21#include <sys/vmmeter.h>
22#include <sys/types.h>
23#include <sys/time.h>
24#include <sys/proc.h>
25#include <sys/vnode.h>
26#include <sys/malloc.h>
27#include <sys/file.h>
28#include <sys/stat.h>
29#include <sys/mount.h>
30#include <sys/namei.h>
31#include <sys/buf.h>
32#include <sys/dirent.h>
33#include <miscfs/kernfs/kernfs.h>
34
35#define KSTRING 256 /* Largest I/O available via this filesystem */
36#define UIO_MX 32
37
a1e23f7a
JSP
38#define READ_MODE (S_IRUSR|S_IRGRP|S_IROTH)
39#define WRITE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)
40#define DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
41
341568e0
JSP
42struct kern_target {
43 char *kt_name;
44 void *kt_data;
45#define KTT_NULL 1
46#define KTT_TIME 5
47#define KTT_INT 17
48#define KTT_STRING 31
49#define KTT_HOSTNAME 47
50#define KTT_AVENRUN 53
51 int kt_tag;
341568e0
JSP
52 int kt_rw;
53 int kt_vtype;
54} kern_targets[] = {
55/* NOTE: The name must be less than UIO_MX-16 chars in length */
56 /* name data tag ro/rw */
a1e23f7a
JSP
57 { ".", 0, KTT_NULL, VREAD, VDIR },
58 { "..", 0, KTT_NULL, VREAD, VDIR },
d0b6ab6e 59 { "boottime", &boottime.tv_sec, KTT_INT, VREAD, VREG },
a1e23f7a
JSP
60 { "copyright", copyright, KTT_STRING, VREAD, VREG },
61 { "hostname", 0, KTT_HOSTNAME, VREAD|VWRITE, VREG },
62 { "hz", &hz, KTT_INT, VREAD, VREG },
63 { "loadavg", 0, KTT_AVENRUN, VREAD, VREG },
64 { "pagesize", &cnt.v_page_size, KTT_INT, VREAD, VREG },
65 { "physmem", &physmem, KTT_INT, VREAD, VREG },
650e78ba 66#if 0
a1e23f7a 67 { "root", 0, KTT_NULL, VREAD, VDIR },
650e78ba 68#endif
a1e23f7a
JSP
69 { "rootdev", 0, KTT_NULL, VREAD, VBLK },
70 { "rrootdev", 0, KTT_NULL, VREAD, VCHR },
71 { "time", 0, KTT_TIME, VREAD, VREG },
72 { "version", version, KTT_STRING, VREAD, VREG },
341568e0
JSP
73};
74
75static int nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]);
76
77static int
78kernfs_xread(kt, buf, len, lenp)
79 struct kern_target *kt;
80 char *buf;
81 int len;
82 int *lenp;
83{
84 int xlen;
85
86 switch (kt->kt_tag) {
87 case KTT_TIME: {
88 struct timeval tv;
89 microtime(&tv);
90 sprintf(buf, "%d %d\n", tv.tv_sec, tv.tv_usec);
91 break;
92 }
93
94 case KTT_INT: {
95 int *ip = kt->kt_data;
96 sprintf(buf, "%d\n", *ip);
97 break;
98 }
99
100 case KTT_STRING: {
101 char *cp = kt->kt_data;
102 int xlen = strlen(cp) + 1;
103
104 if (xlen >= len)
105 return (EINVAL);
106
107 bcopy(cp, buf, xlen);
108 break;
109 }
110
111 case KTT_HOSTNAME: {
112 char *cp = hostname;
113 int xlen = hostnamelen;
114
650e78ba 115 if (xlen >= (len-2))
341568e0
JSP
116 return (EINVAL);
117
650e78ba
JSP
118 bcopy(cp, buf, xlen);
119 buf[xlen] = '\n';
120 buf[xlen+1] = '\0';
341568e0
JSP
121 break;
122 }
123
124 case KTT_AVENRUN:
125 sprintf(buf, "%ld %ld %ld %ld\n",
126 averunnable.ldavg[0],
127 averunnable.ldavg[1],
128 averunnable.ldavg[2],
129 averunnable.fscale);
130 break;
131
132 default:
133 return (EINVAL);
134 }
135
136 *lenp = strlen(buf);
137 return (0);
138}
139
140static int
141kernfs_xwrite(kt, buf, len)
142 struct kern_target *kt;
143 char *buf;
144 int len;
145{
146 switch (kt->kt_tag) {
147 case KTT_HOSTNAME: {
148 if (buf[len-1] == '\n')
149 --len;
150 bcopy(buf, hostname, len);
650e78ba
JSP
151 hostname[len] = '\0';
152 hostnamelen = len;
341568e0
JSP
153 return (0);
154 }
155
156 default:
157 return (EIO);
158 }
159}
160
161
162/*
163 * vp is the current namei directory
164 * ndp is the name to locate in that directory...
165 */
166kernfs_lookup(ap)
167 struct vop_lookup_args /* {
168 struct vnode * a_dvp;
169 struct vnode ** a_vpp;
170 struct componentname * a_cnp;
171 } */ *ap;
172{
173 struct vnode **vpp = ap->a_vpp;
174 struct vnode *dvp = ap->a_dvp;
175 struct componentname *cnp = ap->a_cnp;
176 char *pname;
177 struct proc *p;
178 int error;
179 struct vnode *fvp;
180 int i;
181
182#ifdef KERNFS_DIAGNOSTIC
183 printf("kernfs_lookup(%x)\n", ap);
184 printf("kernfs_lookup(dp = %x, vpp = %x, cnp = %x)\n", dvp, vpp, ap->a_cnp);
185#endif
186 pname = cnp->cn_nameptr;
187#ifdef KERNFS_DIAGNOSTIC
188 printf("kernfs_lookup(%s)\n", pname);
189#endif
190 if (cnp->cn_namelen == 1 && *pname == '.') {
191 *vpp = dvp;
fea856fc 192 VREF(dvp);
341568e0
JSP
193 /*VOP_LOCK(dvp);*/
194 return (0);
195 }
196
650e78ba 197#if 0
341568e0
JSP
198 if (cnp->cn_namelen == 4 && bcmp(pname, "root", 4) == 0) {
199 *vpp = rootdir;
200 VREF(rootdir);
201 VOP_LOCK(rootdir);
202 return (0);
203 }
650e78ba 204#endif
fea856fc 205
341568e0
JSP
206 /*
207 * /kern/rootdev is the root device
208 */
209 if (cnp->cn_namelen == 7 && bcmp(pname, "rootdev", 7) == 0) {
210 *vpp = rootvp;
211 VREF(rootvp);
212 VOP_LOCK(rootvp);
213 return (0);
214 }
215
a1e23f7a
JSP
216 /*
217 * /kern/rrootdev is the raw root device
218 */
219 if (cnp->cn_namelen == 8 && bcmp(pname, "rrootdev", 8) == 0) {
220 if (rrootvp) {
221 *vpp = rrootvp;
222 VREF(rrootvp);
223 VOP_LOCK(rrootvp);
224 return (0);
225 }
226 error = ENXIO;
227 goto bad;
228 }
229
1128113a
JSP
230 error = ENOENT;
231
341568e0
JSP
232 for (i = 0; i < nkern_targets; i++) {
233 struct kern_target *kt = &kern_targets[i];
234 if (cnp->cn_namelen == strlen(kt->kt_name) &&
235 bcmp(kt->kt_name, pname, cnp->cn_namelen) == 0) {
236 error = 0;
237 break;
238 }
239 }
240
241#ifdef KERNFS_DIAGNOSTIC
242 printf("kernfs_lookup: i = %d, error = %d\n", i, error);
243#endif
244
245 if (error)
246 goto bad;
247
248#ifdef KERNFS_DIAGNOSTIC
249 printf("kernfs_lookup: allocate new vnode\n");
250#endif
251 error = getnewvnode(VT_UFS, dvp->v_mount, kernfs_vnodeop_p, &fvp);
252 if (error)
253 goto bad;
254 MALLOC(fvp->v_data, void *, sizeof(struct kernfs_node), M_TEMP, M_WAITOK);
255 VTOKERN(fvp)->kf_kt = &kern_targets[i];
256 fvp->v_type = VTOKERN(fvp)->kf_kt->kt_vtype;
257 *vpp = fvp;
258#ifdef KERNFS_DIAGNOSTIC
259 printf("kernfs_lookup: newvp = %x\n", fvp);
260#endif
261 return (0);
262
263bad:;
264 *vpp = NULL;
265#ifdef KERNFS_DIAGNOSTIC
266 printf("kernfs_lookup: error = %d\n", error);
267#endif
268 return (error);
269}
270
271kernfs_open(ap)
272 struct vop_open_args /* {
273 struct vnode *a_vp;
274 int a_mode;
275 struct ucred *a_cred;
276 struct proc *a_p;
277 } */ *ap;
278{
279 struct vnode *vp = ap->a_vp;
280
281 /*
282 * Can always open the root (modulo perms)
283 */
284 if (vp->v_flag & VROOT)
285 return (0);
286
287#ifdef KERNFS_DIAGNOSTIC
288 printf("kernfs_open, mode = %x, file = %s\n",
289 ap->a_mode, VTOKERN(vp)->kf_kt->kt_name);
290#endif
291
e9451893 292 if ((ap->a_mode & FWRITE) && !(VTOKERN(vp)->kf_kt->kt_rw & VWRITE))
650e78ba 293 return (EOPNOTSUPP);
341568e0
JSP
294
295 return (0);
296}
297
298static int
299kernfs_access(ap)
300 struct vop_access_args /* {
301 struct vnode *a_vp;
302 int a_mode;
303 struct ucred *a_cred;
304 struct proc *a_p;
305 } */ *ap;
306{
307 struct vnode *vp = ap->a_vp;
308 struct ucred *cred = ap->a_cred;
341568e0
JSP
309 mode_t mode = ap->a_mode;
310
311 if (mode & VEXEC) {
312 if (vp->v_flag & VROOT)
313 return (0);
314 return (EACCES);
315 }
316
317 if (cred->cr_uid == 0) {
8015f948
KM
318 if ((vp->v_flag & VROOT) == 0) {
319 struct kern_target *kt = VTOKERN(vp)->kf_kt;
320
321 if ((mode & VWRITE) && !(kt->kt_rw & VWRITE))
322 return (EROFS);
323 }
341568e0
JSP
324 return (0);
325 }
326
327 if (mode & VWRITE)
328 return (EACCES);
329
330 return (0);
331}
332
333
334kernfs_getattr(ap)
335 struct vop_getattr_args /* {
336 struct vnode *a_vp;
337 struct vattr *a_vap;
338 struct ucred *a_cred;
339 struct proc *a_p;
340 } */ *ap;
341{
342 struct vnode *vp = ap->a_vp;
343 struct vattr *vap = ap->a_vap;
344 int error = 0;
345 char strbuf[KSTRING];
341568e0
JSP
346
347 bzero((caddr_t) vap, sizeof(*vap));
348 vattr_null(vap);
349 vap->va_uid = 0;
350 vap->va_gid = 0;
351 vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
352 /* vap->va_qsize = 0; */
353 vap->va_blocksize = DEV_BSIZE;
354 microtime(&vap->va_atime);
355 vap->va_mtime = vap->va_atime;
356 vap->va_ctime = vap->va_ctime;
357 vap->va_gen = 0;
358 vap->va_flags = 0;
359 vap->va_rdev = 0;
360 /* vap->va_qbytes = 0; */
361 vap->va_bytes = 0;
362
363 if (vp->v_flag & VROOT) {
364#ifdef KERNFS_DIAGNOSTIC
365 printf("kernfs_getattr: stat rootdir\n");
366#endif
367 vap->va_type = VDIR;
a1e23f7a 368 vap->va_mode = DIR_MODE;
341568e0
JSP
369 vap->va_nlink = 2;
370 vap->va_fileid = 2;
371 vap->va_size = DEV_BSIZE;
372 } else {
8015f948 373 struct kern_target *kt = VTOKERN(vp)->kf_kt;
341568e0
JSP
374 int nbytes;
375#ifdef KERNFS_DIAGNOSTIC
376 printf("kernfs_getattr: stat target %s\n", kt->kt_name);
377#endif
378 vap->va_type = kt->kt_vtype;
a1e23f7a 379 vap->va_mode = (kt->kt_rw & VWRITE ? WRITE_MODE : READ_MODE);
341568e0
JSP
380 vap->va_nlink = 1;
381 vap->va_fileid = 3 + (kt - kern_targets) / sizeof(*kt);
382 error = kernfs_xread(kt, strbuf, sizeof(strbuf), &nbytes);
383 vap->va_size = nbytes;
384 }
385
386 vp->v_type = vap->va_type;
387#ifdef KERNFS_DIAGNOSTIC
388 printf("kernfs_getattr: return error %d\n", error);
389#endif
390 return (error);
391}
392
393kernfs_setattr(ap)
394 struct vop_setattr_args /* {
395 struct vnode *a_vp;
396 struct vattr *a_vap;
397 struct ucred *a_cred;
398 struct proc *a_p;
399 } */ *ap;
400{
401
402 /*
403 * Silently ignore attribute changes.
404 * This allows for open with truncate to have no
405 * effect until some data is written. I want to
406 * do it this way because all writes are atomic.
407 */
408 return (0);
409}
410
411static int
412kernfs_read(ap)
413 struct vop_read_args /* {
414 struct vnode *a_vp;
415 struct uio *a_uio;
416 int a_ioflag;
417 struct ucred *a_cred;
418 } */ *ap;
419{
420 struct vnode *vp = ap->a_vp;
421 struct uio *uio = ap->a_uio;
8015f948 422 struct kern_target *kt;
341568e0
JSP
423 char strbuf[KSTRING];
424 int off = uio->uio_offset;
425 int len = 0;
426 char *cp = strbuf;
427 int error;
8015f948
KM
428
429 if (vp->v_flag & VROOT)
430 return (0);
431
432 kt = VTOKERN(vp)->kf_kt;
433
341568e0
JSP
434#ifdef KERNFS_DIAGNOSTIC
435 printf("kern_read %s\n", kt->kt_name);
436#endif
437
438 error = kernfs_xread(kt, strbuf, sizeof(strbuf), &len);
439 if (error)
440 return (error);
441 cp = strbuf + off;
442 len -= off;
443 return (uiomove(cp, len, uio));
444}
445
446static int
447kernfs_write(ap)
448 struct vop_write_args /* {
449 struct vnode *a_vp;
450 struct uio *a_uio;
451 int a_ioflag;
452 struct ucred *a_cred;
453 } */ *ap;
454{
455 struct vnode *vp = ap->a_vp;
456 struct uio *uio = ap->a_uio;
8015f948 457 struct kern_target *kt;
341568e0
JSP
458 char strbuf[KSTRING];
459 int len = uio->uio_resid;
460 char *cp = strbuf;
461 int xlen;
462 int error;
463
8015f948
KM
464 if (vp->v_flag & VROOT)
465 return (0);
466
467 kt = VTOKERN(vp)->kf_kt;
468
341568e0
JSP
469 if (uio->uio_offset != 0)
470 return (EINVAL);
471
472 xlen = min(uio->uio_resid, KSTRING-1);
473 error = uiomove(strbuf, xlen, uio);
474 if (error)
475 return (error);
476
477 if (uio->uio_resid != 0)
478 return (EIO);
479
480 strbuf[xlen] = '\0';
650e78ba 481 xlen = strlen(strbuf);
341568e0
JSP
482 return (kernfs_xwrite(kt, strbuf, xlen));
483}
484
485
486kernfs_readdir(ap)
487 struct vop_readdir_args /* {
488 struct vnode *a_vp;
489 struct uio *a_uio;
490 struct ucred *a_cred;
491 } */ *ap;
492{
493 struct uio *uio = ap->a_uio;
494 int i;
495 int error;
496
497 i = uio->uio_offset / UIO_MX;
498 error = 0;
499 while (uio->uio_resid > 0 && i < nkern_targets) {
500 struct dirent d;
501 struct dirent *dp = &d;
502 struct kern_target *kt = &kern_targets[i];
503#ifdef KERNFS_DIAGNOSTIC
504 printf("kernfs_readdir: i = %d\n", i);
505#endif
506
507 bzero((caddr_t) dp, UIO_MX);
508
509 dp->d_namlen = strlen(kt->kt_name);
510 bcopy(kt->kt_name, dp->d_name, dp->d_namlen+1);
511
512#ifdef KERNFS_DIAGNOSTIC
513 printf("kernfs_readdir: name = %s, len = %d\n",
514 dp->d_name, dp->d_namlen);
515#endif
516 /*
517 * Fill in the remaining fields
518 */
519 dp->d_reclen = UIO_MX;
520 dp->d_fileno = i + 3;
521 dp->d_type = DT_UNKNOWN; /* XXX */
522 /*
523 * And ship to userland
524 */
525 error = uiomove((caddr_t) dp, UIO_MX, uio);
526 if (error)
527 break;
528 i++;
529 }
530
531 uio->uio_offset = i * UIO_MX;
532
533 return (error);
534}
535
536kernfs_inactive(ap)
537 struct vop_inactive_args /* {
538 struct vnode *a_vp;
539 } */ *ap;
540{
541 struct vnode *vp = ap->a_vp;
542
543 /*
544 * Clear out the v_type field to avoid
545 * nasty things happening in vgone().
546 */
547 vp->v_type = VNON;
548#ifdef KERNFS_DIAGNOSTIC
549 printf("kernfs_inactive(%x)\n", vp);
550#endif
551 return (0);
552}
553
554kernfs_reclaim(ap)
555 struct vop_reclaim_args /* {
556 struct vnode *a_vp;
557 } */ *ap;
558{
559 struct vnode *vp = ap->a_vp;
ae51ce7d 560#ifdef KERNFS_DIAGNOSTIC
341568e0 561 printf("kernfs_reclaim(%x)\n", vp);
ae51ce7d 562#endif
341568e0
JSP
563 if (vp->v_data) {
564 FREE(vp->v_data, M_TEMP);
565 vp->v_data = 0;
566 }
567 return (0);
568}
569
570/*
571 * Print out the contents of a /dev/fd vnode.
572 */
573/* ARGSUSED */
574kernfs_print(ap)
575 struct vop_print_args /* {
576 struct vnode *a_vp;
577 } */ *ap;
578{
579
580 printf("tag VT_NON, kernfs vnode\n");
581 return (0);
582}
583
584/*void*/
585kernfs_vfree(ap)
586 struct vop_vfree_args /* {
587 struct vnode *a_pvp;
588 ino_t a_ino;
589 int a_mode;
590 } */ *ap;
591{
592
593 return (0);
594}
595
596/*
597 * /dev/fd vnode unsupported operation
598 */
599kernfs_enotsupp()
600{
601
602 return (EOPNOTSUPP);
603}
604
605/*
606 * /dev/fd "should never get here" operation
607 */
608kernfs_badop()
609{
610
611 panic("kernfs: bad op");
612 /* NOTREACHED */
613}
614
615/*
fea856fc 616 * kernfs vnode null operation
341568e0
JSP
617 */
618kernfs_nullop()
619{
620
621 return (0);
622}
623
624#define kernfs_create ((int (*) __P((struct vop_create_args *)))kernfs_enotsupp)
625#define kernfs_mknod ((int (*) __P((struct vop_mknod_args *)))kernfs_enotsupp)
626#define kernfs_close ((int (*) __P((struct vop_close_args *)))nullop)
627#define kernfs_ioctl ((int (*) __P((struct vop_ioctl_args *)))kernfs_enotsupp)
628#define kernfs_select ((int (*) __P((struct vop_select_args *)))kernfs_enotsupp)
629#define kernfs_mmap ((int (*) __P((struct vop_mmap_args *)))kernfs_enotsupp)
630#define kernfs_fsync ((int (*) __P((struct vop_fsync_args *)))nullop)
631#define kernfs_seek ((int (*) __P((struct vop_seek_args *)))nullop)
632#define kernfs_remove ((int (*) __P((struct vop_remove_args *)))kernfs_enotsupp)
633#define kernfs_link ((int (*) __P((struct vop_link_args *)))kernfs_enotsupp)
634#define kernfs_rename ((int (*) __P((struct vop_rename_args *)))kernfs_enotsupp)
635#define kernfs_mkdir ((int (*) __P((struct vop_mkdir_args *)))kernfs_enotsupp)
636#define kernfs_rmdir ((int (*) __P((struct vop_rmdir_args *)))kernfs_enotsupp)
637#define kernfs_symlink ((int (*) __P((struct vop_symlink_args *)))kernfs_enotsupp)
638#define kernfs_readlink \
639 ((int (*) __P((struct vop_readlink_args *)))kernfs_enotsupp)
640#define kernfs_abortop ((int (*) __P((struct vop_abortop_args *)))nullop)
641#define kernfs_lock ((int (*) __P((struct vop_lock_args *)))nullop)
642#define kernfs_unlock ((int (*) __P((struct vop_unlock_args *)))nullop)
643#define kernfs_bmap ((int (*) __P((struct vop_bmap_args *)))kernfs_badop)
644#define kernfs_strategy ((int (*) __P((struct vop_strategy_args *)))kernfs_badop)
645#define kernfs_islocked ((int (*) __P((struct vop_islocked_args *)))nullop)
646#define kernfs_advlock ((int (*) __P((struct vop_advlock_args *)))kernfs_enotsupp)
647#define kernfs_blkatoff \
648 ((int (*) __P((struct vop_blkatoff_args *)))kernfs_enotsupp)
649#define kernfs_valloc ((int(*) __P(( \
650 struct vnode *pvp, \
651 int mode, \
652 struct ucred *cred, \
653 struct vnode **vpp))) kernfs_enotsupp)
654#define kernfs_truncate \
655 ((int (*) __P((struct vop_truncate_args *)))kernfs_enotsupp)
656#define kernfs_update ((int (*) __P((struct vop_update_args *)))kernfs_enotsupp)
657#define kernfs_bwrite ((int (*) __P((struct vop_bwrite_args *)))kernfs_enotsupp)
658
659int (**kernfs_vnodeop_p)();
660struct vnodeopv_entry_desc kernfs_vnodeop_entries[] = {
661 { &vop_default_desc, vn_default_error },
662 { &vop_lookup_desc, kernfs_lookup }, /* lookup */
663 { &vop_create_desc, kernfs_create }, /* create */
664 { &vop_mknod_desc, kernfs_mknod }, /* mknod */
665 { &vop_open_desc, kernfs_open }, /* open */
666 { &vop_close_desc, kernfs_close }, /* close */
667 { &vop_access_desc, kernfs_access }, /* access */
668 { &vop_getattr_desc, kernfs_getattr }, /* getattr */
669 { &vop_setattr_desc, kernfs_setattr }, /* setattr */
670 { &vop_read_desc, kernfs_read }, /* read */
671 { &vop_write_desc, kernfs_write }, /* write */
672 { &vop_ioctl_desc, kernfs_ioctl }, /* ioctl */
673 { &vop_select_desc, kernfs_select }, /* select */
674 { &vop_mmap_desc, kernfs_mmap }, /* mmap */
675 { &vop_fsync_desc, kernfs_fsync }, /* fsync */
676 { &vop_seek_desc, kernfs_seek }, /* seek */
677 { &vop_remove_desc, kernfs_remove }, /* remove */
678 { &vop_link_desc, kernfs_link }, /* link */
679 { &vop_rename_desc, kernfs_rename }, /* rename */
680 { &vop_mkdir_desc, kernfs_mkdir }, /* mkdir */
681 { &vop_rmdir_desc, kernfs_rmdir }, /* rmdir */
682 { &vop_symlink_desc, kernfs_symlink }, /* symlink */
683 { &vop_readdir_desc, kernfs_readdir }, /* readdir */
684 { &vop_readlink_desc, kernfs_readlink }, /* readlink */
685 { &vop_abortop_desc, kernfs_abortop }, /* abortop */
686 { &vop_inactive_desc, kernfs_inactive }, /* inactive */
687 { &vop_reclaim_desc, kernfs_reclaim }, /* reclaim */
688 { &vop_lock_desc, kernfs_lock }, /* lock */
689 { &vop_unlock_desc, kernfs_unlock }, /* unlock */
690 { &vop_bmap_desc, kernfs_bmap }, /* bmap */
691 { &vop_strategy_desc, kernfs_strategy }, /* strategy */
692 { &vop_print_desc, kernfs_print }, /* print */
693 { &vop_islocked_desc, kernfs_islocked }, /* islocked */
694 { &vop_advlock_desc, kernfs_advlock }, /* advlock */
695 { &vop_blkatoff_desc, kernfs_blkatoff }, /* blkatoff */
696 { &vop_valloc_desc, kernfs_valloc }, /* valloc */
697 { &vop_vfree_desc, kernfs_vfree }, /* vfree */
698 { &vop_truncate_desc, kernfs_truncate }, /* truncate */
699 { &vop_update_desc, kernfs_update }, /* update */
700 { &vop_bwrite_desc, kernfs_bwrite }, /* bwrite */
701 { (struct vnodeop_desc*)NULL, (int(*)())NULL }
702};
703struct vnodeopv_desc kernfs_vnodeop_opv_desc =
704 { &kernfs_vnodeop_p, kernfs_vnodeop_entries };