2 * Copyright (c) 2004,2009 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * Implement vnode ops wrappers. All vnode ops are wrapped through
38 * These wrappers are responsible for hanlding all MPSAFE issues related
39 * to a vnode operation.
42 #include <sys/param.h>
43 #include <sys/systm.h>
46 #include <sys/dirent.h>
47 #include <sys/domain.h>
48 #include <sys/eventhandler.h>
49 #include <sys/fcntl.h>
50 #include <sys/kernel.h>
51 #include <sys/kthread.h>
52 #include <sys/malloc.h>
54 #include <sys/mount.h>
56 #include <sys/namei.h>
57 #include <sys/reboot.h>
58 #include <sys/socket.h>
60 #include <sys/sysctl.h>
61 #include <sys/syslog.h>
62 #include <sys/vmmeter.h>
63 #include <sys/vnode.h>
64 #include <sys/vfsops.h>
65 #include <sys/sysmsg.h>
66 #include <sys/vfs_quota.h>
68 #include <machine/limits.h>
71 #include <vm/vm_object.h>
72 #include <vm/vm_extern.h>
73 #include <vm/vm_kern.h>
75 #include <vm/vm_map.h>
76 #include <vm/vm_page.h>
77 #include <vm/vm_pager.h>
78 #include <vm/vnode_pager.h>
79 #include <vm/vm_zone.h>
82 #include <sys/mplock2.h>
84 #define VDESCNAME(name) __CONCAT(__CONCAT(vop_,name),_desc)
86 #define VNODEOP_DESC_INIT(name) \
87 struct syslink_desc VDESCNAME(name) = { \
88 __offsetof(struct vop_ops, __CONCAT(vop_, name)), \
91 VNODEOP_DESC_INIT(default);
92 VNODEOP_DESC_INIT(old_lookup
);
93 VNODEOP_DESC_INIT(old_create
);
94 VNODEOP_DESC_INIT(old_whiteout
);
95 VNODEOP_DESC_INIT(old_mknod
);
96 VNODEOP_DESC_INIT(open
);
97 VNODEOP_DESC_INIT(close
);
98 VNODEOP_DESC_INIT(access
);
99 VNODEOP_DESC_INIT(getattr
);
100 VNODEOP_DESC_INIT(getattr_quick
);
101 VNODEOP_DESC_INIT(setattr
);
102 VNODEOP_DESC_INIT(read
);
103 VNODEOP_DESC_INIT(write
);
104 VNODEOP_DESC_INIT(ioctl
);
105 VNODEOP_DESC_INIT(poll
);
106 VNODEOP_DESC_INIT(kqfilter
);
107 VNODEOP_DESC_INIT(mmap
);
108 VNODEOP_DESC_INIT(fsync
);
109 VNODEOP_DESC_INIT(old_remove
);
110 VNODEOP_DESC_INIT(old_link
);
111 VNODEOP_DESC_INIT(old_rename
);
113 VNODEOP_DESC_INIT(old_mkdir
);
114 VNODEOP_DESC_INIT(old_rmdir
);
115 VNODEOP_DESC_INIT(old_symlink
);
116 VNODEOP_DESC_INIT(readdir
);
117 VNODEOP_DESC_INIT(readlink
);
118 VNODEOP_DESC_INIT(inactive
);
119 VNODEOP_DESC_INIT(reclaim
);
120 VNODEOP_DESC_INIT(bmap
);
121 VNODEOP_DESC_INIT(strategy
);
122 VNODEOP_DESC_INIT(print
);
123 VNODEOP_DESC_INIT(pathconf
);
124 VNODEOP_DESC_INIT(advlock
);
125 VNODEOP_DESC_INIT(balloc
);
126 VNODEOP_DESC_INIT(reallocblks
);
127 VNODEOP_DESC_INIT(getpages
);
128 VNODEOP_DESC_INIT(putpages
);
129 VNODEOP_DESC_INIT(freeblks
);
130 VNODEOP_DESC_INIT(getacl
);
131 VNODEOP_DESC_INIT(setacl
);
132 VNODEOP_DESC_INIT(aclcheck
);
133 VNODEOP_DESC_INIT(getextattr
);
134 VNODEOP_DESC_INIT(setextattr
);
135 VNODEOP_DESC_INIT(mountctl
);
136 VNODEOP_DESC_INIT(markatime
);
138 VNODEOP_DESC_INIT(nresolve
);
139 VNODEOP_DESC_INIT(nlookupdotdot
);
140 VNODEOP_DESC_INIT(ncreate
);
141 VNODEOP_DESC_INIT(nmkdir
);
142 VNODEOP_DESC_INIT(nmknod
);
143 VNODEOP_DESC_INIT(nlink
);
144 VNODEOP_DESC_INIT(nsymlink
);
145 VNODEOP_DESC_INIT(nwhiteout
);
146 VNODEOP_DESC_INIT(nremove
);
147 VNODEOP_DESC_INIT(nrmdir
);
148 VNODEOP_DESC_INIT(nrename
);
150 #define DO_OPS(ops, error, ap, vop_field) \
151 error = ops->vop_field(ap)
153 /************************************************************************
154 * PRIMARY HIGH LEVEL VNODE OPERATIONS CALLS *
155 ************************************************************************
157 * These procedures are called directly from the kernel and/or fileops
158 * code to perform file/device operations on the system.
160 * NOTE: The old namespace api functions such as vop_rename() are no
161 * longer available for general use and have been renamed to
162 * vop_old_*(). Only the code in vfs_default.c is allowed to call
165 * NOTE: The VFS_MPLOCK() macro handle mounts which do not set MNTK_MPSAFE.
171 vop_old_lookup(struct vop_ops
*ops
, struct vnode
*dvp
,
172 struct vnode
**vpp
, struct componentname
*cnp
)
174 struct vop_old_lookup_args ap
;
178 ap
.a_head
.a_desc
= &vop_old_lookup_desc
;
179 ap
.a_head
.a_ops
= ops
;
183 VFS_MPLOCK(dvp
->v_mount
);
184 DO_OPS(ops
, error
, &ap
, vop_old_lookup
);
194 vop_old_create(struct vop_ops
*ops
, struct vnode
*dvp
,
195 struct vnode
**vpp
, struct componentname
*cnp
, struct vattr
*vap
)
197 struct vop_old_create_args ap
;
201 ap
.a_head
.a_desc
= &vop_old_create_desc
;
202 ap
.a_head
.a_ops
= ops
;
208 VFS_MPLOCK(dvp
->v_mount
);
209 DO_OPS(ops
, error
, &ap
, vop_old_create
);
219 vop_old_whiteout(struct vop_ops
*ops
, struct vnode
*dvp
,
220 struct componentname
*cnp
, int flags
)
222 struct vop_old_whiteout_args ap
;
226 ap
.a_head
.a_desc
= &vop_old_whiteout_desc
;
227 ap
.a_head
.a_ops
= ops
;
232 VFS_MPLOCK(dvp
->v_mount
);
233 DO_OPS(ops
, error
, &ap
, vop_old_whiteout
);
243 vop_old_mknod(struct vop_ops
*ops
, struct vnode
*dvp
,
244 struct vnode
**vpp
, struct componentname
*cnp
, struct vattr
*vap
)
246 struct vop_old_mknod_args ap
;
250 ap
.a_head
.a_desc
= &vop_old_mknod_desc
;
251 ap
.a_head
.a_ops
= ops
;
257 VFS_MPLOCK(dvp
->v_mount
);
258 DO_OPS(ops
, error
, &ap
, vop_old_mknod
);
265 * NOTE: VAGE is always cleared when calling VOP_OPEN().
268 vop_open(struct vop_ops
*ops
, struct vnode
*vp
, int mode
, struct ucred
*cred
,
271 struct vop_open_args ap
;
276 * Decrement 3-2-1-0. Does not decrement beyond 0
278 if (vp
->v_flag
& VAGE0
) {
279 vclrflags(vp
, VAGE0
);
280 } else if (vp
->v_flag
& VAGE1
) {
281 vclrflags(vp
, VAGE1
);
282 vsetflags(vp
, VAGE0
);
285 ap
.a_head
.a_desc
= &vop_open_desc
;
286 ap
.a_head
.a_ops
= ops
;
292 VFS_MPLOCK(vp
->v_mount
);
293 DO_OPS(ops
, error
, &ap
, vop_open
);
303 vop_close(struct vop_ops
*ops
, struct vnode
*vp
, int fflag
,
306 struct vop_close_args ap
;
310 ap
.a_head
.a_desc
= &vop_close_desc
;
311 ap
.a_head
.a_ops
= ops
;
316 VFS_MPLOCK(vp
->v_mount
);
317 DO_OPS(ops
, error
, &ap
, vop_close
);
327 vop_access(struct vop_ops
*ops
, struct vnode
*vp
, int mode
, int flags
,
330 struct vop_access_args ap
;
334 ap
.a_head
.a_desc
= &vop_access_desc
;
335 ap
.a_head
.a_ops
= ops
;
341 VFS_MPLOCK(vp
->v_mount
);
342 DO_OPS(ops
, error
, &ap
, vop_access
);
352 vop_getattr(struct vop_ops
*ops
, struct vnode
*vp
, struct vattr
*vap
,
355 struct vop_getattr_args ap
;
359 ap
.a_head
.a_desc
= &vop_getattr_desc
;
360 ap
.a_head
.a_ops
= ops
;
365 VFS_MPLOCK_FLAG(vp
->v_mount
, MNTK_GA_MPSAFE
);
366 DO_OPS(ops
, error
, &ap
, vop_getattr
);
376 vop_getattr_quick(struct vop_ops
*ops
, struct vnode
*vp
, struct vattr
*vap
)
378 struct vop_getattr_args ap
;
382 ap
.a_head
.a_desc
= &vop_getattr_quick_desc
;
383 ap
.a_head
.a_ops
= ops
;
388 VFS_MPLOCK_FLAG(vp
->v_mount
, MNTK_GA_MPSAFE
);
389 DO_OPS(ops
, error
, &ap
, vop_getattr_quick
);
399 vop_setattr(struct vop_ops
*ops
, struct vnode
*vp
, struct vattr
*vap
,
400 struct ucred
*cred
, struct file
*fp
)
402 struct vop_setattr_args ap
;
406 ap
.a_head
.a_desc
= &vop_setattr_desc
;
407 ap
.a_head
.a_ops
= ops
;
413 VFS_MPLOCK(vp
->v_mount
);
414 DO_OPS(ops
, error
, &ap
, vop_setattr
);
424 vop_read(struct vop_ops
*ops
, struct vnode
*vp
, struct uio
*uio
, int ioflag
,
425 struct ucred
*cred
, struct file
*fp
)
427 struct vop_read_args ap
;
431 ap
.a_head
.a_desc
= &vop_read_desc
;
432 ap
.a_head
.a_ops
= ops
;
435 ap
.a_ioflag
= ioflag
;
439 VFS_MPLOCK_FLAG(vp
->v_mount
, MNTK_RD_MPSAFE
);
440 DO_OPS(ops
, error
, &ap
, vop_read
);
450 vop_write(struct vop_ops
*ops
, struct vnode
*vp
, struct uio
*uio
, int ioflag
,
451 struct ucred
*cred
, struct file
*fp
)
453 struct vop_write_args ap
;
455 int error
, do_accounting
= 0;
457 uint64_t size_before
=0, size_after
=0;
459 uint64_t offset
, delta
;
461 ap
.a_head
.a_desc
= &vop_write_desc
;
462 ap
.a_head
.a_ops
= ops
;
465 ap
.a_ioflag
= ioflag
;
469 /* is this a regular vnode ? */
470 VFS_MPLOCK_FLAG(vp
->v_mount
, MNTK_WR_MPSAFE
);
471 if (vfs_quota_enabled
&& (vp
->v_type
== VREG
)) {
472 if ((error
= VOP_GETATTR(vp
, &va
)) != 0)
474 size_before
= va
.va_size
;
475 /* this file may already have been removed */
479 offset
= uio
->uio_offset
;
480 if (ioflag
& IO_APPEND
)
481 offset
= size_before
;
482 size_after
= offset
+ uio
->uio_resid
;
483 if (size_after
< size_before
)
484 size_after
= size_before
;
485 delta
= size_after
- size_before
;
488 if (!vq_write_ok(mp
, va
.va_uid
, va
.va_gid
, delta
)) {
493 DO_OPS(ops
, error
, &ap
, vop_write
);
494 if ((error
== 0) && do_accounting
) {
495 VFS_ACCOUNT(mp
, va
.va_uid
, va
.va_gid
, size_after
- size_before
);
507 vop_ioctl(struct vop_ops
*ops
, struct vnode
*vp
, u_long command
, caddr_t data
,
508 int fflag
, struct ucred
*cred
, struct sysmsg
*msg
)
510 struct vop_ioctl_args ap
;
514 ap
.a_head
.a_desc
= &vop_ioctl_desc
;
515 ap
.a_head
.a_ops
= ops
;
517 ap
.a_command
= command
;
523 VFS_MPLOCK(vp
->v_mount
);
524 DO_OPS(ops
, error
, &ap
, vop_ioctl
);
534 vop_poll(struct vop_ops
*ops
, struct vnode
*vp
, int events
, struct ucred
*cred
)
536 struct vop_poll_args ap
;
540 ap
.a_head
.a_desc
= &vop_poll_desc
;
541 ap
.a_head
.a_ops
= ops
;
543 ap
.a_events
= events
;
546 VFS_MPLOCK(vp
->v_mount
);
547 DO_OPS(ops
, error
, &ap
, vop_poll
);
557 vop_kqfilter(struct vop_ops
*ops
, struct vnode
*vp
, struct knote
*kn
)
559 struct vop_kqfilter_args ap
;
563 ap
.a_head
.a_desc
= &vop_kqfilter_desc
;
564 ap
.a_head
.a_ops
= ops
;
568 VFS_MPLOCK(vp
->v_mount
);
569 DO_OPS(ops
, error
, &ap
, vop_kqfilter
);
579 vop_mmap(struct vop_ops
*ops
, struct vnode
*vp
, int fflags
, struct ucred
*cred
)
581 struct vop_mmap_args ap
;
585 ap
.a_head
.a_desc
= &vop_mmap_desc
;
586 ap
.a_head
.a_ops
= ops
;
588 ap
.a_fflags
= fflags
;
591 VFS_MPLOCK(vp
->v_mount
);
592 DO_OPS(ops
, error
, &ap
, vop_mmap
);
602 vop_fsync(struct vop_ops
*ops
, struct vnode
*vp
, int waitfor
, int flags
,
605 struct vop_fsync_args ap
;
609 ap
.a_head
.a_desc
= &vop_fsync_desc
;
610 ap
.a_head
.a_ops
= ops
;
612 ap
.a_waitfor
= waitfor
;
616 VFS_MPLOCK(vp
->v_mount
);
617 DO_OPS(ops
, error
, &ap
, vop_fsync
);
627 vop_old_remove(struct vop_ops
*ops
, struct vnode
*dvp
,
628 struct vnode
*vp
, struct componentname
*cnp
)
630 struct vop_old_remove_args ap
;
634 ap
.a_head
.a_desc
= &vop_old_remove_desc
;
635 ap
.a_head
.a_ops
= ops
;
640 VFS_MPLOCK(dvp
->v_mount
);
641 DO_OPS(ops
, error
, &ap
, vop_old_remove
);
651 vop_old_link(struct vop_ops
*ops
, struct vnode
*tdvp
,
652 struct vnode
*vp
, struct componentname
*cnp
)
654 struct vop_old_link_args ap
;
658 ap
.a_head
.a_desc
= &vop_old_link_desc
;
659 ap
.a_head
.a_ops
= ops
;
664 VFS_MPLOCK(tdvp
->v_mount
);
665 DO_OPS(ops
, error
, &ap
, vop_old_link
);
675 vop_old_rename(struct vop_ops
*ops
,
676 struct vnode
*fdvp
, struct vnode
*fvp
, struct componentname
*fcnp
,
677 struct vnode
*tdvp
, struct vnode
*tvp
, struct componentname
*tcnp
)
679 struct vop_old_rename_args ap
;
683 ap
.a_head
.a_desc
= &vop_old_rename_desc
;
684 ap
.a_head
.a_ops
= ops
;
692 VFS_MPLOCK(tdvp
->v_mount
);
693 DO_OPS(ops
, error
, &ap
, vop_old_rename
);
703 vop_old_mkdir(struct vop_ops
*ops
, struct vnode
*dvp
,
704 struct vnode
**vpp
, struct componentname
*cnp
, struct vattr
*vap
)
706 struct vop_old_mkdir_args ap
;
710 ap
.a_head
.a_desc
= &vop_old_mkdir_desc
;
711 ap
.a_head
.a_ops
= ops
;
717 VFS_MPLOCK(dvp
->v_mount
);
718 DO_OPS(ops
, error
, &ap
, vop_old_mkdir
);
728 vop_old_rmdir(struct vop_ops
*ops
, struct vnode
*dvp
,
729 struct vnode
*vp
, struct componentname
*cnp
)
731 struct vop_old_rmdir_args ap
;
735 ap
.a_head
.a_desc
= &vop_old_rmdir_desc
;
736 ap
.a_head
.a_ops
= ops
;
741 VFS_MPLOCK(dvp
->v_mount
);
742 DO_OPS(ops
, error
, &ap
, vop_old_rmdir
);
752 vop_old_symlink(struct vop_ops
*ops
, struct vnode
*dvp
,
753 struct vnode
**vpp
, struct componentname
*cnp
,
754 struct vattr
*vap
, char *target
)
756 struct vop_old_symlink_args ap
;
760 ap
.a_head
.a_desc
= &vop_old_symlink_desc
;
761 ap
.a_head
.a_ops
= ops
;
766 ap
.a_target
= target
;
768 VFS_MPLOCK(dvp
->v_mount
);
769 DO_OPS(ops
, error
, &ap
, vop_old_symlink
);
779 vop_readdir(struct vop_ops
*ops
, struct vnode
*vp
, struct uio
*uio
,
780 struct ucred
*cred
, int *eofflag
, int *ncookies
, off_t
**cookies
,
783 struct vop_readdir_args ap
;
787 ap
.a_head
.a_desc
= &vop_readdir_desc
;
788 ap
.a_head
.a_ops
= ops
;
792 ap
.a_eofflag
= eofflag
;
793 ap
.a_ncookies
= ncookies
;
794 ap
.a_cookies
= cookies
;
797 VFS_MPLOCK(vp
->v_mount
);
798 DO_OPS(ops
, error
, &ap
, vop_readdir
);
808 vop_readlink(struct vop_ops
*ops
, struct vnode
*vp
, struct uio
*uio
,
811 struct vop_readlink_args ap
;
815 ap
.a_head
.a_desc
= &vop_readlink_desc
;
816 ap
.a_head
.a_ops
= ops
;
821 VFS_MPLOCK(vp
->v_mount
);
822 DO_OPS(ops
, error
, &ap
, vop_readlink
);
832 vop_inactive(struct vop_ops
*ops
, struct vnode
*vp
)
834 struct vop_inactive_args ap
;
839 ap
.a_head
.a_desc
= &vop_inactive_desc
;
840 ap
.a_head
.a_ops
= ops
;
844 * WARNING! Deactivation of the vnode can cause it to be recycled,
845 * clearing vp->v_mount.
848 VFS_MPLOCK_FLAG(mp
, MNTK_IN_MPSAFE
);
849 DO_OPS(ops
, error
, &ap
, vop_inactive
);
859 vop_reclaim(struct vop_ops
*ops
, struct vnode
*vp
)
861 struct vop_reclaim_args ap
;
866 ap
.a_head
.a_desc
= &vop_reclaim_desc
;
867 ap
.a_head
.a_ops
= ops
;
871 * WARNING! Reclamation of the vnode will clear vp->v_mount.
875 DO_OPS(ops
, error
, &ap
, vop_reclaim
);
885 vop_bmap(struct vop_ops
*ops
, struct vnode
*vp
, off_t loffset
,
886 off_t
*doffsetp
, int *runp
, int *runb
, buf_cmd_t cmd
)
888 struct vop_bmap_args ap
;
892 ap
.a_head
.a_desc
= &vop_bmap_desc
;
893 ap
.a_head
.a_ops
= ops
;
895 ap
.a_loffset
= loffset
;
896 ap
.a_doffsetp
= doffsetp
;
901 VFS_MPLOCK(vp
->v_mount
);
902 DO_OPS(ops
, error
, &ap
, vop_bmap
);
909 * WARNING! Vnode can go-away after the ops call (e.g. async flush
910 * from buffer kthread).
913 vop_strategy(struct vop_ops
*ops
, struct vnode
*vp
, struct bio
*bio
)
915 struct vop_strategy_args ap
;
919 ap
.a_head
.a_desc
= &vop_strategy_desc
;
920 ap
.a_head
.a_ops
= ops
;
925 VFS_MPLOCK_FLAG(vp
->v_mount
, MNTK_SG_MPSAFE
);
926 DO_OPS(ops
, error
, &ap
, vop_strategy
);
929 /* ugly hack for swap */
931 DO_OPS(ops
, error
, &ap
, vop_strategy
);
941 vop_print(struct vop_ops
*ops
, struct vnode
*vp
)
943 struct vop_print_args ap
;
947 ap
.a_head
.a_desc
= &vop_print_desc
;
948 ap
.a_head
.a_ops
= ops
;
951 VFS_MPLOCK(vp
->v_mount
);
952 DO_OPS(ops
, error
, &ap
, vop_print
);
962 vop_pathconf(struct vop_ops
*ops
, struct vnode
*vp
, int name
,
965 struct vop_pathconf_args ap
;
969 ap
.a_head
.a_desc
= &vop_pathconf_desc
;
970 ap
.a_head
.a_ops
= ops
;
973 ap
.a_retval
= retval
;
975 VFS_MPLOCK(vp
->v_mount
);
976 DO_OPS(ops
, error
, &ap
, vop_pathconf
);
986 vop_advlock(struct vop_ops
*ops
, struct vnode
*vp
, caddr_t id
, int op
,
987 struct flock
*fl
, int flags
)
989 struct vop_advlock_args ap
;
993 ap
.a_head
.a_desc
= &vop_advlock_desc
;
994 ap
.a_head
.a_ops
= ops
;
1001 VFS_MPLOCK(vp
->v_mount
);
1002 DO_OPS(ops
, error
, &ap
, vop_advlock
);
1012 vop_balloc(struct vop_ops
*ops
, struct vnode
*vp
, off_t startoffset
,
1013 int size
, struct ucred
*cred
, int flags
,
1016 struct vop_balloc_args ap
;
1020 ap
.a_head
.a_desc
= &vop_balloc_desc
;
1021 ap
.a_head
.a_ops
= ops
;
1023 ap
.a_startoffset
= startoffset
;
1029 VFS_MPLOCK(vp
->v_mount
);
1030 DO_OPS(ops
, error
, &ap
, vop_balloc
);
1040 vop_reallocblks(struct vop_ops
*ops
, struct vnode
*vp
,
1041 struct cluster_save
*buflist
)
1043 struct vop_reallocblks_args ap
;
1047 ap
.a_head
.a_desc
= &vop_reallocblks_desc
;
1048 ap
.a_head
.a_ops
= ops
;
1050 ap
.a_buflist
= buflist
;
1052 VFS_MPLOCK(vp
->v_mount
);
1053 DO_OPS(ops
, error
, &ap
, vop_reallocblks
);
1063 vop_getpages(struct vop_ops
*ops
, struct vnode
*vp
, vm_page_t
*m
, int count
,
1064 int reqpage
, vm_ooffset_t offset
, int seqaccess
)
1066 struct vop_getpages_args ap
;
1070 ap
.a_head
.a_desc
= &vop_getpages_desc
;
1071 ap
.a_head
.a_ops
= ops
;
1075 ap
.a_reqpage
= reqpage
;
1076 ap
.a_offset
= offset
;
1077 ap
.a_seqaccess
= seqaccess
;
1079 VFS_MPLOCK(vp
->v_mount
);
1080 DO_OPS(ops
, error
, &ap
, vop_getpages
);
1090 vop_putpages(struct vop_ops
*ops
, struct vnode
*vp
, vm_page_t
*m
, int count
,
1091 int flags
, int *rtvals
, vm_ooffset_t offset
)
1093 struct vop_putpages_args ap
;
1097 ap
.a_head
.a_desc
= &vop_putpages_desc
;
1098 ap
.a_head
.a_ops
= ops
;
1103 ap
.a_rtvals
= rtvals
;
1104 ap
.a_offset
= offset
;
1106 VFS_MPLOCK(vp
->v_mount
);
1107 DO_OPS(ops
, error
, &ap
, vop_putpages
);
1117 vop_freeblks(struct vop_ops
*ops
, struct vnode
*vp
, off_t offset
, int length
)
1119 struct vop_freeblks_args ap
;
1123 ap
.a_head
.a_desc
= &vop_freeblks_desc
;
1124 ap
.a_head
.a_ops
= ops
;
1126 ap
.a_offset
= offset
;
1127 ap
.a_length
= length
;
1129 VFS_MPLOCK(vp
->v_mount
);
1130 DO_OPS(ops
, error
, &ap
, vop_freeblks
);
1140 vop_getacl(struct vop_ops
*ops
, struct vnode
*vp
, acl_type_t type
,
1141 struct acl
*aclp
, struct ucred
*cred
)
1143 struct vop_getacl_args ap
;
1147 ap
.a_head
.a_desc
= &vop_getacl_desc
;
1148 ap
.a_head
.a_ops
= ops
;
1154 VFS_MPLOCK(vp
->v_mount
);
1155 DO_OPS(ops
, error
, &ap
, vop_getacl
);
1165 vop_setacl(struct vop_ops
*ops
, struct vnode
*vp
, acl_type_t type
,
1166 struct acl
*aclp
, struct ucred
*cred
)
1168 struct vop_setacl_args ap
;
1172 ap
.a_head
.a_desc
= &vop_setacl_desc
;
1173 ap
.a_head
.a_ops
= ops
;
1179 VFS_MPLOCK(vp
->v_mount
);
1180 DO_OPS(ops
, error
, &ap
, vop_setacl
);
1190 vop_aclcheck(struct vop_ops
*ops
, struct vnode
*vp
, acl_type_t type
,
1191 struct acl
*aclp
, struct ucred
*cred
)
1193 struct vop_aclcheck_args ap
;
1197 ap
.a_head
.a_desc
= &vop_aclcheck_desc
;
1198 ap
.a_head
.a_ops
= ops
;
1204 VFS_MPLOCK(vp
->v_mount
);
1205 DO_OPS(ops
, error
, &ap
, vop_aclcheck
);
1215 vop_getextattr(struct vop_ops
*ops
, struct vnode
*vp
, int attrnamespace
,
1216 char *attrname
, struct uio
*uio
, struct ucred
*cred
)
1218 struct vop_getextattr_args ap
;
1222 ap
.a_head
.a_desc
= &vop_getextattr_desc
;
1223 ap
.a_head
.a_ops
= ops
;
1225 ap
.a_attrnamespace
= attrnamespace
;
1226 ap
.a_attrname
= attrname
;
1230 VFS_MPLOCK(vp
->v_mount
);
1231 DO_OPS(ops
, error
, &ap
, vop_getextattr
);
1241 vop_setextattr(struct vop_ops
*ops
, struct vnode
*vp
, int attrnamespace
,
1242 char *attrname
, struct uio
*uio
, struct ucred
*cred
)
1244 struct vop_setextattr_args ap
;
1248 ap
.a_head
.a_desc
= &vop_setextattr_desc
;
1249 ap
.a_head
.a_ops
= ops
;
1251 ap
.a_attrnamespace
= attrnamespace
;
1252 ap
.a_attrname
= attrname
;
1256 VFS_MPLOCK(vp
->v_mount
);
1257 DO_OPS(ops
, error
, &ap
, vop_setextattr
);
1267 vop_mountctl(struct vop_ops
*ops
, struct vnode
*vp
, int op
, struct file
*fp
,
1268 const void *ctl
, int ctllen
, void *buf
, int buflen
, int *res
)
1270 struct vop_mountctl_args ap
;
1274 ap
.a_head
.a_desc
= &vop_mountctl_desc
;
1275 ap
.a_head
.a_ops
= ops
;
1279 ap
.a_ctllen
= ctllen
;
1281 ap
.a_buflen
= buflen
;
1284 VFS_MPLOCK(vp
->v_mount
);
1285 DO_OPS(ops
, error
, &ap
, vop_mountctl
);
1295 vop_markatime(struct vop_ops
*ops
, struct vnode
*vp
, struct ucred
*cred
)
1297 struct vop_markatime_args ap
;
1301 ap
.a_head
.a_desc
= &vop_markatime_desc
;
1302 ap
.a_head
.a_ops
= ops
;
1306 VFS_MPLOCK(vp
->v_mount
);
1307 DO_OPS(ops
, error
, &ap
, vop_markatime
);
1316 * nresolve takes a locked ncp, a referenced but unlocked dvp, and a cred,
1317 * and resolves the ncp into a positive or negative hit.
1319 * The namecache is automatically adjusted by this function. The ncp
1320 * is left locked on return.
1325 vop_nresolve(struct vop_ops
*ops
, struct nchandle
*nch
,
1326 struct vnode
*dvp
, struct ucred
*cred
)
1328 struct vop_nresolve_args ap
;
1332 ap
.a_head
.a_desc
= &vop_nresolve_desc
;
1333 ap
.a_head
.a_ops
= ops
;
1338 VFS_MPLOCK(dvp
->v_mount
);
1339 DO_OPS(ops
, error
, &ap
, vop_nresolve
);
1346 * nlookupdotdot takes an unlocked directory, referenced dvp, and looks
1347 * up "..", returning a locked parent directory in *vpp. If an error
1348 * occurs *vpp will be NULL.
1353 vop_nlookupdotdot(struct vop_ops
*ops
, struct vnode
*dvp
,
1354 struct vnode
**vpp
, struct ucred
*cred
, char **fakename
)
1356 struct vop_nlookupdotdot_args ap
;
1360 ap
.a_head
.a_desc
= &vop_nlookupdotdot_desc
;
1361 ap
.a_head
.a_ops
= ops
;
1365 ap
.a_fakename
= fakename
;
1367 VFS_MPLOCK(dvp
->v_mount
);
1368 DO_OPS(ops
, error
, &ap
, vop_nlookupdotdot
);
1375 * ncreate takes a locked, resolved ncp that typically represents a negative
1376 * cache hit and creates the file or node specified by the ncp, cred, and
1377 * vattr. If no error occurs a locked vnode is returned in *vpp.
1379 * The dvp passed in is referenced but unlocked.
1381 * The namecache is automatically adjusted by this function. The ncp
1382 * is left locked on return.
1387 vop_ncreate(struct vop_ops
*ops
, struct nchandle
*nch
, struct vnode
*dvp
,
1388 struct vnode
**vpp
, struct ucred
*cred
, struct vattr
*vap
)
1390 struct vop_ncreate_args ap
;
1394 ap
.a_head
.a_desc
= &vop_ncreate_desc
;
1395 ap
.a_head
.a_ops
= ops
;
1402 VFS_MPLOCK(dvp
->v_mount
);
1403 DO_OPS(ops
, error
, &ap
, vop_ncreate
);
1410 * nmkdir takes a locked, resolved ncp that typically represents a negative
1411 * cache hit and creates the directory specified by the ncp, cred, and
1412 * vattr. If no error occurs a locked vnode is returned in *vpp.
1414 * The dvp passed in is referenced but unlocked.
1416 * The namecache is automatically adjusted by this function. The ncp
1417 * is left locked on return.
1422 vop_nmkdir(struct vop_ops
*ops
, struct nchandle
*nch
, struct vnode
*dvp
,
1423 struct vnode
**vpp
, struct ucred
*cred
, struct vattr
*vap
)
1425 struct vop_nmkdir_args ap
;
1429 ap
.a_head
.a_desc
= &vop_nmkdir_desc
;
1430 ap
.a_head
.a_ops
= ops
;
1437 VFS_MPLOCK(dvp
->v_mount
);
1438 DO_OPS(ops
, error
, &ap
, vop_nmkdir
);
1445 * nmknod takes a locked, resolved ncp that typically represents a negative
1446 * cache hit and creates the node specified by the ncp, cred, and
1447 * vattr. If no error occurs a locked vnode is returned in *vpp.
1449 * The dvp passed in is referenced but unlocked.
1451 * The namecache is automatically adjusted by this function. The ncp
1452 * is left locked on return.
1457 vop_nmknod(struct vop_ops
*ops
, struct nchandle
*nch
, struct vnode
*dvp
,
1458 struct vnode
**vpp
, struct ucred
*cred
, struct vattr
*vap
)
1460 struct vop_nmknod_args ap
;
1464 ap
.a_head
.a_desc
= &vop_nmknod_desc
;
1465 ap
.a_head
.a_ops
= ops
;
1472 VFS_MPLOCK(dvp
->v_mount
);
1473 DO_OPS(ops
, error
, &ap
, vop_nmknod
);
1480 * nlink takes a locked, resolved ncp that typically represents a negative
1481 * cache hit and creates the node specified by the ncp, cred, and
1482 * existing vnode. The passed vp must be locked and will remain locked
1483 * on return, as does the ncp, whether an error occurs or not.
1485 * The dvp passed in is referenced but unlocked.
1487 * The namecache is automatically adjusted by this function. The ncp
1488 * is left locked on return.
1493 vop_nlink(struct vop_ops
*ops
, struct nchandle
*nch
, struct vnode
*dvp
,
1494 struct vnode
*vp
, struct ucred
*cred
)
1496 struct vop_nlink_args ap
;
1500 ap
.a_head
.a_desc
= &vop_nlink_desc
;
1501 ap
.a_head
.a_ops
= ops
;
1507 VFS_MPLOCK(dvp
->v_mount
);
1508 DO_OPS(ops
, error
, &ap
, vop_nlink
);
1515 * nsymlink takes a locked, resolved ncp that typically represents a negative
1516 * cache hit and creates a symbolic link based on cred, vap, and target (the
1517 * contents of the link). If no error occurs a locked vnode is returned in
1520 * The dvp passed in is referenced but unlocked.
1522 * The namecache is automatically adjusted by this function. The ncp
1523 * is left locked on return.
1528 vop_nsymlink(struct vop_ops
*ops
, struct nchandle
*nch
, struct vnode
*dvp
,
1529 struct vnode
**vpp
, struct ucred
*cred
,
1530 struct vattr
*vap
, char *target
)
1532 struct vop_nsymlink_args ap
;
1536 ap
.a_head
.a_desc
= &vop_nsymlink_desc
;
1537 ap
.a_head
.a_ops
= ops
;
1543 ap
.a_target
= target
;
1545 VFS_MPLOCK(dvp
->v_mount
);
1546 DO_OPS(ops
, error
, &ap
, vop_nsymlink
);
1553 * nwhiteout takes a locked, resolved ncp that can represent a positive or
1554 * negative hit and executes the whiteout function specified in flags.
1556 * The dvp passed in is referenced but unlocked.
1558 * The namecache is automatically adjusted by this function. The ncp
1559 * is left locked on return.
1564 vop_nwhiteout(struct vop_ops
*ops
, struct nchandle
*nch
, struct vnode
*dvp
,
1565 struct ucred
*cred
, int flags
)
1567 struct vop_nwhiteout_args ap
;
1571 ap
.a_head
.a_desc
= &vop_nwhiteout_desc
;
1572 ap
.a_head
.a_ops
= ops
;
1578 VFS_MPLOCK(dvp
->v_mount
);
1579 DO_OPS(ops
, error
, &ap
, vop_nwhiteout
);
1586 * nremove takes a locked, resolved ncp that generally represents a
1587 * positive hit and removes the file.
1589 * The dvp passed in is referenced but unlocked.
1591 * The namecache is automatically adjusted by this function. The ncp
1592 * is left locked on return.
1597 vop_nremove(struct vop_ops
*ops
, struct nchandle
*nch
, struct vnode
*dvp
,
1600 struct vop_nremove_args ap
;
1605 ap
.a_head
.a_desc
= &vop_nremove_desc
;
1606 ap
.a_head
.a_ops
= ops
;
1611 if ((error
= VOP_GETATTR(nch
->ncp
->nc_vp
, &va
)) != 0)
1614 VFS_MPLOCK(dvp
->v_mount
);
1615 DO_OPS(ops
, error
, &ap
, vop_nremove
);
1616 /* Only update space counters if this is the last hard link */
1617 if ((error
== 0) && (va
.va_nlink
== 1)) {
1618 VFS_ACCOUNT(nch
->mount
, va
.va_uid
, va
.va_gid
, -va
.va_size
);
1626 * nrmdir takes a locked, resolved ncp that generally represents a
1627 * directory and removes the directory.
1629 * The dvp passed in is referenced but unlocked.
1631 * The namecache is automatically adjusted by this function. The ncp
1632 * is left locked on return.
1637 vop_nrmdir(struct vop_ops
*ops
, struct nchandle
*nch
, struct vnode
*dvp
,
1640 struct vop_nrmdir_args ap
;
1644 ap
.a_head
.a_desc
= &vop_nrmdir_desc
;
1645 ap
.a_head
.a_ops
= ops
;
1650 VFS_MPLOCK(dvp
->v_mount
);
1651 DO_OPS(ops
, error
, &ap
, vop_nrmdir
);
1658 * nrename takes TWO locked, resolved ncp's and the cred of the caller
1659 * and renames the source ncp to the target ncp. The target ncp may
1660 * represent a positive or negative hit.
1662 * The fdvp and tdvp passed in are referenced but unlocked.
1664 * The namecache is automatically adjusted by this function. The ncp
1665 * is left locked on return. The source ncp is typically changed to
1666 * a negative cache hit and the target ncp typically takes on the
1667 * source ncp's underlying file.
1672 vop_nrename(struct vop_ops
*ops
,
1673 struct nchandle
*fnch
, struct nchandle
*tnch
,
1674 struct vnode
*fdvp
, struct vnode
*tdvp
,
1677 struct vop_nrename_args ap
;
1681 ap
.a_head
.a_desc
= &vop_nrename_desc
;
1682 ap
.a_head
.a_ops
= ops
;
1689 VFS_MPLOCK(fdvp
->v_mount
);
1690 DO_OPS(ops
, error
, &ap
, vop_nrename
);
1696 /************************************************************************
1697 * PRIMARY VNODE OPERATIONS FORWARDING CALLS *
1698 ************************************************************************
1700 * These procedures are called from VFSs such as nullfs
1701 * when they wish to forward an operation on one VFS to another. The
1702 * argument structure/message is modified and then directly passed to the
1703 * appropriate routine. This routines may also be called by initiators
1704 * who have an argument structure in hand rather then discreet arguments.
1706 * MPSAFE - Caller expected to already hold the appropriate vfs lock.
1709 vop_vnoperate_ap(struct vop_generic_args
*ap
)
1711 struct vop_ops
*ops
;
1715 error
= VOCALL(ops
, ap
);
1721 * This routine is called by the cache coherency layer to execute the actual
1722 * VFS operation. If a journaling layer is present we call though it, else
1723 * we call the native VOP functions.
1726 vop_cache_operate_ap(struct vop_generic_args
*ap
)
1728 struct vop_ops
*ops
;
1732 if (ops
->head
.vv_mount
->mnt_vn_journal_ops
)
1733 error
= VOCALL(ops
->head
.vv_mount
->mnt_vn_journal_ops
, ap
);
1735 error
= VOCALL(ops
->head
.vv_mount
->mnt_vn_norm_ops
, ap
);
1741 * This routine is called by the journaling layer to execute the actual
1745 vop_journal_operate_ap(struct vop_generic_args
*ap
)
1747 struct vop_ops
*ops
;
1751 error
= VOCALL(ops
->head
.vv_mount
->mnt_vn_norm_ops
, ap
);
1757 vop_open_ap(struct vop_open_args
*ap
)
1761 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_open
);
1766 vop_close_ap(struct vop_close_args
*ap
)
1770 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_close
);
1775 vop_access_ap(struct vop_access_args
*ap
)
1779 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_access
);
1784 vop_getattr_ap(struct vop_getattr_args
*ap
)
1788 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_getattr
);
1793 vop_getattr_quick_ap(struct vop_getattr_args
*ap
)
1797 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_getattr_quick
);
1802 vop_setattr_ap(struct vop_setattr_args
*ap
)
1806 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_setattr
);
1811 vop_read_ap(struct vop_read_args
*ap
)
1815 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_read
);
1820 vop_write_ap(struct vop_write_args
*ap
)
1824 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_write
);
1829 vop_ioctl_ap(struct vop_ioctl_args
*ap
)
1833 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_ioctl
);
1838 vop_poll_ap(struct vop_poll_args
*ap
)
1842 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_poll
);
1847 vop_kqfilter_ap(struct vop_kqfilter_args
*ap
)
1851 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_kqfilter
);
1856 vop_mmap_ap(struct vop_mmap_args
*ap
)
1860 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_mmap
);
1865 vop_fsync_ap(struct vop_fsync_args
*ap
)
1869 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_fsync
);
1874 vop_readdir_ap(struct vop_readdir_args
*ap
)
1878 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_readdir
);
1883 vop_readlink_ap(struct vop_readlink_args
*ap
)
1887 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_readlink
);
1892 vop_inactive_ap(struct vop_inactive_args
*ap
)
1896 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_inactive
);
1901 vop_reclaim_ap(struct vop_reclaim_args
*ap
)
1905 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_reclaim
);
1910 vop_bmap_ap(struct vop_bmap_args
*ap
)
1914 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_bmap
);
1919 vop_strategy_ap(struct vop_strategy_args
*ap
)
1923 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_strategy
);
1928 vop_print_ap(struct vop_print_args
*ap
)
1932 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_print
);
1937 vop_pathconf_ap(struct vop_pathconf_args
*ap
)
1941 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_pathconf
);
1946 vop_advlock_ap(struct vop_advlock_args
*ap
)
1950 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_advlock
);
1955 vop_balloc_ap(struct vop_balloc_args
*ap
)
1959 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_balloc
);
1964 vop_reallocblks_ap(struct vop_reallocblks_args
*ap
)
1968 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_reallocblks
);
1973 vop_getpages_ap(struct vop_getpages_args
*ap
)
1977 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_getpages
);
1982 vop_putpages_ap(struct vop_putpages_args
*ap
)
1986 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_putpages
);
1991 vop_freeblks_ap(struct vop_freeblks_args
*ap
)
1995 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_freeblks
);
2000 vop_getacl_ap(struct vop_getacl_args
*ap
)
2004 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_getacl
);
2009 vop_setacl_ap(struct vop_setacl_args
*ap
)
2013 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_setacl
);
2018 vop_aclcheck_ap(struct vop_aclcheck_args
*ap
)
2022 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_aclcheck
);
2027 vop_getextattr_ap(struct vop_getextattr_args
*ap
)
2031 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_getextattr
);
2036 vop_setextattr_ap(struct vop_setextattr_args
*ap
)
2040 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_setextattr
);
2045 vop_mountctl_ap(struct vop_mountctl_args
*ap
)
2049 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_mountctl
);
2054 vop_markatime_ap(struct vop_markatime_args
*ap
)
2058 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_markatime
);
2063 vop_nresolve_ap(struct vop_nresolve_args
*ap
)
2067 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_nresolve
);
2072 vop_nlookupdotdot_ap(struct vop_nlookupdotdot_args
*ap
)
2076 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_nlookupdotdot
);
2081 vop_ncreate_ap(struct vop_ncreate_args
*ap
)
2085 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_ncreate
);
2090 vop_nmkdir_ap(struct vop_nmkdir_args
*ap
)
2094 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_nmkdir
);
2099 vop_nmknod_ap(struct vop_nmknod_args
*ap
)
2103 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_nmknod
);
2108 vop_nlink_ap(struct vop_nlink_args
*ap
)
2112 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_nlink
);
2117 vop_nsymlink_ap(struct vop_nsymlink_args
*ap
)
2121 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_nsymlink
);
2126 vop_nwhiteout_ap(struct vop_nwhiteout_args
*ap
)
2130 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_nwhiteout
);
2135 vop_nremove_ap(struct vop_nremove_args
*ap
)
2139 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_nremove
);
2144 vop_nrmdir_ap(struct vop_nrmdir_args
*ap
)
2148 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_nrmdir
);
2153 vop_nrename_ap(struct vop_nrename_args
*ap
)
2157 DO_OPS(ap
->a_head
.a_ops
, error
, ap
, vop_nrename
);