1 /*        $NetBSD: vnode_if.c,v 1.119 2023/06/15 09:15:13 hannken Exp $         */
2 
3 /*
4  * Warning: DO NOT EDIT! This file is automatically generated!
5  * (Modifications made here may easily be lost!)
6  *
7  * Created from the file:
8  *        NetBSD: vnode_if.src,v 1.85 2023/06/15 09:13:36 hannken Exp
9  * by the script:
10  *        NetBSD: vnode_if.sh,v 1.77 2022/10/26 23:39:43 riastradh Exp
11  */
12 
13 /*
14  * Copyright (c) 1992, 1993, 1994, 1995
15  *        The Regents of the University of California.  All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  * 1. Redistributions of source code must retain the above copyright
21  *    notice, this list of conditions and the following disclaimer.
22  * 2. Redistributions in binary form must reproduce the above copyright
23  *    notice, this list of conditions and the following disclaimer in the
24  *    documentation and/or other materials provided with the distribution.
25  * 3. Neither the name of the University nor the names of its contributors
26  *    may be used to endorse or promote products derived from this software
27  *    without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39  * SUCH DAMAGE.
40  */
41 
42 #include <sys/cdefs.h>
43 __KERNEL_RCSID(0, "$NetBSD: vnode_if.c,v 1.119 2023/06/15 09:15:13 hannken Exp $");
44 
45 #ifdef _KERNEL_OPT
46 #include "opt_vnode_lockdebug.h"
47 #endif /* _KERNEL_OPT */
48 
49 #include <sys/param.h>
50 #include <sys/mount.h>
51 #include <sys/buf.h>
52 #include <sys/fcntl.h>
53 #include <sys/vnode.h>
54 #include <sys/lock.h>
55 #include <sys/fstrans.h>
56 
57 #include <miscfs/deadfs/deadfs.h>
58 
59 enum fst_op { FST_NO, FST_YES, FST_LAZY, FST_TRY };
60 
61 static inline int
vop_pre(vnode_t * vp,struct mount ** mp,bool * mpsafe,enum fst_op op)62 vop_pre(vnode_t *vp, struct mount **mp, bool *mpsafe, enum fst_op op)
63 {
64           int error;
65 
66           *mpsafe = (vp->v_vflag & VV_MPSAFE);
67 
68           if (!*mpsafe) {
69                     KERNEL_LOCK(1, curlwp);
70           }
71 
72           if (op == FST_YES || op == FST_LAZY || op == FST_TRY) {
73                     for (;;) {
74                               *mp = vp->v_mount;
75                               if (op == FST_TRY) {
76                                         error = fstrans_start_nowait(*mp);
77                                         if (error) {
78                                                   if (!*mpsafe) {
79                                                             KERNEL_UNLOCK_ONE(curlwp);
80                                                   }
81                                                   return error;
82                                         }
83                               } else if (op == FST_LAZY) {
84                                         fstrans_start_lazy(*mp);
85                               } else {
86                                         fstrans_start(*mp);
87                               }
88                               if (__predict_true(*mp == vp->v_mount))
89                                         break;
90                               fstrans_done(*mp);
91                     }
92           } else {
93                     *mp = vp->v_mount;
94           }
95 
96           return 0;
97 }
98 
99 static inline u_quad_t
vop_pre_get_size(struct vnode * vp)100 vop_pre_get_size(struct vnode *vp)
101 {
102           mutex_enter(vp->v_interlock);
103           KASSERT(vp->v_size != VSIZENOTSET);
104           u_quad_t rv = (u_quad_t)vp->v_size;
105           mutex_exit(vp->v_interlock);
106 
107           return rv;
108 }
109 
110 /*
111  * VOP_RMDIR(), VOP_REMOVE(), and VOP_RENAME() need special handling
112  * because they each drop the caller's references on one or more of
113  * their arguments.  While there must be an open file descriptor in
114  * associated with a vnode in order for knotes to be attached to it,
115  * that status could change during the course of the operation.  So,
116  * for the vnode arguments that are WILLRELE or WILLPUT, we check
117  * pre-op if there are registered knotes, take a hold count if so,
118  * and post-op release the hold after activating any knotes still
119  * associated with the vnode.
120  */
121 
122 #define   VOP_POST_KNOTE(thisvp, e, n)                                          \
123 do {                                                                                      \
124           if (__predict_true((e) == 0)) {                                                 \
125                     /*                                                                    \
126                      * VN_KNOTE() does the VN_KEVENT_INTEREST()                 \
127                      * check for us.                                            \
128                      */                                                                   \
129                     VN_KNOTE((thisvp), (n));                                    \
130           }                                                                               \
131 } while (/*CONSTCOND*/0)
132 
133 #define   VOP_POST_KNOTE_HELD(thisvp, e, n)                                     \
134 do {                                                                                      \
135           /*                                                                              \
136            * We don't perform a VN_KEVENT_INTEREST() check here; it   \
137            * was already performed when we did the pre-op work that   \
138            * caused the vnode to be held in the first place.                    \
139            */                                                                             \
140           mutex_enter((thisvp)->v_interlock);                                   \
141           if (__predict_true((e) == 0)) {                                                 \
142                     knote(&(thisvp)->v_klist->vk_klist, (n));                   \
143           }                                                                               \
144           holdrelel((thisvp));                                                            \
145           mutex_exit((thisvp)->v_interlock);                                    \
146           /*                                                                              \
147            * thisvp might be gone now!  Don't touch!                            \
148            */                                                                             \
149 } while (/*CONSTCOND*/0)
150 
151 #define   vop_create_post(ap, e)                                                          \
152           VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE)
153 
154 #define   vop_mknod_post(ap, e)                                                           \
155           VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE)
156 
157 #define   vop_setattr_pre(ap)                                                   \
158           u_quad_t osize = 0;                                                   \
159           long vp_events =                                                      \
160               VN_KEVENT_INTEREST((ap)->a_vp, NOTE_ATTRIB | NOTE_EXTEND)         \
161               ? NOTE_ATTRIB : 0;                                                          \
162           bool check_extend = false;                                            \
163           if (__predict_false(vp_events != 0 &&                                 \
164               (ap)->a_vap->va_size != VNOVALSIZE)) {                            \
165                     check_extend = true;                                                  \
166                     osize = vop_pre_get_size((ap)->a_vp);                       \
167           }
168 
169 #define   vop_setattr_post(ap, e)                                                         \
170 do {                                                                                      \
171           if (__predict_false(vp_events != 0)) {                                \
172                     if (__predict_false(check_extend &&                         \
173                         (ap)->a_vap->va_size > osize)) {                        \
174                               vp_events |= NOTE_EXTEND;                         \
175                     }                                                                     \
176                     VOP_POST_KNOTE((ap)->a_vp, (e), vp_events);                 \
177           }                                                                               \
178 } while (/*CONSTCOND*/0)
179 
180 #define   vop_setacl_post(ap, e)                                                          \
181           VOP_POST_KNOTE((ap)->a_vp, (e), NOTE_ATTRIB)
182 
183 #define   vop_link_post(ap, e)                                                            \
184 do {                                                                                      \
185           VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE);                         \
186           VOP_POST_KNOTE((ap)->a_vp, (e), NOTE_LINK);                           \
187 } while (/*CONSTCOND*/0)
188 
189 #define   vop_mkdir_post(ap, e)                                                           \
190           VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE | NOTE_LINK)
191 
192 #define   vop_remove_pre_common(ap)                                             \
193           bool post_event_vp =                                                            \
194               VN_KEVENT_INTEREST((ap)->a_vp, NOTE_DELETE | NOTE_LINK);          \
195           if (__predict_false(post_event_vp)) {                                 \
196                     vhold((ap)->a_vp);                                          \
197           }
198 
199 #define   vop_remove_post_common(ap, e, dn, lc)                                 \
200 do {                                                                                      \
201           VOP_POST_KNOTE((ap)->a_dvp, (e), (dn));                               \
202           if (__predict_false(post_event_vp)) {                                 \
203                     VOP_POST_KNOTE_HELD((ap)->a_vp, (e),                        \
204                         (lc) ? NOTE_LINK : NOTE_DELETE);                        \
205           }                                                                               \
206 } while (/*CONSTCOND*/0)
207 
208 /*
209  * One could make the argument that VOP_REMOVE() should send NOTE_LINK
210  * on vp if the resulting link count is not zero, but that's not what
211  * the documentation says.
212  *
213  * We could change this easily by passing ap->ctx_vp_new_nlink to
214  * vop_remove_post_common().
215  */
216 #define   vop_remove_pre(ap)                                                    \
217           vop_remove_pre_common((ap));                                          \
218           /*                                                                              \
219            * We will assume that the file being removed is deleted unless       \
220            * the file system tells us otherwise by updating vp_new_nlink.       \
221            */                                                                             \
222           (ap)->ctx_vp_new_nlink = 0;
223 
224 #define   vop_remove_post(ap, e)                                                          \
225           vop_remove_post_common((ap), (e), NOTE_WRITE, 0)
226 
227 #define   vop_rmdir_pre(ap)                                                     \
228           vop_remove_pre_common(ap)
229 
230 #define   vop_rmdir_post(ap, e)                                                           \
231           vop_remove_post_common((ap), (e), NOTE_WRITE | NOTE_LINK, 0)
232 
233 #define   vop_symlink_post(ap, e)                                                         \
234           VOP_POST_KNOTE((ap)->a_dvp, (e), NOTE_WRITE)
235 
236 #define   vop_open_post(ap, e)                                                            \
237           VOP_POST_KNOTE((ap)->a_vp, (e), NOTE_OPEN)
238 
239 #define   vop_close_post(ap, e)                                                           \
240 do {                                                                                      \
241           /* See the definition of VN_KNOTE() in <sys/vnode.h>. */    \
242           if (__predict_false(VN_KEVENT_INTEREST((ap)->a_vp,                    \
243               NOTE_CLOSE_WRITE | NOTE_CLOSE) && (e) == 0)) {                    \
244                     struct vnode *thisvp = (ap)->a_vp;                          \
245                     mutex_enter(thisvp->v_interlock);                           \
246                     /*                                                                    \
247                      * Don't send NOTE_CLOSE when closing a vnode that's        \
248                      * been reclaimed or otherwise revoked; a NOTE_REVOKE       \
249                      * has already been sent, and this close is effectively     \
250                      * meaningless from the watcher's perspective.              \
251                      */                                                                   \
252                     if (__predict_true(thisvp->v_op != dead_vnodeop_p)) {       \
253                               knote(&thisvp->v_klist->vk_klist,                 \
254                                   ((ap)->a_fflag & FWRITE)                      \
255                                   ? NOTE_CLOSE_WRITE : NOTE_CLOSE);             \
256                     }                                                                     \
257                     mutex_exit(thisvp->v_interlock);                            \
258           }                                                                               \
259 } while (/*CONSTCOND*/0)
260 
261 #define   vop_read_post(ap, e)                                                            \
262           VOP_POST_KNOTE((ap)->a_vp, (e), NOTE_READ)
263 
264 #define   vop_write_pre(ap)                                                     \
265           off_t ooffset = 0, noffset = 0;                                                 \
266           u_quad_t osize = 0;                                                   \
267           long vp_events =                                                      \
268               VN_KEVENT_INTEREST((ap)->a_vp, NOTE_WRITE | NOTE_EXTEND)          \
269               ? NOTE_WRITE : 0;                                                           \
270           if (__predict_false(vp_events != 0)) {                                \
271                     ooffset = (ap)->a_uio->uio_offset;                          \
272                     osize = vop_pre_get_size((ap)->a_vp);                       \
273           }
274 
275 #define   vop_write_post(ap, e)                                                           \
276 do {                                                                                      \
277           /*                                                                              \
278            * If any data was written, we'll post an event, even if    \
279            * there was an error.                                                          \
280            */                                                                             \
281           noffset = (ap)->a_uio->uio_offset;                                    \
282           if (__predict_false(vp_events != 0 && noffset > ooffset)) { \
283                     if (noffset > osize) {                                                \
284                               vp_events |= NOTE_EXTEND;                         \
285                     }                                                                     \
286                     VN_KNOTE((ap)->a_vp, vp_events);                            \
287           }                                                                               \
288 } while (/*CONSTCOND*/0)
289 
290 static inline void
vop_post(vnode_t * vp,struct mount * mp,bool mpsafe,enum fst_op op)291 vop_post(vnode_t *vp, struct mount *mp, bool mpsafe, enum fst_op op)
292 {
293 
294           if (op == FST_YES || op == FST_LAZY) {
295                     fstrans_done(mp);
296           }
297 
298           if (!mpsafe) {
299                     KERNEL_UNLOCK_ONE(curlwp);
300           }
301 }
302 
303 static inline void
assert_vop_unlocked(vnode_t * vp,const char * str)304 assert_vop_unlocked(vnode_t *vp, const char *str)
305 {
306 #if defined(VNODE_LOCKDEBUG)
307 
308           if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE)
309                     panic("%s: %p %d/%d is locked but should not be",
310                         str, vp, vp->v_tag, vp->v_type);
311 #endif
312 }
313 
314 static inline void
assert_vop_locked(vnode_t * vp,const char * str)315 assert_vop_locked(vnode_t *vp, const char *str)
316 {
317 #if defined(VNODE_LOCKDEBUG)
318 
319           if (VOP_ISLOCKED(vp) == LK_NONE)
320                     panic("%s: %p %d/%d is not locked but should be",
321                         str, vp, vp->v_tag, vp->v_type);
322 #endif
323 }
324 
325 static inline void
assert_vop_elocked(vnode_t * vp,const char * str)326 assert_vop_elocked(vnode_t *vp, const char *str)
327 {
328 #if defined(VNODE_LOCKDEBUG)
329 
330           if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE)
331                     panic("%s: %p %d/%d is not exclusive locked but should be",
332                         str, vp, vp->v_tag, vp->v_type);
333 #endif
334 }
335 
336 const struct vnodeop_desc vop_default_desc = {
337           0,
338           "default",
339           0,
340           NULL,
341           VDESC_NO_OFFSET,
342           VDESC_NO_OFFSET,
343           VDESC_NO_OFFSET,
344 };
345 
346 
347 const int vop_bwrite_vp_offsets[] = {
348           VOPARG_OFFSETOF(struct vop_bwrite_args,a_vp),
349           VDESC_NO_OFFSET
350 };
351 const struct vnodeop_desc vop_bwrite_desc = {
352           VOP_BWRITE_DESCOFFSET,
353           "vop_bwrite",
354           0,
355           vop_bwrite_vp_offsets,
356           VDESC_NO_OFFSET,
357           VDESC_NO_OFFSET,
358           VDESC_NO_OFFSET,
359 };
360 int
VOP_BWRITE(struct vnode * vp,struct buf * bp)361 VOP_BWRITE(struct vnode *vp,
362     struct buf *bp)
363 {
364           int error;
365           bool mpsafe;
366           struct vop_bwrite_args a;
367           struct mount *mp;
368           a.a_desc = VDESC(vop_bwrite);
369           a.a_vp = vp;
370           a.a_bp = bp;
371           error = vop_pre(vp, &mp, &mpsafe, FST_YES);
372           if (error)
373                     return error;
374           error = (VCALL(vp, VOFFSET(vop_bwrite), &a));
375           vop_post(vp, mp, mpsafe, FST_YES);
376           return error;
377 }
378 
379 const int vop_parsepath_vp_offsets[] = {
380           VOPARG_OFFSETOF(struct vop_parsepath_args,a_dvp),
381           VDESC_NO_OFFSET
382 };
383 const struct vnodeop_desc vop_parsepath_desc = {
384           VOP_PARSEPATH_DESCOFFSET,
385           "vop_parsepath",
386           0,
387           vop_parsepath_vp_offsets,
388           VDESC_NO_OFFSET,
389           VDESC_NO_OFFSET,
390           VDESC_NO_OFFSET,
391 };
392 int
VOP_PARSEPATH(struct vnode * dvp,const char * name,size_t * retval)393 VOP_PARSEPATH(struct vnode *dvp,
394     const char *name,
395     size_t *retval)
396 {
397           int error;
398           bool mpsafe;
399           struct vop_parsepath_args a;
400           struct mount *mp;
401           a.a_desc = VDESC(vop_parsepath);
402           a.a_dvp = dvp;
403           a.a_name = name;
404           a.a_retval = retval;
405           error = vop_pre(dvp, &mp, &mpsafe, FST_NO);
406           if (error)
407                     return error;
408           error = (VCALL(dvp, VOFFSET(vop_parsepath), &a));
409           vop_post(dvp, mp, mpsafe, FST_NO);
410           return error;
411 }
412 
413 const int vop_lookup_vp_offsets[] = {
414           VOPARG_OFFSETOF(struct vop_lookup_v2_args,a_dvp),
415           VDESC_NO_OFFSET
416 };
417 const struct vnodeop_desc vop_lookup_desc = {
418           VOP_LOOKUP_DESCOFFSET,
419           "vop_lookup",
420           0,
421           vop_lookup_vp_offsets,
422           VOPARG_OFFSETOF(struct vop_lookup_v2_args, a_vpp),
423           VDESC_NO_OFFSET,
424           VOPARG_OFFSETOF(struct vop_lookup_v2_args, a_cnp),
425 };
426 int
VOP_LOOKUP(struct vnode * dvp,struct vnode ** vpp,struct componentname * cnp)427 VOP_LOOKUP(struct vnode *dvp,
428     struct vnode **vpp,
429     struct componentname *cnp)
430 {
431           int error;
432           bool mpsafe;
433           struct vop_lookup_v2_args a;
434           struct mount *mp;
435           a.a_desc = VDESC(vop_lookup);
436           a.a_dvp = dvp;
437           a.a_vpp = vpp;
438           a.a_cnp = cnp;
439           assert_vop_locked(dvp, "vop_lookup: dvp");
440           error = vop_pre(dvp, &mp, &mpsafe, FST_NO);
441           if (error)
442                     return error;
443           error = (VCALL(dvp, VOFFSET(vop_lookup), &a));
444           vop_post(dvp, mp, mpsafe, FST_NO);
445 #ifdef DIAGNOSTIC
446           if (error == 0)
447                     KASSERT((*vpp)->v_size != VSIZENOTSET
448                         && (*vpp)->v_writesize != VSIZENOTSET);
449 #endif /* DIAGNOSTIC */
450           return error;
451 }
452 
453 const int vop_create_vp_offsets[] = {
454           VOPARG_OFFSETOF(struct vop_create_v3_args,a_dvp),
455           VDESC_NO_OFFSET
456 };
457 const struct vnodeop_desc vop_create_desc = {
458           VOP_CREATE_DESCOFFSET,
459           "vop_create",
460           0,
461           vop_create_vp_offsets,
462           VOPARG_OFFSETOF(struct vop_create_v3_args, a_vpp),
463           VDESC_NO_OFFSET,
464           VOPARG_OFFSETOF(struct vop_create_v3_args, a_cnp),
465 };
466 int
VOP_CREATE(struct vnode * dvp,struct vnode ** vpp,struct componentname * cnp,struct vattr * vap)467 VOP_CREATE(struct vnode *dvp,
468     struct vnode **vpp,
469     struct componentname *cnp,
470     struct vattr *vap)
471 {
472           int error;
473           bool mpsafe;
474           struct vop_create_v3_args a;
475           struct mount *mp;
476           a.a_desc = VDESC(vop_create);
477           a.a_dvp = dvp;
478           a.a_vpp = vpp;
479           a.a_cnp = cnp;
480           a.a_vap = vap;
481           assert_vop_elocked(dvp, "vop_create: dvp");
482           error = vop_pre(dvp, &mp, &mpsafe, FST_NO);
483           if (error)
484                     return error;
485           error = (VCALL(dvp, VOFFSET(vop_create), &a));
486           vop_post(dvp, mp, mpsafe, FST_NO);
487           vop_create_post(&a, error);
488 #ifdef DIAGNOSTIC
489           if (error == 0)
490                     KASSERT((*vpp)->v_size != VSIZENOTSET
491                         && (*vpp)->v_writesize != VSIZENOTSET);
492 #endif /* DIAGNOSTIC */
493           return error;
494 }
495 
496 const int vop_mknod_vp_offsets[] = {
497           VOPARG_OFFSETOF(struct vop_mknod_v3_args,a_dvp),
498           VDESC_NO_OFFSET
499 };
500 const struct vnodeop_desc vop_mknod_desc = {
501           VOP_MKNOD_DESCOFFSET,
502           "vop_mknod",
503           0,
504           vop_mknod_vp_offsets,
505           VOPARG_OFFSETOF(struct vop_mknod_v3_args, a_vpp),
506           VDESC_NO_OFFSET,
507           VOPARG_OFFSETOF(struct vop_mknod_v3_args, a_cnp),
508 };
509 int
VOP_MKNOD(struct vnode * dvp,struct vnode ** vpp,struct componentname * cnp,struct vattr * vap)510 VOP_MKNOD(struct vnode *dvp,
511     struct vnode **vpp,
512     struct componentname *cnp,
513     struct vattr *vap)
514 {
515           int error;
516           bool mpsafe;
517           struct vop_mknod_v3_args a;
518           struct mount *mp;
519           a.a_desc = VDESC(vop_mknod);
520           a.a_dvp = dvp;
521           a.a_vpp = vpp;
522           a.a_cnp = cnp;
523           a.a_vap = vap;
524           assert_vop_elocked(dvp, "vop_mknod: dvp");
525           error = vop_pre(dvp, &mp, &mpsafe, FST_NO);
526           if (error)
527                     return error;
528           error = (VCALL(dvp, VOFFSET(vop_mknod), &a));
529           vop_post(dvp, mp, mpsafe, FST_NO);
530           vop_mknod_post(&a, error);
531 #ifdef DIAGNOSTIC
532           if (error == 0)
533                     KASSERT((*vpp)->v_size != VSIZENOTSET
534                         && (*vpp)->v_writesize != VSIZENOTSET);
535 #endif /* DIAGNOSTIC */
536           return error;
537 }
538 
539 const int vop_open_vp_offsets[] = {
540           VOPARG_OFFSETOF(struct vop_open_args,a_vp),
541           VDESC_NO_OFFSET
542 };
543 const struct vnodeop_desc vop_open_desc = {
544           VOP_OPEN_DESCOFFSET,
545           "vop_open",
546           0,
547           vop_open_vp_offsets,
548           VDESC_NO_OFFSET,
549           VOPARG_OFFSETOF(struct vop_open_args, a_cred),
550           VDESC_NO_OFFSET,
551 };
552 int
VOP_OPEN(struct vnode * vp,int mode,kauth_cred_t cred)553 VOP_OPEN(struct vnode *vp,
554     int mode,
555     kauth_cred_t cred)
556 {
557           int error;
558           bool mpsafe;
559           struct vop_open_args a;
560           struct mount *mp;
561           a.a_desc = VDESC(vop_open);
562           a.a_vp = vp;
563           a.a_mode = mode;
564           a.a_cred = cred;
565           assert_vop_locked(vp, "vop_open: vp");
566           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
567           if (error)
568                     return error;
569           error = (VCALL(vp, VOFFSET(vop_open), &a));
570           vop_post(vp, mp, mpsafe, FST_NO);
571           vop_open_post(&a, error);
572           return error;
573 }
574 
575 const int vop_close_vp_offsets[] = {
576           VOPARG_OFFSETOF(struct vop_close_args,a_vp),
577           VDESC_NO_OFFSET
578 };
579 const struct vnodeop_desc vop_close_desc = {
580           VOP_CLOSE_DESCOFFSET,
581           "vop_close",
582           0,
583           vop_close_vp_offsets,
584           VDESC_NO_OFFSET,
585           VOPARG_OFFSETOF(struct vop_close_args, a_cred),
586           VDESC_NO_OFFSET,
587 };
588 int
VOP_CLOSE(struct vnode * vp,int fflag,kauth_cred_t cred)589 VOP_CLOSE(struct vnode *vp,
590     int fflag,
591     kauth_cred_t cred)
592 {
593           int error;
594           bool mpsafe;
595           struct vop_close_args a;
596           struct mount *mp;
597           a.a_desc = VDESC(vop_close);
598           a.a_vp = vp;
599           a.a_fflag = fflag;
600           a.a_cred = cred;
601           assert_vop_locked(vp, "vop_close: vp");
602           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
603           if (error)
604                     return error;
605           error = (VCALL(vp, VOFFSET(vop_close), &a));
606           vop_post(vp, mp, mpsafe, FST_NO);
607           vop_close_post(&a, error);
608           return error;
609 }
610 
611 const int vop_access_vp_offsets[] = {
612           VOPARG_OFFSETOF(struct vop_access_args,a_vp),
613           VDESC_NO_OFFSET
614 };
615 const struct vnodeop_desc vop_access_desc = {
616           VOP_ACCESS_DESCOFFSET,
617           "vop_access",
618           0,
619           vop_access_vp_offsets,
620           VDESC_NO_OFFSET,
621           VOPARG_OFFSETOF(struct vop_access_args, a_cred),
622           VDESC_NO_OFFSET,
623 };
624 int
VOP_ACCESS(struct vnode * vp,accmode_t accmode,kauth_cred_t cred)625 VOP_ACCESS(struct vnode *vp,
626     accmode_t accmode,
627     kauth_cred_t cred)
628 {
629           int error;
630           bool mpsafe;
631           struct vop_access_args a;
632           struct mount *mp;
633           a.a_desc = VDESC(vop_access);
634           a.a_vp = vp;
635           a.a_accmode = accmode;
636           a.a_cred = cred;
637           assert_vop_locked(vp, "vop_access: vp");
638           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
639           if (error)
640                     return error;
641           error = (VCALL(vp, VOFFSET(vop_access), &a));
642           vop_post(vp, mp, mpsafe, FST_NO);
643           return error;
644 }
645 
646 const int vop_accessx_vp_offsets[] = {
647           VOPARG_OFFSETOF(struct vop_accessx_args,a_vp),
648           VDESC_NO_OFFSET
649 };
650 const struct vnodeop_desc vop_accessx_desc = {
651           VOP_ACCESSX_DESCOFFSET,
652           "vop_accessx",
653           0,
654           vop_accessx_vp_offsets,
655           VDESC_NO_OFFSET,
656           VOPARG_OFFSETOF(struct vop_accessx_args, a_cred),
657           VDESC_NO_OFFSET,
658 };
659 int
VOP_ACCESSX(struct vnode * vp,accmode_t accmode,kauth_cred_t cred)660 VOP_ACCESSX(struct vnode *vp,
661     accmode_t accmode,
662     kauth_cred_t cred)
663 {
664           int error;
665           bool mpsafe;
666           struct vop_accessx_args a;
667           struct mount *mp;
668           a.a_desc = VDESC(vop_accessx);
669           a.a_vp = vp;
670           a.a_accmode = accmode;
671           a.a_cred = cred;
672           assert_vop_locked(vp, "vop_accessx: vp");
673           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
674           if (error)
675                     return error;
676           error = (VCALL(vp, VOFFSET(vop_accessx), &a));
677           vop_post(vp, mp, mpsafe, FST_NO);
678           return error;
679 }
680 
681 const int vop_getattr_vp_offsets[] = {
682           VOPARG_OFFSETOF(struct vop_getattr_args,a_vp),
683           VDESC_NO_OFFSET
684 };
685 const struct vnodeop_desc vop_getattr_desc = {
686           VOP_GETATTR_DESCOFFSET,
687           "vop_getattr",
688           0,
689           vop_getattr_vp_offsets,
690           VDESC_NO_OFFSET,
691           VOPARG_OFFSETOF(struct vop_getattr_args, a_cred),
692           VDESC_NO_OFFSET,
693 };
694 int
VOP_GETATTR(struct vnode * vp,struct vattr * vap,kauth_cred_t cred)695 VOP_GETATTR(struct vnode *vp,
696     struct vattr *vap,
697     kauth_cred_t cred)
698 {
699           int error;
700           bool mpsafe;
701           struct vop_getattr_args a;
702           struct mount *mp;
703           a.a_desc = VDESC(vop_getattr);
704           a.a_vp = vp;
705           a.a_vap = vap;
706           a.a_cred = cred;
707           assert_vop_locked(vp, "vop_getattr: vp");
708           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
709           if (error)
710                     return error;
711           error = (VCALL(vp, VOFFSET(vop_getattr), &a));
712           vop_post(vp, mp, mpsafe, FST_NO);
713           return error;
714 }
715 
716 const int vop_setattr_vp_offsets[] = {
717           VOPARG_OFFSETOF(struct vop_setattr_args,a_vp),
718           VDESC_NO_OFFSET
719 };
720 const struct vnodeop_desc vop_setattr_desc = {
721           VOP_SETATTR_DESCOFFSET,
722           "vop_setattr",
723           0,
724           vop_setattr_vp_offsets,
725           VDESC_NO_OFFSET,
726           VOPARG_OFFSETOF(struct vop_setattr_args, a_cred),
727           VDESC_NO_OFFSET,
728 };
729 int
VOP_SETATTR(struct vnode * vp,struct vattr * vap,kauth_cred_t cred)730 VOP_SETATTR(struct vnode *vp,
731     struct vattr *vap,
732     kauth_cred_t cred)
733 {
734           int error;
735           bool mpsafe;
736           struct vop_setattr_args a;
737           struct mount *mp;
738           a.a_desc = VDESC(vop_setattr);
739           a.a_vp = vp;
740           a.a_vap = vap;
741           a.a_cred = cred;
742           assert_vop_elocked(vp, "vop_setattr: vp");
743           vop_setattr_pre(&a);
744           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
745           if (error)
746                     return error;
747           error = (VCALL(vp, VOFFSET(vop_setattr), &a));
748           vop_post(vp, mp, mpsafe, FST_NO);
749           vop_setattr_post(&a, error);
750           return error;
751 }
752 
753 const int vop_read_vp_offsets[] = {
754           VOPARG_OFFSETOF(struct vop_read_args,a_vp),
755           VDESC_NO_OFFSET
756 };
757 const struct vnodeop_desc vop_read_desc = {
758           VOP_READ_DESCOFFSET,
759           "vop_read",
760           0,
761           vop_read_vp_offsets,
762           VDESC_NO_OFFSET,
763           VOPARG_OFFSETOF(struct vop_read_args, a_cred),
764           VDESC_NO_OFFSET,
765 };
766 int
VOP_READ(struct vnode * vp,struct uio * uio,int ioflag,kauth_cred_t cred)767 VOP_READ(struct vnode *vp,
768     struct uio *uio,
769     int ioflag,
770     kauth_cred_t cred)
771 {
772           int error;
773           bool mpsafe;
774           struct vop_read_args a;
775           struct mount *mp;
776           a.a_desc = VDESC(vop_read);
777           a.a_vp = vp;
778           a.a_uio = uio;
779           a.a_ioflag = ioflag;
780           a.a_cred = cred;
781           assert_vop_locked(vp, "vop_read: vp");
782           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
783           if (error)
784                     return error;
785           error = (VCALL(vp, VOFFSET(vop_read), &a));
786           vop_post(vp, mp, mpsafe, FST_NO);
787           vop_read_post(&a, error);
788           return error;
789 }
790 
791 const int vop_write_vp_offsets[] = {
792           VOPARG_OFFSETOF(struct vop_write_args,a_vp),
793           VDESC_NO_OFFSET
794 };
795 const struct vnodeop_desc vop_write_desc = {
796           VOP_WRITE_DESCOFFSET,
797           "vop_write",
798           0,
799           vop_write_vp_offsets,
800           VDESC_NO_OFFSET,
801           VOPARG_OFFSETOF(struct vop_write_args, a_cred),
802           VDESC_NO_OFFSET,
803 };
804 int
VOP_WRITE(struct vnode * vp,struct uio * uio,int ioflag,kauth_cred_t cred)805 VOP_WRITE(struct vnode *vp,
806     struct uio *uio,
807     int ioflag,
808     kauth_cred_t cred)
809 {
810           int error;
811           bool mpsafe;
812           struct vop_write_args a;
813           struct mount *mp;
814           a.a_desc = VDESC(vop_write);
815           a.a_vp = vp;
816           a.a_uio = uio;
817           a.a_ioflag = ioflag;
818           a.a_cred = cred;
819           assert_vop_locked(vp, "vop_write: vp");
820           vop_write_pre(&a);
821           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
822           if (error)
823                     return error;
824           error = (VCALL(vp, VOFFSET(vop_write), &a));
825           vop_post(vp, mp, mpsafe, FST_NO);
826           vop_write_post(&a, error);
827           return error;
828 }
829 
830 const int vop_fallocate_vp_offsets[] = {
831           VOPARG_OFFSETOF(struct vop_fallocate_args,a_vp),
832           VDESC_NO_OFFSET
833 };
834 const struct vnodeop_desc vop_fallocate_desc = {
835           VOP_FALLOCATE_DESCOFFSET,
836           "vop_fallocate",
837           0,
838           vop_fallocate_vp_offsets,
839           VDESC_NO_OFFSET,
840           VDESC_NO_OFFSET,
841           VDESC_NO_OFFSET,
842 };
843 int
VOP_FALLOCATE(struct vnode * vp,off_t pos,off_t len)844 VOP_FALLOCATE(struct vnode *vp,
845     off_t pos,
846     off_t len)
847 {
848           int error;
849           bool mpsafe;
850           struct vop_fallocate_args a;
851           struct mount *mp;
852           a.a_desc = VDESC(vop_fallocate);
853           a.a_vp = vp;
854           a.a_pos = pos;
855           a.a_len = len;
856           assert_vop_locked(vp, "vop_fallocate: vp");
857           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
858           if (error)
859                     return error;
860           error = (VCALL(vp, VOFFSET(vop_fallocate), &a));
861           vop_post(vp, mp, mpsafe, FST_NO);
862           return error;
863 }
864 
865 const int vop_fdiscard_vp_offsets[] = {
866           VOPARG_OFFSETOF(struct vop_fdiscard_args,a_vp),
867           VDESC_NO_OFFSET
868 };
869 const struct vnodeop_desc vop_fdiscard_desc = {
870           VOP_FDISCARD_DESCOFFSET,
871           "vop_fdiscard",
872           0,
873           vop_fdiscard_vp_offsets,
874           VDESC_NO_OFFSET,
875           VDESC_NO_OFFSET,
876           VDESC_NO_OFFSET,
877 };
878 int
VOP_FDISCARD(struct vnode * vp,off_t pos,off_t len)879 VOP_FDISCARD(struct vnode *vp,
880     off_t pos,
881     off_t len)
882 {
883           int error;
884           bool mpsafe;
885           struct vop_fdiscard_args a;
886           struct mount *mp;
887           a.a_desc = VDESC(vop_fdiscard);
888           a.a_vp = vp;
889           a.a_pos = pos;
890           a.a_len = len;
891           assert_vop_locked(vp, "vop_fdiscard: vp");
892           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
893           if (error)
894                     return error;
895           error = (VCALL(vp, VOFFSET(vop_fdiscard), &a));
896           vop_post(vp, mp, mpsafe, FST_NO);
897           return error;
898 }
899 
900 const int vop_ioctl_vp_offsets[] = {
901           VOPARG_OFFSETOF(struct vop_ioctl_args,a_vp),
902           VDESC_NO_OFFSET
903 };
904 const struct vnodeop_desc vop_ioctl_desc = {
905           VOP_IOCTL_DESCOFFSET,
906           "vop_ioctl",
907           0,
908           vop_ioctl_vp_offsets,
909           VDESC_NO_OFFSET,
910           VOPARG_OFFSETOF(struct vop_ioctl_args, a_cred),
911           VDESC_NO_OFFSET,
912 };
913 int
VOP_IOCTL(struct vnode * vp,u_long command,void * data,int fflag,kauth_cred_t cred)914 VOP_IOCTL(struct vnode *vp,
915     u_long command,
916     void *data,
917     int fflag,
918     kauth_cred_t cred)
919 {
920           int error;
921           bool mpsafe;
922           struct vop_ioctl_args a;
923           struct mount *mp;
924           a.a_desc = VDESC(vop_ioctl);
925           a.a_vp = vp;
926           a.a_command = command;
927           a.a_data = data;
928           a.a_fflag = fflag;
929           a.a_cred = cred;
930           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
931           if (error)
932                     return error;
933           error = (VCALL(vp, VOFFSET(vop_ioctl), &a));
934           vop_post(vp, mp, mpsafe, FST_NO);
935           return error;
936 }
937 
938 const int vop_fcntl_vp_offsets[] = {
939           VOPARG_OFFSETOF(struct vop_fcntl_args,a_vp),
940           VDESC_NO_OFFSET
941 };
942 const struct vnodeop_desc vop_fcntl_desc = {
943           VOP_FCNTL_DESCOFFSET,
944           "vop_fcntl",
945           0,
946           vop_fcntl_vp_offsets,
947           VDESC_NO_OFFSET,
948           VOPARG_OFFSETOF(struct vop_fcntl_args, a_cred),
949           VDESC_NO_OFFSET,
950 };
951 int
VOP_FCNTL(struct vnode * vp,u_int command,void * data,int fflag,kauth_cred_t cred)952 VOP_FCNTL(struct vnode *vp,
953     u_int command,
954     void *data,
955     int fflag,
956     kauth_cred_t cred)
957 {
958           int error;
959           bool mpsafe;
960           struct vop_fcntl_args a;
961           struct mount *mp;
962           a.a_desc = VDESC(vop_fcntl);
963           a.a_vp = vp;
964           a.a_command = command;
965           a.a_data = data;
966           a.a_fflag = fflag;
967           a.a_cred = cred;
968           assert_vop_unlocked(vp, "vop_fcntl: vp");
969           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
970           if (error)
971                     return error;
972           error = (VCALL(vp, VOFFSET(vop_fcntl), &a));
973           vop_post(vp, mp, mpsafe, FST_NO);
974           return error;
975 }
976 
977 const int vop_poll_vp_offsets[] = {
978           VOPARG_OFFSETOF(struct vop_poll_args,a_vp),
979           VDESC_NO_OFFSET
980 };
981 const struct vnodeop_desc vop_poll_desc = {
982           VOP_POLL_DESCOFFSET,
983           "vop_poll",
984           0,
985           vop_poll_vp_offsets,
986           VDESC_NO_OFFSET,
987           VDESC_NO_OFFSET,
988           VDESC_NO_OFFSET,
989 };
990 int
VOP_POLL(struct vnode * vp,int events)991 VOP_POLL(struct vnode *vp,
992     int events)
993 {
994           int error;
995           bool mpsafe;
996           struct vop_poll_args a;
997           struct mount *mp;
998           a.a_desc = VDESC(vop_poll);
999           a.a_vp = vp;
1000           a.a_events = events;
1001           assert_vop_unlocked(vp, "vop_poll: vp");
1002           error = vop_pre(vp, &mp, &mpsafe, FST_YES);
1003           if (error)
1004                     return error;
1005           error = (VCALL(vp, VOFFSET(vop_poll), &a));
1006           vop_post(vp, mp, mpsafe, FST_YES);
1007           return error;
1008 }
1009 
1010 const int vop_kqfilter_vp_offsets[] = {
1011           VOPARG_OFFSETOF(struct vop_kqfilter_args,a_vp),
1012           VDESC_NO_OFFSET
1013 };
1014 const struct vnodeop_desc vop_kqfilter_desc = {
1015           VOP_KQFILTER_DESCOFFSET,
1016           "vop_kqfilter",
1017           0,
1018           vop_kqfilter_vp_offsets,
1019           VDESC_NO_OFFSET,
1020           VDESC_NO_OFFSET,
1021           VDESC_NO_OFFSET,
1022 };
1023 int
VOP_KQFILTER(struct vnode * vp,struct knote * kn)1024 VOP_KQFILTER(struct vnode *vp,
1025     struct knote *kn)
1026 {
1027           int error;
1028           bool mpsafe;
1029           struct vop_kqfilter_args a;
1030           struct mount *mp;
1031           a.a_desc = VDESC(vop_kqfilter);
1032           a.a_vp = vp;
1033           a.a_kn = kn;
1034           assert_vop_unlocked(vp, "vop_kqfilter: vp");
1035           error = vop_pre(vp, &mp, &mpsafe, FST_YES);
1036           if (error)
1037                     return error;
1038           error = (VCALL(vp, VOFFSET(vop_kqfilter), &a));
1039           vop_post(vp, mp, mpsafe, FST_YES);
1040           return error;
1041 }
1042 
1043 const int vop_revoke_vp_offsets[] = {
1044           VOPARG_OFFSETOF(struct vop_revoke_args,a_vp),
1045           VDESC_NO_OFFSET
1046 };
1047 const struct vnodeop_desc vop_revoke_desc = {
1048           VOP_REVOKE_DESCOFFSET,
1049           "vop_revoke",
1050           0,
1051           vop_revoke_vp_offsets,
1052           VDESC_NO_OFFSET,
1053           VDESC_NO_OFFSET,
1054           VDESC_NO_OFFSET,
1055 };
1056 int
VOP_REVOKE(struct vnode * vp,int flags)1057 VOP_REVOKE(struct vnode *vp,
1058     int flags)
1059 {
1060           int error;
1061           bool mpsafe;
1062           struct vop_revoke_args a;
1063           struct mount *mp;
1064           a.a_desc = VDESC(vop_revoke);
1065           a.a_vp = vp;
1066           a.a_flags = flags;
1067           assert_vop_unlocked(vp, "vop_revoke: vp");
1068           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
1069           if (error)
1070                     return error;
1071           error = (VCALL(vp, VOFFSET(vop_revoke), &a));
1072           vop_post(vp, mp, mpsafe, FST_NO);
1073           return error;
1074 }
1075 
1076 const int vop_mmap_vp_offsets[] = {
1077           VOPARG_OFFSETOF(struct vop_mmap_args,a_vp),
1078           VDESC_NO_OFFSET
1079 };
1080 const struct vnodeop_desc vop_mmap_desc = {
1081           VOP_MMAP_DESCOFFSET,
1082           "vop_mmap",
1083           0,
1084           vop_mmap_vp_offsets,
1085           VDESC_NO_OFFSET,
1086           VOPARG_OFFSETOF(struct vop_mmap_args, a_cred),
1087           VDESC_NO_OFFSET,
1088 };
1089 int
VOP_MMAP(struct vnode * vp,vm_prot_t prot,kauth_cred_t cred)1090 VOP_MMAP(struct vnode *vp,
1091     vm_prot_t prot,
1092     kauth_cred_t cred)
1093 {
1094           int error;
1095           bool mpsafe;
1096           struct vop_mmap_args a;
1097           struct mount *mp;
1098           a.a_desc = VDESC(vop_mmap);
1099           a.a_vp = vp;
1100           a.a_prot = prot;
1101           a.a_cred = cred;
1102           error = vop_pre(vp, &mp, &mpsafe, FST_YES);
1103           if (error)
1104                     return error;
1105           error = (VCALL(vp, VOFFSET(vop_mmap), &a));
1106           vop_post(vp, mp, mpsafe, FST_YES);
1107           return error;
1108 }
1109 
1110 const int vop_fsync_vp_offsets[] = {
1111           VOPARG_OFFSETOF(struct vop_fsync_args,a_vp),
1112           VDESC_NO_OFFSET
1113 };
1114 const struct vnodeop_desc vop_fsync_desc = {
1115           VOP_FSYNC_DESCOFFSET,
1116           "vop_fsync",
1117           0,
1118           vop_fsync_vp_offsets,
1119           VDESC_NO_OFFSET,
1120           VOPARG_OFFSETOF(struct vop_fsync_args, a_cred),
1121           VDESC_NO_OFFSET,
1122 };
1123 int
VOP_FSYNC(struct vnode * vp,kauth_cred_t cred,int flags,off_t offlo,off_t offhi)1124 VOP_FSYNC(struct vnode *vp,
1125     kauth_cred_t cred,
1126     int flags,
1127     off_t offlo,
1128     off_t offhi)
1129 {
1130           int error;
1131           bool mpsafe;
1132           struct vop_fsync_args a;
1133           struct mount *mp;
1134           a.a_desc = VDESC(vop_fsync);
1135           a.a_vp = vp;
1136           a.a_cred = cred;
1137           a.a_flags = flags;
1138           a.a_offlo = offlo;
1139           a.a_offhi = offhi;
1140           assert_vop_locked(vp, "vop_fsync: vp");
1141           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
1142           if (error)
1143                     return error;
1144           error = (VCALL(vp, VOFFSET(vop_fsync), &a));
1145           vop_post(vp, mp, mpsafe, FST_NO);
1146           return error;
1147 }
1148 
1149 const int vop_seek_vp_offsets[] = {
1150           VOPARG_OFFSETOF(struct vop_seek_args,a_vp),
1151           VDESC_NO_OFFSET
1152 };
1153 const struct vnodeop_desc vop_seek_desc = {
1154           VOP_SEEK_DESCOFFSET,
1155           "vop_seek",
1156           0,
1157           vop_seek_vp_offsets,
1158           VDESC_NO_OFFSET,
1159           VOPARG_OFFSETOF(struct vop_seek_args, a_cred),
1160           VDESC_NO_OFFSET,
1161 };
1162 int
VOP_SEEK(struct vnode * vp,off_t oldoff,off_t newoff,kauth_cred_t cred)1163 VOP_SEEK(struct vnode *vp,
1164     off_t oldoff,
1165     off_t newoff,
1166     kauth_cred_t cred)
1167 {
1168           int error;
1169           bool mpsafe;
1170           struct vop_seek_args a;
1171           struct mount *mp;
1172           a.a_desc = VDESC(vop_seek);
1173           a.a_vp = vp;
1174           a.a_oldoff = oldoff;
1175           a.a_newoff = newoff;
1176           a.a_cred = cred;
1177           error = vop_pre(vp, &mp, &mpsafe, FST_YES);
1178           if (error)
1179                     return error;
1180           error = (VCALL(vp, VOFFSET(vop_seek), &a));
1181           vop_post(vp, mp, mpsafe, FST_YES);
1182           return error;
1183 }
1184 
1185 const int vop_remove_vp_offsets[] = {
1186           VOPARG_OFFSETOF(struct vop_remove_v3_args,a_dvp),
1187           VOPARG_OFFSETOF(struct vop_remove_v3_args,a_vp),
1188           VDESC_NO_OFFSET
1189 };
1190 const struct vnodeop_desc vop_remove_desc = {
1191           VOP_REMOVE_DESCOFFSET,
1192           "vop_remove",
1193           0 | VDESC_VP1_WILLPUT,
1194           vop_remove_vp_offsets,
1195           VDESC_NO_OFFSET,
1196           VDESC_NO_OFFSET,
1197           VOPARG_OFFSETOF(struct vop_remove_v3_args, a_cnp),
1198 };
1199 int
VOP_REMOVE(struct vnode * dvp,struct vnode * vp,struct componentname * cnp)1200 VOP_REMOVE(struct vnode *dvp,
1201     struct vnode *vp,
1202     struct componentname *cnp)
1203 {
1204           int error;
1205           bool mpsafe;
1206           struct vop_remove_v3_args a;
1207           struct mount *mp;
1208           a.a_desc = VDESC(vop_remove);
1209           a.a_dvp = dvp;
1210           a.a_vp = vp;
1211           a.a_cnp = cnp;
1212           assert_vop_elocked(dvp, "vop_remove: dvp");
1213           assert_vop_locked(vp, "vop_remove: vp");
1214           vop_remove_pre(&a);
1215           error = vop_pre(dvp, &mp, &mpsafe, FST_NO);
1216           if (error)
1217                     return error;
1218           error = (VCALL(dvp, VOFFSET(vop_remove), &a));
1219           vop_post(dvp, mp, mpsafe, FST_NO);
1220           vop_remove_post(&a, error);
1221           return error;
1222 }
1223 
1224 const int vop_link_vp_offsets[] = {
1225           VOPARG_OFFSETOF(struct vop_link_v2_args,a_dvp),
1226           VOPARG_OFFSETOF(struct vop_link_v2_args,a_vp),
1227           VDESC_NO_OFFSET
1228 };
1229 const struct vnodeop_desc vop_link_desc = {
1230           VOP_LINK_DESCOFFSET,
1231           "vop_link",
1232           0,
1233           vop_link_vp_offsets,
1234           VDESC_NO_OFFSET,
1235           VDESC_NO_OFFSET,
1236           VOPARG_OFFSETOF(struct vop_link_v2_args, a_cnp),
1237 };
1238 int
VOP_LINK(struct vnode * dvp,struct vnode * vp,struct componentname * cnp)1239 VOP_LINK(struct vnode *dvp,
1240     struct vnode *vp,
1241     struct componentname *cnp)
1242 {
1243           int error;
1244           bool mpsafe;
1245           struct vop_link_v2_args a;
1246           struct mount *mp;
1247           a.a_desc = VDESC(vop_link);
1248           a.a_dvp = dvp;
1249           a.a_vp = vp;
1250           a.a_cnp = cnp;
1251           assert_vop_elocked(dvp, "vop_link: dvp");
1252           assert_vop_unlocked(vp, "vop_link: vp");
1253           error = vop_pre(dvp, &mp, &mpsafe, FST_NO);
1254           if (error)
1255                     return error;
1256           error = (VCALL(dvp, VOFFSET(vop_link), &a));
1257           vop_post(dvp, mp, mpsafe, FST_NO);
1258           vop_link_post(&a, error);
1259           return error;
1260 }
1261 
1262 const int vop_rename_vp_offsets[] = {
1263           VOPARG_OFFSETOF(struct vop_rename_args,a_fdvp),
1264           VOPARG_OFFSETOF(struct vop_rename_args,a_fvp),
1265           VOPARG_OFFSETOF(struct vop_rename_args,a_tdvp),
1266           VOPARG_OFFSETOF(struct vop_rename_args,a_tvp),
1267           VDESC_NO_OFFSET
1268 };
1269 const struct vnodeop_desc vop_rename_desc = {
1270           VOP_RENAME_DESCOFFSET,
1271           "vop_rename",
1272           0 | VDESC_VP0_WILLRELE | VDESC_VP1_WILLRELE | VDESC_VP2_WILLPUT | VDESC_VP3_WILLPUT,
1273           vop_rename_vp_offsets,
1274           VDESC_NO_OFFSET,
1275           VDESC_NO_OFFSET,
1276           VOPARG_OFFSETOF(struct vop_rename_args, a_fcnp),
1277 };
1278 int
VOP_RENAME(struct vnode * fdvp,struct vnode * fvp,struct componentname * fcnp,struct vnode * tdvp,struct vnode * tvp,struct componentname * tcnp)1279 VOP_RENAME(struct vnode *fdvp,
1280     struct vnode *fvp,
1281     struct componentname *fcnp,
1282     struct vnode *tdvp,
1283     struct vnode *tvp,
1284     struct componentname *tcnp)
1285 {
1286           int error;
1287           bool mpsafe;
1288           struct vop_rename_args a;
1289           struct mount *mp;
1290           a.a_desc = VDESC(vop_rename);
1291           a.a_fdvp = fdvp;
1292           a.a_fvp = fvp;
1293           a.a_fcnp = fcnp;
1294           a.a_tdvp = tdvp;
1295           a.a_tvp = tvp;
1296           a.a_tcnp = tcnp;
1297           assert_vop_locked(tdvp, "vop_rename: tdvp");
1298           error = vop_pre(fdvp, &mp, &mpsafe, FST_YES);
1299           if (error)
1300                     return error;
1301           error = (VCALL(fdvp, VOFFSET(vop_rename), &a));
1302           vop_post(fdvp, mp, mpsafe, FST_YES);
1303           return error;
1304 }
1305 
1306 const int vop_mkdir_vp_offsets[] = {
1307           VOPARG_OFFSETOF(struct vop_mkdir_v3_args,a_dvp),
1308           VDESC_NO_OFFSET
1309 };
1310 const struct vnodeop_desc vop_mkdir_desc = {
1311           VOP_MKDIR_DESCOFFSET,
1312           "vop_mkdir",
1313           0,
1314           vop_mkdir_vp_offsets,
1315           VOPARG_OFFSETOF(struct vop_mkdir_v3_args, a_vpp),
1316           VDESC_NO_OFFSET,
1317           VOPARG_OFFSETOF(struct vop_mkdir_v3_args, a_cnp),
1318 };
1319 int
VOP_MKDIR(struct vnode * dvp,struct vnode ** vpp,struct componentname * cnp,struct vattr * vap)1320 VOP_MKDIR(struct vnode *dvp,
1321     struct vnode **vpp,
1322     struct componentname *cnp,
1323     struct vattr *vap)
1324 {
1325           int error;
1326           bool mpsafe;
1327           struct vop_mkdir_v3_args a;
1328           struct mount *mp;
1329           a.a_desc = VDESC(vop_mkdir);
1330           a.a_dvp = dvp;
1331           a.a_vpp = vpp;
1332           a.a_cnp = cnp;
1333           a.a_vap = vap;
1334           assert_vop_elocked(dvp, "vop_mkdir: dvp");
1335           error = vop_pre(dvp, &mp, &mpsafe, FST_NO);
1336           if (error)
1337                     return error;
1338           error = (VCALL(dvp, VOFFSET(vop_mkdir), &a));
1339           vop_post(dvp, mp, mpsafe, FST_NO);
1340           vop_mkdir_post(&a, error);
1341 #ifdef DIAGNOSTIC
1342           if (error == 0)
1343                     KASSERT((*vpp)->v_size != VSIZENOTSET
1344                         && (*vpp)->v_writesize != VSIZENOTSET);
1345 #endif /* DIAGNOSTIC */
1346           return error;
1347 }
1348 
1349 const int vop_rmdir_vp_offsets[] = {
1350           VOPARG_OFFSETOF(struct vop_rmdir_v2_args,a_dvp),
1351           VOPARG_OFFSETOF(struct vop_rmdir_v2_args,a_vp),
1352           VDESC_NO_OFFSET
1353 };
1354 const struct vnodeop_desc vop_rmdir_desc = {
1355           VOP_RMDIR_DESCOFFSET,
1356           "vop_rmdir",
1357           0 | VDESC_VP1_WILLPUT,
1358           vop_rmdir_vp_offsets,
1359           VDESC_NO_OFFSET,
1360           VDESC_NO_OFFSET,
1361           VOPARG_OFFSETOF(struct vop_rmdir_v2_args, a_cnp),
1362 };
1363 int
VOP_RMDIR(struct vnode * dvp,struct vnode * vp,struct componentname * cnp)1364 VOP_RMDIR(struct vnode *dvp,
1365     struct vnode *vp,
1366     struct componentname *cnp)
1367 {
1368           int error;
1369           bool mpsafe;
1370           struct vop_rmdir_v2_args a;
1371           struct mount *mp;
1372           a.a_desc = VDESC(vop_rmdir);
1373           a.a_dvp = dvp;
1374           a.a_vp = vp;
1375           a.a_cnp = cnp;
1376           assert_vop_elocked(dvp, "vop_rmdir: dvp");
1377           assert_vop_elocked(vp, "vop_rmdir: vp");
1378           vop_rmdir_pre(&a);
1379           error = vop_pre(dvp, &mp, &mpsafe, FST_NO);
1380           if (error)
1381                     return error;
1382           error = (VCALL(dvp, VOFFSET(vop_rmdir), &a));
1383           vop_post(dvp, mp, mpsafe, FST_NO);
1384           vop_rmdir_post(&a, error);
1385           return error;
1386 }
1387 
1388 const int vop_symlink_vp_offsets[] = {
1389           VOPARG_OFFSETOF(struct vop_symlink_v3_args,a_dvp),
1390           VDESC_NO_OFFSET
1391 };
1392 const struct vnodeop_desc vop_symlink_desc = {
1393           VOP_SYMLINK_DESCOFFSET,
1394           "vop_symlink",
1395           0,
1396           vop_symlink_vp_offsets,
1397           VOPARG_OFFSETOF(struct vop_symlink_v3_args, a_vpp),
1398           VDESC_NO_OFFSET,
1399           VOPARG_OFFSETOF(struct vop_symlink_v3_args, a_cnp),
1400 };
1401 int
VOP_SYMLINK(struct vnode * dvp,struct vnode ** vpp,struct componentname * cnp,struct vattr * vap,char * target)1402 VOP_SYMLINK(struct vnode *dvp,
1403     struct vnode **vpp,
1404     struct componentname *cnp,
1405     struct vattr *vap,
1406     char *target)
1407 {
1408           int error;
1409           bool mpsafe;
1410           struct vop_symlink_v3_args a;
1411           struct mount *mp;
1412           a.a_desc = VDESC(vop_symlink);
1413           a.a_dvp = dvp;
1414           a.a_vpp = vpp;
1415           a.a_cnp = cnp;
1416           a.a_vap = vap;
1417           a.a_target = target;
1418           assert_vop_elocked(dvp, "vop_symlink: dvp");
1419           error = vop_pre(dvp, &mp, &mpsafe, FST_NO);
1420           if (error)
1421                     return error;
1422           error = (VCALL(dvp, VOFFSET(vop_symlink), &a));
1423           vop_post(dvp, mp, mpsafe, FST_NO);
1424           vop_symlink_post(&a, error);
1425 #ifdef DIAGNOSTIC
1426           if (error == 0)
1427                     KASSERT((*vpp)->v_size != VSIZENOTSET
1428                         && (*vpp)->v_writesize != VSIZENOTSET);
1429 #endif /* DIAGNOSTIC */
1430           return error;
1431 }
1432 
1433 const int vop_readdir_vp_offsets[] = {
1434           VOPARG_OFFSETOF(struct vop_readdir_args,a_vp),
1435           VDESC_NO_OFFSET
1436 };
1437 const struct vnodeop_desc vop_readdir_desc = {
1438           VOP_READDIR_DESCOFFSET,
1439           "vop_readdir",
1440           0,
1441           vop_readdir_vp_offsets,
1442           VDESC_NO_OFFSET,
1443           VOPARG_OFFSETOF(struct vop_readdir_args, a_cred),
1444           VDESC_NO_OFFSET,
1445 };
1446 int
VOP_READDIR(struct vnode * vp,struct uio * uio,kauth_cred_t cred,int * eofflag,off_t ** cookies,int * ncookies)1447 VOP_READDIR(struct vnode *vp,
1448     struct uio *uio,
1449     kauth_cred_t cred,
1450     int *eofflag,
1451     off_t **cookies,
1452     int *ncookies)
1453 {
1454           int error;
1455           bool mpsafe;
1456           struct vop_readdir_args a;
1457           struct mount *mp;
1458           a.a_desc = VDESC(vop_readdir);
1459           a.a_vp = vp;
1460           a.a_uio = uio;
1461           a.a_cred = cred;
1462           a.a_eofflag = eofflag;
1463           a.a_cookies = cookies;
1464           a.a_ncookies = ncookies;
1465           assert_vop_locked(vp, "vop_readdir: vp");
1466           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
1467           if (error)
1468                     return error;
1469           error = (VCALL(vp, VOFFSET(vop_readdir), &a));
1470           vop_post(vp, mp, mpsafe, FST_NO);
1471           return error;
1472 }
1473 
1474 const int vop_readlink_vp_offsets[] = {
1475           VOPARG_OFFSETOF(struct vop_readlink_args,a_vp),
1476           VDESC_NO_OFFSET
1477 };
1478 const struct vnodeop_desc vop_readlink_desc = {
1479           VOP_READLINK_DESCOFFSET,
1480           "vop_readlink",
1481           0,
1482           vop_readlink_vp_offsets,
1483           VDESC_NO_OFFSET,
1484           VOPARG_OFFSETOF(struct vop_readlink_args, a_cred),
1485           VDESC_NO_OFFSET,
1486 };
1487 int
VOP_READLINK(struct vnode * vp,struct uio * uio,kauth_cred_t cred)1488 VOP_READLINK(struct vnode *vp,
1489     struct uio *uio,
1490     kauth_cred_t cred)
1491 {
1492           int error;
1493           bool mpsafe;
1494           struct vop_readlink_args a;
1495           struct mount *mp;
1496           a.a_desc = VDESC(vop_readlink);
1497           a.a_vp = vp;
1498           a.a_uio = uio;
1499           a.a_cred = cred;
1500           assert_vop_locked(vp, "vop_readlink: vp");
1501           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
1502           if (error)
1503                     return error;
1504           error = (VCALL(vp, VOFFSET(vop_readlink), &a));
1505           vop_post(vp, mp, mpsafe, FST_NO);
1506           return error;
1507 }
1508 
1509 const int vop_abortop_vp_offsets[] = {
1510           VOPARG_OFFSETOF(struct vop_abortop_args,a_dvp),
1511           VDESC_NO_OFFSET
1512 };
1513 const struct vnodeop_desc vop_abortop_desc = {
1514           VOP_ABORTOP_DESCOFFSET,
1515           "vop_abortop",
1516           0,
1517           vop_abortop_vp_offsets,
1518           VDESC_NO_OFFSET,
1519           VDESC_NO_OFFSET,
1520           VOPARG_OFFSETOF(struct vop_abortop_args, a_cnp),
1521 };
1522 int
VOP_ABORTOP(struct vnode * dvp,struct componentname * cnp)1523 VOP_ABORTOP(struct vnode *dvp,
1524     struct componentname *cnp)
1525 {
1526           int error;
1527           bool mpsafe;
1528           struct vop_abortop_args a;
1529           struct mount *mp;
1530           a.a_desc = VDESC(vop_abortop);
1531           a.a_dvp = dvp;
1532           a.a_cnp = cnp;
1533           error = vop_pre(dvp, &mp, &mpsafe, FST_YES);
1534           if (error)
1535                     return error;
1536           error = (VCALL(dvp, VOFFSET(vop_abortop), &a));
1537           vop_post(dvp, mp, mpsafe, FST_YES);
1538           return error;
1539 }
1540 
1541 const int vop_inactive_vp_offsets[] = {
1542           VOPARG_OFFSETOF(struct vop_inactive_v2_args,a_vp),
1543           VDESC_NO_OFFSET
1544 };
1545 const struct vnodeop_desc vop_inactive_desc = {
1546           VOP_INACTIVE_DESCOFFSET,
1547           "vop_inactive",
1548           0,
1549           vop_inactive_vp_offsets,
1550           VDESC_NO_OFFSET,
1551           VDESC_NO_OFFSET,
1552           VDESC_NO_OFFSET,
1553 };
1554 int
VOP_INACTIVE(struct vnode * vp,bool * recycle)1555 VOP_INACTIVE(struct vnode *vp,
1556     bool *recycle)
1557 {
1558           int error;
1559           bool mpsafe;
1560           struct vop_inactive_v2_args a;
1561           struct mount *mp;
1562           a.a_desc = VDESC(vop_inactive);
1563           a.a_vp = vp;
1564           a.a_recycle = recycle;
1565           assert_vop_elocked(vp, "vop_inactive: vp");
1566           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
1567           if (error)
1568                     return error;
1569           error = (VCALL(vp, VOFFSET(vop_inactive), &a));
1570           vop_post(vp, mp, mpsafe, FST_NO);
1571           return error;
1572 }
1573 
1574 const int vop_reclaim_vp_offsets[] = {
1575           VOPARG_OFFSETOF(struct vop_reclaim_v2_args,a_vp),
1576           VDESC_NO_OFFSET
1577 };
1578 const struct vnodeop_desc vop_reclaim_desc = {
1579           VOP_RECLAIM_DESCOFFSET,
1580           "vop_reclaim",
1581           0,
1582           vop_reclaim_vp_offsets,
1583           VDESC_NO_OFFSET,
1584           VDESC_NO_OFFSET,
1585           VDESC_NO_OFFSET,
1586 };
1587 int
VOP_RECLAIM(struct vnode * vp)1588 VOP_RECLAIM(struct vnode *vp)
1589 {
1590           int error;
1591           bool mpsafe;
1592           struct vop_reclaim_v2_args a;
1593           struct mount *mp;
1594           a.a_desc = VDESC(vop_reclaim);
1595           a.a_vp = vp;
1596           assert_vop_elocked(vp, "vop_reclaim: vp");
1597           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
1598           if (error)
1599                     return error;
1600           error = (VCALL(vp, VOFFSET(vop_reclaim), &a));
1601           vop_post(vp, mp, mpsafe, FST_NO);
1602           return error;
1603 }
1604 
1605 const int vop_lock_vp_offsets[] = {
1606           VOPARG_OFFSETOF(struct vop_lock_args,a_vp),
1607           VDESC_NO_OFFSET
1608 };
1609 const struct vnodeop_desc vop_lock_desc = {
1610           VOP_LOCK_DESCOFFSET,
1611           "vop_lock",
1612           0,
1613           vop_lock_vp_offsets,
1614           VDESC_NO_OFFSET,
1615           VDESC_NO_OFFSET,
1616           VDESC_NO_OFFSET,
1617 };
1618 int
VOP_LOCK(struct vnode * vp,int flags)1619 VOP_LOCK(struct vnode *vp,
1620     int flags)
1621 {
1622           int error;
1623           bool mpsafe;
1624           struct vop_lock_args a;
1625           struct mount *mp;
1626           a.a_desc = VDESC(vop_lock);
1627           a.a_vp = vp;
1628           a.a_flags = flags;
1629           error = vop_pre(vp, &mp, &mpsafe, (!(flags & (LK_SHARED|LK_EXCLUSIVE)) ? FST_NO : (flags & LK_NOWAIT ? FST_TRY : FST_YES)));
1630           if (error)
1631                     return error;
1632           error = (VCALL(vp, VOFFSET(vop_lock), &a));
1633           vop_post(vp, mp, mpsafe, (flags & (LK_UPGRADE|LK_DOWNGRADE) ? FST_NO : (error ? FST_YES : FST_NO)));
1634           return error;
1635 }
1636 
1637 const int vop_unlock_vp_offsets[] = {
1638           VOPARG_OFFSETOF(struct vop_unlock_args,a_vp),
1639           VDESC_NO_OFFSET
1640 };
1641 const struct vnodeop_desc vop_unlock_desc = {
1642           VOP_UNLOCK_DESCOFFSET,
1643           "vop_unlock",
1644           0,
1645           vop_unlock_vp_offsets,
1646           VDESC_NO_OFFSET,
1647           VDESC_NO_OFFSET,
1648           VDESC_NO_OFFSET,
1649 };
1650 int
VOP_UNLOCK(struct vnode * vp)1651 VOP_UNLOCK(struct vnode *vp)
1652 {
1653           int error;
1654           bool mpsafe;
1655           struct vop_unlock_args a;
1656           struct mount *mp;
1657           a.a_desc = VDESC(vop_unlock);
1658           a.a_vp = vp;
1659           assert_vop_locked(vp, "vop_unlock: vp");
1660           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
1661           if (error)
1662                     return error;
1663           error = (VCALL(vp, VOFFSET(vop_unlock), &a));
1664           vop_post(vp, mp, mpsafe, FST_YES);
1665           return error;
1666 }
1667 
1668 const int vop_bmap_vp_offsets[] = {
1669           VOPARG_OFFSETOF(struct vop_bmap_args,a_vp),
1670           VDESC_NO_OFFSET
1671 };
1672 const struct vnodeop_desc vop_bmap_desc = {
1673           VOP_BMAP_DESCOFFSET,
1674           "vop_bmap",
1675           0,
1676           vop_bmap_vp_offsets,
1677           VOPARG_OFFSETOF(struct vop_bmap_args, a_vpp),
1678           VDESC_NO_OFFSET,
1679           VDESC_NO_OFFSET,
1680 };
1681 int
VOP_BMAP(struct vnode * vp,daddr_t bn,struct vnode ** vpp,daddr_t * bnp,int * runp)1682 VOP_BMAP(struct vnode *vp,
1683     daddr_t bn,
1684     struct vnode **vpp,
1685     daddr_t *bnp,
1686     int *runp)
1687 {
1688           int error;
1689           bool mpsafe;
1690           struct vop_bmap_args a;
1691           struct mount *mp;
1692           a.a_desc = VDESC(vop_bmap);
1693           a.a_vp = vp;
1694           a.a_bn = bn;
1695           a.a_vpp = vpp;
1696           a.a_bnp = bnp;
1697           a.a_runp = runp;
1698           error = vop_pre(vp, &mp, &mpsafe, FST_YES);
1699           if (error)
1700                     return error;
1701           error = (VCALL(vp, VOFFSET(vop_bmap), &a));
1702           vop_post(vp, mp, mpsafe, FST_YES);
1703           return error;
1704 }
1705 
1706 const int vop_strategy_vp_offsets[] = {
1707           VOPARG_OFFSETOF(struct vop_strategy_args,a_vp),
1708           VDESC_NO_OFFSET
1709 };
1710 const struct vnodeop_desc vop_strategy_desc = {
1711           VOP_STRATEGY_DESCOFFSET,
1712           "vop_strategy",
1713           0,
1714           vop_strategy_vp_offsets,
1715           VDESC_NO_OFFSET,
1716           VDESC_NO_OFFSET,
1717           VDESC_NO_OFFSET,
1718 };
1719 int
VOP_STRATEGY(struct vnode * vp,struct buf * bp)1720 VOP_STRATEGY(struct vnode *vp,
1721     struct buf *bp)
1722 {
1723           int error;
1724           bool mpsafe;
1725           struct vop_strategy_args a;
1726           struct mount *mp;
1727           a.a_desc = VDESC(vop_strategy);
1728           a.a_vp = vp;
1729           a.a_bp = bp;
1730           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
1731           if (error)
1732                     return error;
1733           error = (VCALL(vp, VOFFSET(vop_strategy), &a));
1734           vop_post(vp, mp, mpsafe, FST_NO);
1735           return error;
1736 }
1737 
1738 const int vop_print_vp_offsets[] = {
1739           VOPARG_OFFSETOF(struct vop_print_args,a_vp),
1740           VDESC_NO_OFFSET
1741 };
1742 const struct vnodeop_desc vop_print_desc = {
1743           VOP_PRINT_DESCOFFSET,
1744           "vop_print",
1745           0,
1746           vop_print_vp_offsets,
1747           VDESC_NO_OFFSET,
1748           VDESC_NO_OFFSET,
1749           VDESC_NO_OFFSET,
1750 };
1751 int
VOP_PRINT(struct vnode * vp)1752 VOP_PRINT(struct vnode *vp)
1753 {
1754           int error;
1755           bool mpsafe;
1756           struct vop_print_args a;
1757           struct mount *mp;
1758           a.a_desc = VDESC(vop_print);
1759           a.a_vp = vp;
1760           error = vop_pre(vp, &mp, &mpsafe, FST_YES);
1761           if (error)
1762                     return error;
1763           error = (VCALL(vp, VOFFSET(vop_print), &a));
1764           vop_post(vp, mp, mpsafe, FST_YES);
1765           return error;
1766 }
1767 
1768 const int vop_islocked_vp_offsets[] = {
1769           VOPARG_OFFSETOF(struct vop_islocked_args,a_vp),
1770           VDESC_NO_OFFSET
1771 };
1772 const struct vnodeop_desc vop_islocked_desc = {
1773           VOP_ISLOCKED_DESCOFFSET,
1774           "vop_islocked",
1775           0,
1776           vop_islocked_vp_offsets,
1777           VDESC_NO_OFFSET,
1778           VDESC_NO_OFFSET,
1779           VDESC_NO_OFFSET,
1780 };
1781 int
VOP_ISLOCKED(struct vnode * vp)1782 VOP_ISLOCKED(struct vnode *vp)
1783 {
1784           int error;
1785           bool mpsafe;
1786           struct vop_islocked_args a;
1787           struct mount *mp;
1788           a.a_desc = VDESC(vop_islocked);
1789           a.a_vp = vp;
1790           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
1791           if (error)
1792                     return error;
1793           error = (VCALL(vp, VOFFSET(vop_islocked), &a));
1794           vop_post(vp, mp, mpsafe, FST_NO);
1795           return error;
1796 }
1797 
1798 const int vop_pathconf_vp_offsets[] = {
1799           VOPARG_OFFSETOF(struct vop_pathconf_args,a_vp),
1800           VDESC_NO_OFFSET
1801 };
1802 const struct vnodeop_desc vop_pathconf_desc = {
1803           VOP_PATHCONF_DESCOFFSET,
1804           "vop_pathconf",
1805           0,
1806           vop_pathconf_vp_offsets,
1807           VDESC_NO_OFFSET,
1808           VDESC_NO_OFFSET,
1809           VDESC_NO_OFFSET,
1810 };
1811 int
VOP_PATHCONF(struct vnode * vp,int name,register_t * retval)1812 VOP_PATHCONF(struct vnode *vp,
1813     int name,
1814     register_t *retval)
1815 {
1816           int error;
1817           bool mpsafe;
1818           struct vop_pathconf_args a;
1819           struct mount *mp;
1820           a.a_desc = VDESC(vop_pathconf);
1821           a.a_vp = vp;
1822           a.a_name = name;
1823           a.a_retval = retval;
1824           assert_vop_locked(vp, "vop_pathconf: vp");
1825           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
1826           if (error)
1827                     return error;
1828           error = (VCALL(vp, VOFFSET(vop_pathconf), &a));
1829           vop_post(vp, mp, mpsafe, FST_NO);
1830           return error;
1831 }
1832 
1833 const int vop_advlock_vp_offsets[] = {
1834           VOPARG_OFFSETOF(struct vop_advlock_args,a_vp),
1835           VDESC_NO_OFFSET
1836 };
1837 const struct vnodeop_desc vop_advlock_desc = {
1838           VOP_ADVLOCK_DESCOFFSET,
1839           "vop_advlock",
1840           0,
1841           vop_advlock_vp_offsets,
1842           VDESC_NO_OFFSET,
1843           VDESC_NO_OFFSET,
1844           VDESC_NO_OFFSET,
1845 };
1846 int
VOP_ADVLOCK(struct vnode * vp,void * id,int op,struct flock * fl,int flags)1847 VOP_ADVLOCK(struct vnode *vp,
1848     void *id,
1849     int op,
1850     struct flock *fl,
1851     int flags)
1852 {
1853           int error;
1854           bool mpsafe;
1855           struct vop_advlock_args a;
1856           struct mount *mp;
1857           a.a_desc = VDESC(vop_advlock);
1858           a.a_vp = vp;
1859           a.a_id = id;
1860           a.a_op = op;
1861           a.a_fl = fl;
1862           a.a_flags = flags;
1863           assert_vop_unlocked(vp, "vop_advlock: vp");
1864           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
1865           if (error)
1866                     return error;
1867           error = (VCALL(vp, VOFFSET(vop_advlock), &a));
1868           vop_post(vp, mp, mpsafe, FST_NO);
1869           return error;
1870 }
1871 
1872 const int vop_whiteout_vp_offsets[] = {
1873           VOPARG_OFFSETOF(struct vop_whiteout_args,a_dvp),
1874           VDESC_NO_OFFSET
1875 };
1876 const struct vnodeop_desc vop_whiteout_desc = {
1877           VOP_WHITEOUT_DESCOFFSET,
1878           "vop_whiteout",
1879           0,
1880           vop_whiteout_vp_offsets,
1881           VDESC_NO_OFFSET,
1882           VDESC_NO_OFFSET,
1883           VOPARG_OFFSETOF(struct vop_whiteout_args, a_cnp),
1884 };
1885 int
VOP_WHITEOUT(struct vnode * dvp,struct componentname * cnp,int flags)1886 VOP_WHITEOUT(struct vnode *dvp,
1887     struct componentname *cnp,
1888     int flags)
1889 {
1890           int error;
1891           bool mpsafe;
1892           struct vop_whiteout_args a;
1893           struct mount *mp;
1894           a.a_desc = VDESC(vop_whiteout);
1895           a.a_dvp = dvp;
1896           a.a_cnp = cnp;
1897           a.a_flags = flags;
1898           assert_vop_elocked(dvp, "vop_whiteout: dvp");
1899           error = vop_pre(dvp, &mp, &mpsafe, FST_NO);
1900           if (error)
1901                     return error;
1902           error = (VCALL(dvp, VOFFSET(vop_whiteout), &a));
1903           vop_post(dvp, mp, mpsafe, FST_NO);
1904           return error;
1905 }
1906 
1907 const int vop_getpages_vp_offsets[] = {
1908           VOPARG_OFFSETOF(struct vop_getpages_args,a_vp),
1909           VDESC_NO_OFFSET
1910 };
1911 const struct vnodeop_desc vop_getpages_desc = {
1912           VOP_GETPAGES_DESCOFFSET,
1913           "vop_getpages",
1914           0,
1915           vop_getpages_vp_offsets,
1916           VDESC_NO_OFFSET,
1917           VDESC_NO_OFFSET,
1918           VDESC_NO_OFFSET,
1919 };
1920 int
VOP_GETPAGES(struct vnode * vp,voff_t offset,struct vm_page ** m,int * count,int centeridx,vm_prot_t access_type,int advice,int flags)1921 VOP_GETPAGES(struct vnode *vp,
1922     voff_t offset,
1923     struct vm_page **m,
1924     int *count,
1925     int centeridx,
1926     vm_prot_t access_type,
1927     int advice,
1928     int flags)
1929 {
1930           int error;
1931           bool mpsafe;
1932           struct vop_getpages_args a;
1933           struct mount *mp;
1934           a.a_desc = VDESC(vop_getpages);
1935           a.a_vp = vp;
1936           a.a_offset = offset;
1937           a.a_m = m;
1938           a.a_count = count;
1939           a.a_centeridx = centeridx;
1940           a.a_access_type = access_type;
1941           a.a_advice = advice;
1942           a.a_flags = flags;
1943           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
1944           if (error)
1945                     return error;
1946           error = (VCALL(vp, VOFFSET(vop_getpages), &a));
1947           vop_post(vp, mp, mpsafe, FST_NO);
1948           return error;
1949 }
1950 
1951 const int vop_putpages_vp_offsets[] = {
1952           VOPARG_OFFSETOF(struct vop_putpages_args,a_vp),
1953           VDESC_NO_OFFSET
1954 };
1955 const struct vnodeop_desc vop_putpages_desc = {
1956           VOP_PUTPAGES_DESCOFFSET,
1957           "vop_putpages",
1958           0,
1959           vop_putpages_vp_offsets,
1960           VDESC_NO_OFFSET,
1961           VDESC_NO_OFFSET,
1962           VDESC_NO_OFFSET,
1963 };
1964 int
VOP_PUTPAGES(struct vnode * vp,voff_t offlo,voff_t offhi,int flags)1965 VOP_PUTPAGES(struct vnode *vp,
1966     voff_t offlo,
1967     voff_t offhi,
1968     int flags)
1969 {
1970           int error;
1971           bool mpsafe;
1972           struct vop_putpages_args a;
1973           struct mount *mp;
1974           a.a_desc = VDESC(vop_putpages);
1975           a.a_vp = vp;
1976           a.a_offlo = offlo;
1977           a.a_offhi = offhi;
1978           a.a_flags = flags;
1979           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
1980           if (error)
1981                     return error;
1982           error = (VCALL(vp, VOFFSET(vop_putpages), &a));
1983           vop_post(vp, mp, mpsafe, FST_NO);
1984           return error;
1985 }
1986 
1987 const int vop_getacl_vp_offsets[] = {
1988           VOPARG_OFFSETOF(struct vop_getacl_args,a_vp),
1989           VDESC_NO_OFFSET
1990 };
1991 const struct vnodeop_desc vop_getacl_desc = {
1992           VOP_GETACL_DESCOFFSET,
1993           "vop_getacl",
1994           0,
1995           vop_getacl_vp_offsets,
1996           VDESC_NO_OFFSET,
1997           VOPARG_OFFSETOF(struct vop_getacl_args, a_cred),
1998           VDESC_NO_OFFSET,
1999 };
2000 int
VOP_GETACL(struct vnode * vp,acl_type_t type,struct acl * aclp,kauth_cred_t cred)2001 VOP_GETACL(struct vnode *vp,
2002     acl_type_t type,
2003     struct acl *aclp,
2004     kauth_cred_t cred)
2005 {
2006           int error;
2007           bool mpsafe;
2008           struct vop_getacl_args a;
2009           struct mount *mp;
2010           a.a_desc = VDESC(vop_getacl);
2011           a.a_vp = vp;
2012           a.a_type = type;
2013           a.a_aclp = aclp;
2014           a.a_cred = cred;
2015           error = vop_pre(vp, &mp, &mpsafe, FST_YES);
2016           if (error)
2017                     return error;
2018           error = (VCALL(vp, VOFFSET(vop_getacl), &a));
2019           vop_post(vp, mp, mpsafe, FST_YES);
2020           return error;
2021 }
2022 
2023 const int vop_setacl_vp_offsets[] = {
2024           VOPARG_OFFSETOF(struct vop_setacl_args,a_vp),
2025           VDESC_NO_OFFSET
2026 };
2027 const struct vnodeop_desc vop_setacl_desc = {
2028           VOP_SETACL_DESCOFFSET,
2029           "vop_setacl",
2030           0,
2031           vop_setacl_vp_offsets,
2032           VDESC_NO_OFFSET,
2033           VOPARG_OFFSETOF(struct vop_setacl_args, a_cred),
2034           VDESC_NO_OFFSET,
2035 };
2036 int
VOP_SETACL(struct vnode * vp,acl_type_t type,struct acl * aclp,kauth_cred_t cred)2037 VOP_SETACL(struct vnode *vp,
2038     acl_type_t type,
2039     struct acl *aclp,
2040     kauth_cred_t cred)
2041 {
2042           int error;
2043           bool mpsafe;
2044           struct vop_setacl_args a;
2045           struct mount *mp;
2046           a.a_desc = VDESC(vop_setacl);
2047           a.a_vp = vp;
2048           a.a_type = type;
2049           a.a_aclp = aclp;
2050           a.a_cred = cred;
2051           assert_vop_elocked(vp, "vop_setacl: vp");
2052           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
2053           if (error)
2054                     return error;
2055           error = (VCALL(vp, VOFFSET(vop_setacl), &a));
2056           vop_post(vp, mp, mpsafe, FST_NO);
2057           vop_setacl_post(&a, error);
2058           return error;
2059 }
2060 
2061 const int vop_aclcheck_vp_offsets[] = {
2062           VOPARG_OFFSETOF(struct vop_aclcheck_args,a_vp),
2063           VDESC_NO_OFFSET
2064 };
2065 const struct vnodeop_desc vop_aclcheck_desc = {
2066           VOP_ACLCHECK_DESCOFFSET,
2067           "vop_aclcheck",
2068           0,
2069           vop_aclcheck_vp_offsets,
2070           VDESC_NO_OFFSET,
2071           VOPARG_OFFSETOF(struct vop_aclcheck_args, a_cred),
2072           VDESC_NO_OFFSET,
2073 };
2074 int
VOP_ACLCHECK(struct vnode * vp,acl_type_t type,struct acl * aclp,kauth_cred_t cred)2075 VOP_ACLCHECK(struct vnode *vp,
2076     acl_type_t type,
2077     struct acl *aclp,
2078     kauth_cred_t cred)
2079 {
2080           int error;
2081           bool mpsafe;
2082           struct vop_aclcheck_args a;
2083           struct mount *mp;
2084           a.a_desc = VDESC(vop_aclcheck);
2085           a.a_vp = vp;
2086           a.a_type = type;
2087           a.a_aclp = aclp;
2088           a.a_cred = cred;
2089           error = vop_pre(vp, &mp, &mpsafe, FST_YES);
2090           if (error)
2091                     return error;
2092           error = (VCALL(vp, VOFFSET(vop_aclcheck), &a));
2093           vop_post(vp, mp, mpsafe, FST_YES);
2094           return error;
2095 }
2096 
2097 const int vop_closeextattr_vp_offsets[] = {
2098           VOPARG_OFFSETOF(struct vop_closeextattr_args,a_vp),
2099           VDESC_NO_OFFSET
2100 };
2101 const struct vnodeop_desc vop_closeextattr_desc = {
2102           VOP_CLOSEEXTATTR_DESCOFFSET,
2103           "vop_closeextattr",
2104           0,
2105           vop_closeextattr_vp_offsets,
2106           VDESC_NO_OFFSET,
2107           VOPARG_OFFSETOF(struct vop_closeextattr_args, a_cred),
2108           VDESC_NO_OFFSET,
2109 };
2110 int
VOP_CLOSEEXTATTR(struct vnode * vp,int commit,kauth_cred_t cred)2111 VOP_CLOSEEXTATTR(struct vnode *vp,
2112     int commit,
2113     kauth_cred_t cred)
2114 {
2115           int error;
2116           bool mpsafe;
2117           struct vop_closeextattr_args a;
2118           struct mount *mp;
2119           a.a_desc = VDESC(vop_closeextattr);
2120           a.a_vp = vp;
2121           a.a_commit = commit;
2122           a.a_cred = cred;
2123           assert_vop_locked(vp, "vop_closeextattr: vp");
2124           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
2125           if (error)
2126                     return error;
2127           error = (VCALL(vp, VOFFSET(vop_closeextattr), &a));
2128           vop_post(vp, mp, mpsafe, FST_NO);
2129           return error;
2130 }
2131 
2132 const int vop_getextattr_vp_offsets[] = {
2133           VOPARG_OFFSETOF(struct vop_getextattr_args,a_vp),
2134           VDESC_NO_OFFSET
2135 };
2136 const struct vnodeop_desc vop_getextattr_desc = {
2137           VOP_GETEXTATTR_DESCOFFSET,
2138           "vop_getextattr",
2139           0,
2140           vop_getextattr_vp_offsets,
2141           VDESC_NO_OFFSET,
2142           VOPARG_OFFSETOF(struct vop_getextattr_args, a_cred),
2143           VDESC_NO_OFFSET,
2144 };
2145 int
VOP_GETEXTATTR(struct vnode * vp,int attrnamespace,const char * name,struct uio * uio,size_t * size,kauth_cred_t cred)2146 VOP_GETEXTATTR(struct vnode *vp,
2147     int attrnamespace,
2148     const char *name,
2149     struct uio *uio,
2150     size_t *size,
2151     kauth_cred_t cred)
2152 {
2153           int error;
2154           bool mpsafe;
2155           struct vop_getextattr_args a;
2156           struct mount *mp;
2157           a.a_desc = VDESC(vop_getextattr);
2158           a.a_vp = vp;
2159           a.a_attrnamespace = attrnamespace;
2160           a.a_name = name;
2161           a.a_uio = uio;
2162           a.a_size = size;
2163           a.a_cred = cred;
2164           assert_vop_locked(vp, "vop_getextattr: vp");
2165           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
2166           if (error)
2167                     return error;
2168           error = (VCALL(vp, VOFFSET(vop_getextattr), &a));
2169           vop_post(vp, mp, mpsafe, FST_NO);
2170           return error;
2171 }
2172 
2173 const int vop_listextattr_vp_offsets[] = {
2174           VOPARG_OFFSETOF(struct vop_listextattr_args,a_vp),
2175           VDESC_NO_OFFSET
2176 };
2177 const struct vnodeop_desc vop_listextattr_desc = {
2178           VOP_LISTEXTATTR_DESCOFFSET,
2179           "vop_listextattr",
2180           0,
2181           vop_listextattr_vp_offsets,
2182           VDESC_NO_OFFSET,
2183           VOPARG_OFFSETOF(struct vop_listextattr_args, a_cred),
2184           VDESC_NO_OFFSET,
2185 };
2186 int
VOP_LISTEXTATTR(struct vnode * vp,int attrnamespace,struct uio * uio,size_t * size,int flag,kauth_cred_t cred)2187 VOP_LISTEXTATTR(struct vnode *vp,
2188     int attrnamespace,
2189     struct uio *uio,
2190     size_t *size,
2191     int flag,
2192     kauth_cred_t cred)
2193 {
2194           int error;
2195           bool mpsafe;
2196           struct vop_listextattr_args a;
2197           struct mount *mp;
2198           a.a_desc = VDESC(vop_listextattr);
2199           a.a_vp = vp;
2200           a.a_attrnamespace = attrnamespace;
2201           a.a_uio = uio;
2202           a.a_size = size;
2203           a.a_flag = flag;
2204           a.a_cred = cred;
2205           assert_vop_locked(vp, "vop_listextattr: vp");
2206           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
2207           if (error)
2208                     return error;
2209           error = (VCALL(vp, VOFFSET(vop_listextattr), &a));
2210           vop_post(vp, mp, mpsafe, FST_NO);
2211           return error;
2212 }
2213 
2214 const int vop_openextattr_vp_offsets[] = {
2215           VOPARG_OFFSETOF(struct vop_openextattr_args,a_vp),
2216           VDESC_NO_OFFSET
2217 };
2218 const struct vnodeop_desc vop_openextattr_desc = {
2219           VOP_OPENEXTATTR_DESCOFFSET,
2220           "vop_openextattr",
2221           0,
2222           vop_openextattr_vp_offsets,
2223           VDESC_NO_OFFSET,
2224           VOPARG_OFFSETOF(struct vop_openextattr_args, a_cred),
2225           VDESC_NO_OFFSET,
2226 };
2227 int
VOP_OPENEXTATTR(struct vnode * vp,kauth_cred_t cred)2228 VOP_OPENEXTATTR(struct vnode *vp,
2229     kauth_cred_t cred)
2230 {
2231           int error;
2232           bool mpsafe;
2233           struct vop_openextattr_args a;
2234           struct mount *mp;
2235           a.a_desc = VDESC(vop_openextattr);
2236           a.a_vp = vp;
2237           a.a_cred = cred;
2238           assert_vop_locked(vp, "vop_openextattr: vp");
2239           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
2240           if (error)
2241                     return error;
2242           error = (VCALL(vp, VOFFSET(vop_openextattr), &a));
2243           vop_post(vp, mp, mpsafe, FST_NO);
2244           return error;
2245 }
2246 
2247 const int vop_deleteextattr_vp_offsets[] = {
2248           VOPARG_OFFSETOF(struct vop_deleteextattr_args,a_vp),
2249           VDESC_NO_OFFSET
2250 };
2251 const struct vnodeop_desc vop_deleteextattr_desc = {
2252           VOP_DELETEEXTATTR_DESCOFFSET,
2253           "vop_deleteextattr",
2254           0,
2255           vop_deleteextattr_vp_offsets,
2256           VDESC_NO_OFFSET,
2257           VOPARG_OFFSETOF(struct vop_deleteextattr_args, a_cred),
2258           VDESC_NO_OFFSET,
2259 };
2260 int
VOP_DELETEEXTATTR(struct vnode * vp,int attrnamespace,const char * name,kauth_cred_t cred)2261 VOP_DELETEEXTATTR(struct vnode *vp,
2262     int attrnamespace,
2263     const char *name,
2264     kauth_cred_t cred)
2265 {
2266           int error;
2267           bool mpsafe;
2268           struct vop_deleteextattr_args a;
2269           struct mount *mp;
2270           a.a_desc = VDESC(vop_deleteextattr);
2271           a.a_vp = vp;
2272           a.a_attrnamespace = attrnamespace;
2273           a.a_name = name;
2274           a.a_cred = cred;
2275           assert_vop_elocked(vp, "vop_deleteextattr: vp");
2276           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
2277           if (error)
2278                     return error;
2279           error = (VCALL(vp, VOFFSET(vop_deleteextattr), &a));
2280           vop_post(vp, mp, mpsafe, FST_NO);
2281           return error;
2282 }
2283 
2284 const int vop_setextattr_vp_offsets[] = {
2285           VOPARG_OFFSETOF(struct vop_setextattr_args,a_vp),
2286           VDESC_NO_OFFSET
2287 };
2288 const struct vnodeop_desc vop_setextattr_desc = {
2289           VOP_SETEXTATTR_DESCOFFSET,
2290           "vop_setextattr",
2291           0,
2292           vop_setextattr_vp_offsets,
2293           VDESC_NO_OFFSET,
2294           VOPARG_OFFSETOF(struct vop_setextattr_args, a_cred),
2295           VDESC_NO_OFFSET,
2296 };
2297 int
VOP_SETEXTATTR(struct vnode * vp,int attrnamespace,const char * name,struct uio * uio,kauth_cred_t cred)2298 VOP_SETEXTATTR(struct vnode *vp,
2299     int attrnamespace,
2300     const char *name,
2301     struct uio *uio,
2302     kauth_cred_t cred)
2303 {
2304           int error;
2305           bool mpsafe;
2306           struct vop_setextattr_args a;
2307           struct mount *mp;
2308           a.a_desc = VDESC(vop_setextattr);
2309           a.a_vp = vp;
2310           a.a_attrnamespace = attrnamespace;
2311           a.a_name = name;
2312           a.a_uio = uio;
2313           a.a_cred = cred;
2314           assert_vop_elocked(vp, "vop_setextattr: vp");
2315           error = vop_pre(vp, &mp, &mpsafe, FST_NO);
2316           if (error)
2317                     return error;
2318           error = (VCALL(vp, VOFFSET(vop_setextattr), &a));
2319           vop_post(vp, mp, mpsafe, FST_NO);
2320           return error;
2321 }
2322 
2323 const struct vnodeop_desc * const vfs_op_descs[] = {
2324           &vop_default_desc,  /* MUST BE FIRST */
2325 
2326           &vop_bwrite_desc,
2327           &vop_parsepath_desc,
2328           &vop_lookup_desc,
2329           &vop_create_desc,
2330           &vop_mknod_desc,
2331           &vop_open_desc,
2332           &vop_close_desc,
2333           &vop_access_desc,
2334           &vop_accessx_desc,
2335           &vop_getattr_desc,
2336           &vop_setattr_desc,
2337           &vop_read_desc,
2338           &vop_write_desc,
2339           &vop_fallocate_desc,
2340           &vop_fdiscard_desc,
2341           &vop_ioctl_desc,
2342           &vop_fcntl_desc,
2343           &vop_poll_desc,
2344           &vop_kqfilter_desc,
2345           &vop_revoke_desc,
2346           &vop_mmap_desc,
2347           &vop_fsync_desc,
2348           &vop_seek_desc,
2349           &vop_remove_desc,
2350           &vop_link_desc,
2351           &vop_rename_desc,
2352           &vop_mkdir_desc,
2353           &vop_rmdir_desc,
2354           &vop_symlink_desc,
2355           &vop_readdir_desc,
2356           &vop_readlink_desc,
2357           &vop_abortop_desc,
2358           &vop_inactive_desc,
2359           &vop_reclaim_desc,
2360           &vop_lock_desc,
2361           &vop_unlock_desc,
2362           &vop_bmap_desc,
2363           &vop_strategy_desc,
2364           &vop_print_desc,
2365           &vop_islocked_desc,
2366           &vop_pathconf_desc,
2367           &vop_advlock_desc,
2368           &vop_whiteout_desc,
2369           &vop_getpages_desc,
2370           &vop_putpages_desc,
2371           &vop_getacl_desc,
2372           &vop_setacl_desc,
2373           &vop_aclcheck_desc,
2374           &vop_closeextattr_desc,
2375           &vop_getextattr_desc,
2376           &vop_listextattr_desc,
2377           &vop_openextattr_desc,
2378           &vop_deleteextattr_desc,
2379           &vop_setextattr_desc,
2380           NULL
2381 };
2382