2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* $NetBSD: kernfs_vnops.c,v 1.35 1995/02/03 16:18:46 mycroft Exp $ */
25 * Copyright (c) 1992, 1993
26 * The Regents of the University of California. All rights reserved.
28 * This code is derived from software donated to Berkeley by
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. All advertising materials mentioning features or use of this software
40 * must display the following acknowledgement:
41 * This product includes software developed by the University of
42 * California, Berkeley and its contributors.
43 * 4. Neither the name of the University nor the names of its contributors
44 * may be used to endorse or promote products derived from this software
45 * without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * @(#)kernfs_vnops.c 8.9 (Berkeley) 6/15/94
63 * Kernel parameter filesystem (/kern)
66 #include <sys/param.h>
67 #include <sys/systm.h>
68 #include <sys/kernel.h>
69 #include <sys/vmmeter.h>
70 #include <sys/types.h>
73 #include <sys/vnode.h>
74 #include <sys/malloc.h>
77 #include <sys/mount.h>
78 #include <sys/namei.h>
80 #include <sys/dirent.h>
81 #include <sys/msgbuf.h>
83 #include <vfs/vfs_support.h>
84 #include <miscfs/kernfs/kernfs.h>
86 #define KSTRING 256 /* Largest I/O available via this filesystem */
89 #define READ_MODE (S_IRUSR|S_IRGRP|S_IROTH)
90 #define WRITE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)
91 #define DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
101 #define KTT_STRING 31
102 #define KTT_HOSTNAME 47
103 #define KTT_AVENRUN 53
104 #define KTT_DEVICE 71
105 #define KTT_MSGBUF 89
110 /* NOTE: The name must be less than UIO_MX-16 chars in length */
111 #define N(s) sizeof(s)-1, s
112 /* name data tag type ro/rw */
113 { DT_DIR
, N("."), 0, KTT_NULL
, VDIR
, DIR_MODE
},
114 { DT_DIR
, N(".."), 0, KTT_NULL
, VDIR
, DIR_MODE
},
115 { DT_REG
, N("boottime"), &boottime
.tv_sec
, KTT_INT
, VREG
, READ_MODE
},
116 { DT_REG
, N("copyright"), copyright
, KTT_STRING
, VREG
, READ_MODE
},
117 { DT_REG
, N("hostname"), 0, KTT_HOSTNAME
, VREG
, WRITE_MODE
},
118 { DT_REG
, N("hz"), &hz
, KTT_INT
, VREG
, READ_MODE
},
119 { DT_REG
, N("loadavg"), 0, KTT_AVENRUN
, VREG
, READ_MODE
},
120 { DT_REG
, N("msgbuf"), 0, KTT_MSGBUF
, VREG
, READ_MODE
},
121 { DT_REG
, N("pagesize"), &cnt
.v_page_size
, KTT_INT
, VREG
, READ_MODE
},
122 { DT_REG
, N("physmem"), &physmem
, KTT_INT
, VREG
, READ_MODE
},
124 { DT_DIR
, N("root"), 0, KTT_NULL
, VDIR
, DIR_MODE
},
126 { DT_BLK
, N("rootdev"), &rootdev
, KTT_DEVICE
, VBLK
, READ_MODE
},
127 { DT_CHR
, N("rrootdev"), &rrootdev
, KTT_DEVICE
, VCHR
, READ_MODE
},
128 { DT_REG
, N("time"), 0, KTT_TIME
, VREG
, READ_MODE
},
129 { DT_REG
, N("version"), version
, KTT_STRING
, VREG
, READ_MODE
},
132 static int nkern_targets
= sizeof(kern_targets
) / sizeof(kern_targets
[0]);
135 kernfs_xread(kt
, off
, bufp
, len
)
136 struct kern_target
*kt
;
142 switch (kt
->kt_tag
) {
147 sprintf(*bufp
, "%d %d\n", tv
.tv_sec
, tv
.tv_usec
);
152 int *ip
= kt
->kt_data
;
154 sprintf(*bufp
, "%d\n", *ip
);
159 char *cp
= kt
->kt_data
;
166 extern struct msgbuf
*msgbufp
;
169 if (off
>= MSG_BSIZE
)
171 n
= msgbufp
->msg_bufx
+ off
;
174 len
= min(MSG_BSIZE
- n
, MSG_BSIZE
- off
);
175 *bufp
= msgbufp
->msg_bufc
+ n
;
181 int xlen
= hostnamelen
;
186 bcopy(cp
, *bufp
, xlen
);
187 (*bufp
)[xlen
] = '\n';
188 (*bufp
)[xlen
+1] = '\0';
193 averunnable
.fscale
= FSCALE
;
194 sprintf(*bufp
, "%ld %ld %ld %ld\n",
195 averunnable
.ldavg
[0], averunnable
.ldavg
[1],
196 averunnable
.ldavg
[2], averunnable
.fscale
);
211 kernfs_xwrite(kt
, buf
, len
)
212 struct kern_target
*kt
;
217 switch (kt
->kt_tag
) {
219 if (buf
[len
-1] == '\n')
221 bcopy(buf
, hostname
, len
);
222 hostname
[len
] = '\0';
233 * vp is the current namei directory
234 * ndp is the name to locate in that directory...
237 struct vop_lookup_args
/* {
238 struct vnode * a_dvp;
239 struct vnode ** a_vpp;
240 struct componentname * a_cnp;
243 struct componentname
*cnp
= ap
->a_cnp
;
244 struct vnode
**vpp
= ap
->a_vpp
;
245 struct vnode
*dvp
= ap
->a_dvp
;
246 char *pname
= cnp
->cn_nameptr
;
247 struct kern_target
*kt
;
250 struct kernfs_node
*kp
;
252 #ifdef KERNFS_DIAGNOSTIC
253 printf("kernfs_lookup(%x)\n", ap
);
254 printf("kernfs_lookup(dp = %x, vpp = %x, cnp = %x)\n", dvp
, vpp
, ap
->a_cnp
);
255 printf("kernfs_lookup(%s)\n", pname
);
260 if (cnp
->cn_nameiop
== DELETE
|| cnp
->cn_nameiop
== RENAME
)
263 if (cnp
->cn_namelen
== 1 && *pname
== '.') {
271 if (cnp
->cn_namelen
== 4 && bcmp(pname
, "root", 4) == 0) {
279 for (kt
= kern_targets
, i
= 0; i
< nkern_targets
; kt
++, i
++) {
280 if (cnp
->cn_namelen
== kt
->kt_namlen
&&
281 bcmp(kt
->kt_name
, pname
, cnp
->cn_namelen
) == 0)
285 #ifdef KERNFS_DIAGNOSTIC
286 printf("kernfs_lookup: i = %d, failed", i
);
289 return (cnp
->cn_nameiop
== LOOKUP
? ENOENT
: EROFS
);
292 if (kt
->kt_tag
== KTT_DEVICE
) {
293 dev_t
*dp
= kt
->kt_data
;
295 if (*dp
== NODEV
|| !vfinddev(*dp
, kt
->kt_vtype
, &fvp
))
298 if (vget(fvp
, LK_SHARED
, current_proc()))
303 #ifdef KERNFS_DIAGNOSTIC
304 printf("kernfs_lookup: allocate new vnode\n");
306 MALLOC(kp
, void *, sizeof(struct kernfs_node
), M_TEMP
, M_WAITOK
);
307 if (error
= getnewvnode(VT_KERNFS
, dvp
->v_mount
, kernfs_vnodeop_p
,
314 VTOKERN(fvp
)->kf_kt
= kt
;
315 fvp
->v_type
= kt
->kt_vtype
;
316 if (fvp
->v_type
== VREG
)
320 #ifdef KERNFS_DIAGNOSTIC
321 printf("kernfs_lookup: newvp = %x\n", fvp
);
327 struct vop_open_args
/* {
330 struct ucred *a_cred;
335 /* Only need to check access permissions. */
341 struct vop_access_args
/* {
344 struct ucred *a_cred;
348 struct vnode
*vp
= ap
->a_vp
;
350 (vp
->v_flag
& VROOT
) ? DIR_MODE
: VTOKERN(vp
)->kf_kt
->kt_mode
;
352 return (vaccess(fmode
, (uid_t
)0, (gid_t
)0, ap
->a_mode
, ap
->a_cred
));
356 struct vop_getattr_args
/* {
359 struct ucred *a_cred;
363 struct vnode
*vp
= ap
->a_vp
;
364 struct vattr
*vap
= ap
->a_vap
;
366 char strbuf
[KSTRING
], *buf
;
368 bzero((caddr_t
) vap
, sizeof(*vap
));
372 vap
->va_fsid
= vp
->v_mount
->mnt_stat
.f_fsid
.val
[0];
374 vap
->va_blocksize
= DEV_BSIZE
;
375 microtime(&vap
->va_atime
);
376 vap
->va_mtime
= vap
->va_atime
;
377 vap
->va_ctime
= vap
->va_ctime
;
383 if (vp
->v_flag
& VROOT
) {
384 #ifdef KERNFS_DIAGNOSTIC
385 printf("kernfs_getattr: stat rootdir\n");
388 vap
->va_mode
= DIR_MODE
;
391 vap
->va_size
= DEV_BSIZE
;
393 struct kern_target
*kt
= VTOKERN(vp
)->kf_kt
;
395 #ifdef KERNFS_DIAGNOSTIC
396 printf("kernfs_getattr: stat target %s\n", kt
->kt_name
);
398 vap
->va_type
= kt
->kt_vtype
;
399 vap
->va_mode
= kt
->kt_mode
;
401 vap
->va_fileid
= 1 + (kt
- kern_targets
) / sizeof(*kt
);
404 nbytes
= kernfs_xread(kt
, total
, &buf
, sizeof(strbuf
)))
406 vap
->va_size
= total
;
409 #ifdef KERNFS_DIAGNOSTIC
410 printf("kernfs_getattr: return error %d\n", error
);
416 struct vop_setattr_args
/* {
419 struct ucred *a_cred;
425 * Silently ignore attribute changes.
426 * This allows for open with truncate to have no
427 * effect until some data is written. I want to
428 * do it this way because all writes are atomic.
435 struct vop_read_args
/* {
439 struct ucred *a_cred;
442 struct vnode
*vp
= ap
->a_vp
;
443 struct uio
*uio
= ap
->a_uio
;
444 struct kern_target
*kt
;
445 char strbuf
[KSTRING
], *buf
;
449 if (vp
->v_type
== VDIR
)
452 kt
= VTOKERN(vp
)->kf_kt
;
454 #ifdef KERNFS_DIAGNOSTIC
455 printf("kern_read %s\n", kt
->kt_name
);
458 off
= uio
->uio_offset
;
464 len
= kernfs_xread(kt
, off
, &buf
, sizeof(strbuf
))) {
465 if (error
= uiomove(buf
, len
, uio
))
474 struct vop_write_args
/* {
478 struct ucred *a_cred;
481 struct vnode
*vp
= ap
->a_vp
;
482 struct uio
*uio
= ap
->a_uio
;
483 struct kern_target
*kt
;
485 char strbuf
[KSTRING
];
487 if (vp
->v_type
== VDIR
)
490 kt
= VTOKERN(vp
)->kf_kt
;
492 if (uio
->uio_offset
!= 0)
495 xlen
= min(uio
->uio_resid
, KSTRING
-1);
496 if (error
= uiomove(strbuf
, xlen
, uio
))
499 if (uio
->uio_resid
!= 0)
503 xlen
= strlen(strbuf
);
504 return (kernfs_xwrite(kt
, strbuf
, xlen
));
508 struct vop_readdir_args
/* {
511 struct ucred *a_cred;
517 struct uio
*uio
= ap
->a_uio
;
518 struct kern_target
*kt
;
523 if (ap
->a_vp
->v_type
!= VDIR
)
527 * We don't allow exporting kernfs mounts, and currently local
528 * requests do not need cookies.
530 if (ap
->a_ncookies
!= NULL
)
531 panic("kernfs_readdir: not hungry");
533 i
= uio
->uio_offset
/ UIO_MX
;
535 for (kt
= &kern_targets
[i
];
536 uio
->uio_resid
>= UIO_MX
&& i
< nkern_targets
; kt
++, i
++) {
537 struct dirent
*dp
= &d
;
538 #ifdef KERNFS_DIAGNOSTIC
539 printf("kernfs_readdir: i = %d\n", i
);
542 if (kt
->kt_tag
== KTT_DEVICE
) {
543 dev_t
*dp
= kt
->kt_data
;
546 if (*dp
== NODEV
|| !vfinddev(*dp
, kt
->kt_vtype
, &fvp
))
550 bzero((caddr_t
)dp
, UIO_MX
);
551 dp
->d_namlen
= kt
->kt_namlen
;
552 bcopy(kt
->kt_name
, dp
->d_name
, kt
->kt_namlen
+1);
554 #ifdef KERNFS_DIAGNOSTIC
555 printf("kernfs_readdir: name = %s, len = %d\n",
556 dp
->d_name
, dp
->d_namlen
);
559 * Fill in the remaining fields
561 dp
->d_reclen
= UIO_MX
;
562 dp
->d_fileno
= i
+ 3;
563 dp
->d_type
= kt
->kt_type
;
565 * And ship to userland
567 if (error
= uiomove((caddr_t
)dp
, UIO_MX
, uio
))
571 uio
->uio_offset
= i
* UIO_MX
;
577 struct vop_inactive_args
/* {
581 struct vnode
*vp
= ap
->a_vp
;
583 #ifdef KERNFS_DIAGNOSTIC
584 printf("kernfs_inactive(%x)\n", vp
);
587 * Clear out the v_type field to avoid
588 * nasty things happening in vgone().
595 struct vop_reclaim_args
/* {
599 struct vnode
*vp
= ap
->a_vp
;
601 #ifdef KERNFS_DIAGNOSTIC
602 printf("kernfs_reclaim(%x)\n", vp
);
605 FREE(vp
->v_data
, M_TEMP
);
612 * Return POSIX pathconf information applicable to special devices.
615 struct vop_pathconf_args
/* {
618 register_t *a_retval;
622 switch (ap
->a_name
) {
624 *ap
->a_retval
= LINK_MAX
;
627 *ap
->a_retval
= MAX_CANON
;
630 *ap
->a_retval
= MAX_INPUT
;
633 *ap
->a_retval
= PIPE_BUF
;
635 case _PC_CHOWN_RESTRICTED
:
639 *ap
->a_retval
= _POSIX_VDISABLE
;
648 * Print out the contents of a /dev/fd vnode.
652 struct vop_print_args
/* {
657 printf("tag VT_KERNFS, kernfs vnode\n");
663 struct vop_vfree_args
/* {
674 * /dev/fd vnode unsupported operation
683 * /dev/fd "should never get here" operation
688 panic("kernfs: bad op");
693 * kernfs vnode null operation
701 #define kernfs_create ((int (*) __P((struct vop_create_args *)))kernfs_enotsupp)
702 #define kernfs_mknod ((int (*) __P((struct vop_mknod_args *)))kernfs_enotsupp)
703 #define kernfs_close ((int (*) __P((struct vop_close_args *)))nullop)
704 #define kernfs_ioctl ((int (*) __P((struct vop_ioctl_args *)))kernfs_enotsupp)
705 #define kernfs_select ((int (*) __P((struct vop_select_args *)))kernfs_enotsupp)
706 #define kernfs_mmap ((int (*) __P((struct vop_mmap_args *)))kernfs_enotsupp)
707 #define kernfs_fsync ((int (*) __P((struct vop_fsync_args *)))nullop)
708 #define kernfs_seek ((int (*) __P((struct vop_seek_args *)))nullop)
709 #define kernfs_remove ((int (*) __P((struct vop_remove_args *)))kernfs_enotsupp)
710 #define kernfs_link ((int (*) __P((struct vop_link_args *)))kernfs_enotsupp)
711 #define kernfs_rename ((int (*) __P((struct vop_rename_args *)))kernfs_enotsupp)
712 #define kernfs_mkdir ((int (*) __P((struct vop_mkdir_args *)))kernfs_enotsupp)
713 #define kernfs_rmdir ((int (*) __P((struct vop_rmdir_args *)))kernfs_enotsupp)
714 #define kernfs_symlink ((int (*) __P((struct vop_symlink_args *)))kernfs_enotsupp)
715 #define kernfs_readlink \
716 ((int (*) __P((struct vop_readlink_args *)))kernfs_enotsupp)
717 #define kernfs_abortop ((int (*) __P((struct vop_abortop_args *)))nullop)
718 #define kernfs_lock ((int (*) __P((struct vop_lock_args *)))nullop)
719 #define kernfs_unlock ((int (*) __P((struct vop_unlock_args *)))nullop)
720 #define kernfs_bmap ((int (*) __P((struct vop_bmap_args *)))kernfs_badop)
721 #define kernfs_strategy ((int (*) __P((struct vop_strategy_args *)))kernfs_badop)
722 #define kernfs_islocked ((int (*) __P((struct vop_islocked_args *)))nullop)
723 #define kernfs_advlock ((int (*) __P((struct vop_advlock_args *)))kernfs_enotsupp)
724 #define kernfs_blkatoff \
725 ((int (*) __P((struct vop_blkatoff_args *)))kernfs_enotsupp)
726 #define kernfs_valloc ((int(*) __P(( \
729 struct ucred *cred, \
730 struct vnode **vpp))) kernfs_enotsupp)
731 #define kernfs_truncate \
732 ((int (*) __P((struct vop_truncate_args *)))kernfs_enotsupp)
733 #define kernfs_update ((int (*) __P((struct vop_update_args *)))kernfs_enotsupp)
734 #define kernfs_bwrite ((int (*) __P((struct vop_bwrite_args *)))kernfs_enotsupp)
736 #define VOPFUNC int (*)(void *)
738 int (**kernfs_vnodeop_p
)(void *);
739 struct vnodeopv_entry_desc kernfs_vnodeop_entries
[] = {
740 { &vop_default_desc
, (VOPFUNC
)vn_default_error
},
741 { &vop_lookup_desc
, (VOPFUNC
)kernfs_lookup
}, /* lookup */
742 { &vop_create_desc
, (VOPFUNC
)kernfs_create
}, /* create */
743 { &vop_mknod_desc
, (VOPFUNC
)kernfs_mknod
}, /* mknod */
744 { &vop_open_desc
, (VOPFUNC
)kernfs_open
}, /* open */
745 { &vop_close_desc
, (VOPFUNC
)kernfs_close
}, /* close */
746 { &vop_access_desc
, (VOPFUNC
)kernfs_access
}, /* access */
747 { &vop_getattr_desc
, (VOPFUNC
)kernfs_getattr
}, /* getattr */
748 { &vop_setattr_desc
, (VOPFUNC
)kernfs_setattr
}, /* setattr */
749 { &vop_read_desc
, (VOPFUNC
)kernfs_read
}, /* read */
750 { &vop_write_desc
, (VOPFUNC
)kernfs_write
}, /* write */
751 { &vop_ioctl_desc
, (VOPFUNC
)kernfs_ioctl
}, /* ioctl */
752 { &vop_select_desc
, (VOPFUNC
)kernfs_select
}, /* select */
753 { &vop_mmap_desc
, (VOPFUNC
)kernfs_mmap
}, /* mmap */
754 { &vop_fsync_desc
, (VOPFUNC
)kernfs_fsync
}, /* fsync */
755 { &vop_seek_desc
, (VOPFUNC
)kernfs_seek
}, /* seek */
756 { &vop_remove_desc
, (VOPFUNC
)kernfs_remove
}, /* remove */
757 { &vop_link_desc
, (VOPFUNC
)kernfs_link
}, /* link */
758 { &vop_rename_desc
, (VOPFUNC
)kernfs_rename
}, /* rename */
759 { &vop_mkdir_desc
, (VOPFUNC
)kernfs_mkdir
}, /* mkdir */
760 { &vop_rmdir_desc
, (VOPFUNC
)kernfs_rmdir
}, /* rmdir */
761 { &vop_symlink_desc
, (VOPFUNC
)kernfs_symlink
}, /* symlink */
762 { &vop_readdir_desc
, (VOPFUNC
)kernfs_readdir
}, /* readdir */
763 { &vop_readlink_desc
, (VOPFUNC
)kernfs_readlink
},/* readlink */
764 { &vop_abortop_desc
, (VOPFUNC
)kernfs_abortop
}, /* abortop */
765 { &vop_inactive_desc
, (VOPFUNC
)kernfs_inactive
},/* inactive */
766 { &vop_reclaim_desc
, (VOPFUNC
)kernfs_reclaim
}, /* reclaim */
767 { &vop_lock_desc
, (VOPFUNC
)kernfs_lock
}, /* lock */
768 { &vop_unlock_desc
, (VOPFUNC
)kernfs_unlock
}, /* unlock */
769 { &vop_bmap_desc
, (VOPFUNC
)kernfs_bmap
}, /* bmap */
770 { &vop_strategy_desc
, (VOPFUNC
)kernfs_strategy
},/* strategy */
771 { &vop_print_desc
, (VOPFUNC
)kernfs_print
}, /* print */
772 { &vop_islocked_desc
, (VOPFUNC
)kernfs_islocked
},/* islocked */
773 { &vop_pathconf_desc
, (VOPFUNC
)kernfs_pathconf
},/* pathconf */
774 { &vop_advlock_desc
, (VOPFUNC
)kernfs_advlock
}, /* advlock */
775 { &vop_blkatoff_desc
, (VOPFUNC
)kernfs_blkatoff
},/* blkatoff */
776 { &vop_valloc_desc
, (VOPFUNC
)kernfs_valloc
}, /* valloc */
777 { &vop_vfree_desc
, (VOPFUNC
)kernfs_vfree
}, /* vfree */
778 { &vop_truncate_desc
, (VOPFUNC
)kernfs_truncate
},/* truncate */
779 { &vop_update_desc
, (VOPFUNC
)kernfs_update
}, /* update */
780 { &vop_bwrite_desc
, (VOPFUNC
)kernfs_bwrite
}, /* bwrite */
781 { &vop_copyfile_desc
, (VOPFUNC
)err_copyfile
}, /* Copyfile */
782 { (struct vnodeop_desc
*)NULL
, (int(*)())NULL
}
784 struct vnodeopv_desc kernfs_vnodeop_opv_desc
=
785 { &kernfs_vnodeop_p
, kernfs_vnodeop_entries
};