xref: /dragonfly/sys/kern/vfs_vopops.c (revision e98bdfd3)
1 /*
2  * Copyright (c) 2004,2009 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
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
16  *    distribution.
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.
20  *
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
32  * SUCH DAMAGE.
33  */
34 /*
35  * Implement vnode ops wrappers.  All vnode ops are wrapped through
36  * these functions.
37  *
38  * These wrappers are responsible for hanlding all MPSAFE issues related
39  * to a vnode operation.
40  */
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/buf.h>
45 #include <sys/conf.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>
53 #include <sys/mbuf.h>
54 #include <sys/mount.h>
55 #include <sys/proc.h>
56 #include <sys/namei.h>
57 #include <sys/reboot.h>
58 #include <sys/socket.h>
59 #include <sys/stat.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>
67 
68 #include <machine/limits.h>
69 
70 #include <vm/vm.h>
71 #include <vm/vm_object.h>
72 #include <vm/vm_extern.h>
73 #include <vm/vm_kern.h>
74 #include <vm/pmap.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>
80 
81 #include <sys/buf2.h>
82 #include <sys/thread2.h>
83 #include <sys/mplock2.h>
84 
85 #define VDESCNAME(name)	__CONCAT(__CONCAT(vop_,name),_desc)
86 
87 #define VNODEOP_DESC_INIT(name)						\
88 	struct syslink_desc VDESCNAME(name) = {				\
89 		__offsetof(struct vop_ops, __CONCAT(vop_, name)),	\
90 		#name }
91 
92 VNODEOP_DESC_INIT(default);
93 VNODEOP_DESC_INIT(old_lookup);
94 VNODEOP_DESC_INIT(old_create);
95 VNODEOP_DESC_INIT(old_whiteout);
96 VNODEOP_DESC_INIT(old_mknod);
97 VNODEOP_DESC_INIT(open);
98 VNODEOP_DESC_INIT(close);
99 VNODEOP_DESC_INIT(access);
100 VNODEOP_DESC_INIT(getattr);
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);
112 
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);
137 
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);
149 
150 #define DO_OPS(ops, error, ap, vop_field)	\
151 	error = ops->vop_field(ap)
152 
153 /************************************************************************
154  *		PRIMARY HIGH LEVEL VNODE OPERATIONS CALLS		*
155  ************************************************************************
156  *
157  * These procedures are called directly from the kernel and/or fileops
158  * code to perform file/device operations on the system.
159  *
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
163  *	 those ops.
164  *
165  * NOTE: The VFS_MPLOCK() macro handle mounts which do not set MNTK_MPSAFE.
166  *
167  * MPSAFE
168  */
169 
170 int
171 vop_old_lookup(struct vop_ops *ops, struct vnode *dvp,
172 	struct vnode **vpp, struct componentname *cnp)
173 {
174 	struct vop_old_lookup_args ap;
175 	VFS_MPLOCK_DECLARE;
176 	int error;
177 
178 	ap.a_head.a_desc = &vop_old_lookup_desc;
179 	ap.a_head.a_ops = ops;
180 	ap.a_dvp = dvp;
181 	ap.a_vpp = vpp;
182 	ap.a_cnp = cnp;
183 	VFS_MPLOCK(dvp->v_mount);
184 	DO_OPS(ops, error, &ap, vop_old_lookup);
185 	VFS_MPUNLOCK(dvp->v_mount);
186 	return(error);
187 }
188 
189 /*
190  * MPSAFE
191  */
192 int
193 vop_old_create(struct vop_ops *ops, struct vnode *dvp,
194 	struct vnode **vpp, struct componentname *cnp, struct vattr *vap)
195 {
196 	struct vop_old_create_args ap;
197 	VFS_MPLOCK_DECLARE;
198 	int error;
199 
200 	ap.a_head.a_desc = &vop_old_create_desc;
201 	ap.a_head.a_ops = ops;
202 	ap.a_dvp = dvp;
203 	ap.a_vpp = vpp;
204 	ap.a_cnp = cnp;
205 	ap.a_vap = vap;
206 
207 	VFS_MPLOCK(dvp->v_mount);
208 	DO_OPS(ops, error, &ap, vop_old_create);
209 	VFS_MPUNLOCK(dvp->v_mount);
210 	return(error);
211 }
212 
213 /*
214  * MPSAFE
215  */
216 int
217 vop_old_whiteout(struct vop_ops *ops, struct vnode *dvp,
218 	struct componentname *cnp, int flags)
219 {
220 	struct vop_old_whiteout_args ap;
221 	VFS_MPLOCK_DECLARE;
222 	int error;
223 
224 	ap.a_head.a_desc = &vop_old_whiteout_desc;
225 	ap.a_head.a_ops = ops;
226 	ap.a_dvp = dvp;
227 	ap.a_cnp = cnp;
228 	ap.a_flags = flags;
229 
230 	VFS_MPLOCK(dvp->v_mount);
231 	DO_OPS(ops, error, &ap, vop_old_whiteout);
232 	VFS_MPUNLOCK(dvp->v_mount);
233 	return(error);
234 }
235 
236 /*
237  * MPSAFE
238  */
239 int
240 vop_old_mknod(struct vop_ops *ops, struct vnode *dvp,
241 	struct vnode **vpp, struct componentname *cnp, struct vattr *vap)
242 {
243 	struct vop_old_mknod_args ap;
244 	VFS_MPLOCK_DECLARE;
245 	int error;
246 
247 	ap.a_head.a_desc = &vop_old_mknod_desc;
248 	ap.a_head.a_ops = ops;
249 	ap.a_dvp = dvp;
250 	ap.a_vpp = vpp;
251 	ap.a_cnp = cnp;
252 	ap.a_vap = vap;
253 
254 	VFS_MPLOCK(dvp->v_mount);
255 	DO_OPS(ops, error, &ap, vop_old_mknod);
256 	VFS_MPUNLOCK(dvp->v_mount);
257 	return(error);
258 }
259 
260 /*
261  * NOTE: VAGE is always cleared when calling VOP_OPEN().
262  */
263 int
264 vop_open(struct vop_ops *ops, struct vnode *vp, int mode, struct ucred *cred,
265 	struct file *fp)
266 {
267 	struct vop_open_args ap;
268 	VFS_MPLOCK_DECLARE;
269 	int error;
270 
271 	/*
272 	 * Decrement 3-2-1-0.  Does not decrement beyond 0
273 	 */
274 	if (vp->v_flag & VAGE0) {
275 		vclrflags(vp, VAGE0);
276 	} else if (vp->v_flag & VAGE1) {
277 		vclrflags(vp, VAGE1);
278 		vsetflags(vp, VAGE0);
279 	}
280 
281 	ap.a_head.a_desc = &vop_open_desc;
282 	ap.a_head.a_ops = ops;
283 	ap.a_vp = vp;
284 	ap.a_fp = fp;
285 	ap.a_mode = mode;
286 	ap.a_cred = cred;
287 
288 	VFS_MPLOCK(vp->v_mount);
289 	DO_OPS(ops, error, &ap, vop_open);
290 	VFS_MPUNLOCK(vp->v_mount);
291 	return(error);
292 }
293 
294 /*
295  * MPSAFE
296  */
297 int
298 vop_close(struct vop_ops *ops, struct vnode *vp, int fflag,
299          struct file *fp)
300 {
301 	struct vop_close_args ap;
302 	VFS_MPLOCK_DECLARE;
303 	int error;
304 
305 	ap.a_head.a_desc = &vop_close_desc;
306 	ap.a_head.a_ops = ops;
307 	ap.a_vp = vp;
308 	ap.a_fp = fp;
309 	ap.a_fflag = fflag;
310 
311 	VFS_MPLOCK(vp->v_mount);
312 	DO_OPS(ops, error, &ap, vop_close);
313 	VFS_MPUNLOCK(vp->v_mount);
314 	return(error);
315 }
316 
317 /*
318  * MPSAFE
319  */
320 int
321 vop_access(struct vop_ops *ops, struct vnode *vp, int mode, int flags,
322 	   struct ucred *cred)
323 {
324 	struct vop_access_args ap;
325 	VFS_MPLOCK_DECLARE;
326 	int error;
327 
328 	ap.a_head.a_desc = &vop_access_desc;
329 	ap.a_head.a_ops = ops;
330 	ap.a_vp = vp;
331 	ap.a_mode = mode;
332 	ap.a_flags = flags;
333 	ap.a_cred = cred;
334 
335 	VFS_MPLOCK(vp->v_mount);
336 	DO_OPS(ops, error, &ap, vop_access);
337 	VFS_MPUNLOCK(vp->v_mount);
338 	return(error);
339 }
340 
341 /*
342  * MPSAFE
343  */
344 int
345 vop_getattr(struct vop_ops *ops, struct vnode *vp, struct vattr *vap)
346 {
347 	struct vop_getattr_args ap;
348 	VFS_MPLOCK_DECLARE;
349 	int error;
350 
351 	ap.a_head.a_desc = &vop_getattr_desc;
352 	ap.a_head.a_ops = ops;
353 	ap.a_vp = vp;
354 	ap.a_vap = vap;
355 
356 	VFS_MPLOCK_FLAG(vp->v_mount, MNTK_GA_MPSAFE);
357 	DO_OPS(ops, error, &ap, vop_getattr);
358 	VFS_MPUNLOCK(vp->v_mount);
359 
360 	return(error);
361 }
362 
363 /*
364  * MPSAFE
365  */
366 int
367 vop_setattr(struct vop_ops *ops, struct vnode *vp, struct vattr *vap,
368 	struct ucred *cred)
369 {
370 	struct vop_setattr_args ap;
371 	VFS_MPLOCK_DECLARE;
372 	int error;
373 
374 	ap.a_head.a_desc = &vop_setattr_desc;
375 	ap.a_head.a_ops = ops;
376 	ap.a_vp = vp;
377 	ap.a_vap = vap;
378 	ap.a_cred = cred;
379 
380 	VFS_MPLOCK(vp->v_mount);
381 	DO_OPS(ops, error, &ap, vop_setattr);
382 	VFS_MPUNLOCK(vp->v_mount);
383 	return(error);
384 }
385 
386 /*
387  * MPSAFE
388  */
389 int
390 vop_read(struct vop_ops *ops, struct vnode *vp, struct uio *uio, int ioflag,
391 	struct ucred *cred)
392 {
393 	struct vop_read_args ap;
394 	VFS_MPLOCK_DECLARE;
395 	int error;
396 
397 	ap.a_head.a_desc = &vop_read_desc;
398 	ap.a_head.a_ops = ops;
399 	ap.a_vp = vp;
400 	ap.a_uio = uio;
401 	ap.a_ioflag = ioflag;
402 	ap.a_cred = cred;
403 
404 	VFS_MPLOCK_FLAG(vp->v_mount, MNTK_RD_MPSAFE);
405 	DO_OPS(ops, error, &ap, vop_read);
406 	VFS_MPUNLOCK(vp->v_mount);
407 	return(error);
408 }
409 
410 /*
411  * MPSAFE
412  */
413 int
414 vop_write(struct vop_ops *ops, struct vnode *vp, struct uio *uio, int ioflag,
415 	struct ucred *cred)
416 {
417 	struct vop_write_args ap;
418 	VFS_MPLOCK_DECLARE;
419 	int error, do_accounting = 0;
420 	struct vattr va;
421 	uint64_t size_before=0, size_after=0;
422 	struct mount *mp;
423 	uint64_t offset, delta;
424 
425 	ap.a_head.a_desc = &vop_write_desc;
426 	ap.a_head.a_ops = ops;
427 	ap.a_vp = vp;
428 	ap.a_uio = uio;
429 	ap.a_ioflag = ioflag;
430 	ap.a_cred = cred;
431 
432 	/* is this a regular vnode ? */
433 	VFS_MPLOCK_FLAG(vp->v_mount, MNTK_WR_MPSAFE);
434 	if (vfs_quota_enabled && (vp->v_type == VREG)) {
435 		if ((error = VOP_GETATTR(vp, &va)) != 0)
436 			goto done;
437 		size_before = va.va_size;
438 		/* this file may already have been removed */
439 		if (va.va_nlink > 0)
440 			do_accounting = 1;
441 
442 		offset = uio->uio_offset;
443 		if (ioflag & IO_APPEND)
444 			offset = size_before;
445 		size_after = offset + uio->uio_resid;
446 		if (size_after < size_before)
447 			size_after = size_before;
448 		delta = size_after - size_before;
449 		mp = vq_vptomp(vp);
450 		/* QUOTA CHECK */
451 		if (!vq_write_ok(mp, va.va_uid, va.va_gid, delta)) {
452 			error = EDQUOT;
453 			goto done;
454 		}
455 	}
456 	DO_OPS(ops, error, &ap, vop_write);
457 	if ((error == 0) && do_accounting) {
458 		VFS_ACCOUNT(mp, va.va_uid, va.va_gid, size_after - size_before);
459 	}
460 done:
461 	VFS_MPUNLOCK(vp->v_mount);
462 	return(error);
463 }
464 
465 /*
466  * MPSAFE
467  */
468 int
469 vop_ioctl(struct vop_ops *ops, struct vnode *vp, u_long command, caddr_t data,
470 	int fflag, struct ucred *cred, struct sysmsg *msg)
471 {
472 	struct vop_ioctl_args ap;
473 	VFS_MPLOCK_DECLARE;
474 	int error;
475 
476 	ap.a_head.a_desc = &vop_ioctl_desc;
477 	ap.a_head.a_ops = ops;
478 	ap.a_vp = vp;
479 	ap.a_command = command;
480 	ap.a_data = data;
481 	ap.a_fflag = fflag;
482 	ap.a_cred = cred;
483 	ap.a_sysmsg = msg;
484 
485 	VFS_MPLOCK(vp->v_mount);
486 	DO_OPS(ops, error, &ap, vop_ioctl);
487 	VFS_MPUNLOCK(vp->v_mount);
488 	return(error);
489 }
490 
491 /*
492  * MPSAFE
493  */
494 int
495 vop_poll(struct vop_ops *ops, struct vnode *vp, int events, struct ucred *cred)
496 {
497 	struct vop_poll_args ap;
498 	VFS_MPLOCK_DECLARE;
499 	int error;
500 
501 	ap.a_head.a_desc = &vop_poll_desc;
502 	ap.a_head.a_ops = ops;
503 	ap.a_vp = vp;
504 	ap.a_events = events;
505 	ap.a_cred = cred;
506 
507 	VFS_MPLOCK(vp->v_mount);
508 	DO_OPS(ops, error, &ap, vop_poll);
509 	VFS_MPUNLOCK(vp->v_mount);
510 	return(error);
511 }
512 
513 /*
514  * MPSAFE
515  */
516 int
517 vop_kqfilter(struct vop_ops *ops, struct vnode *vp, struct knote *kn)
518 {
519 	struct vop_kqfilter_args ap;
520 	VFS_MPLOCK_DECLARE;
521 	int error;
522 
523 	ap.a_head.a_desc = &vop_kqfilter_desc;
524 	ap.a_head.a_ops = ops;
525 	ap.a_vp = vp;
526 	ap.a_kn = kn;
527 
528 	VFS_MPLOCK(vp->v_mount);
529 	DO_OPS(ops, error, &ap, vop_kqfilter);
530 	VFS_MPUNLOCK(vp->v_mount);
531 	return(error);
532 }
533 
534 /*
535  * MPSAFE
536  */
537 int
538 vop_mmap(struct vop_ops *ops, struct vnode *vp, int fflags, struct ucred *cred)
539 {
540 	struct vop_mmap_args ap;
541 	VFS_MPLOCK_DECLARE;
542 	int error;
543 
544 	ap.a_head.a_desc = &vop_mmap_desc;
545 	ap.a_head.a_ops = ops;
546 	ap.a_vp = vp;
547 	ap.a_fflags = fflags;
548 	ap.a_cred = cred;
549 
550 	VFS_MPLOCK(vp->v_mount);
551 	DO_OPS(ops, error, &ap, vop_mmap);
552 	VFS_MPUNLOCK(vp->v_mount);
553 	return(error);
554 }
555 
556 /*
557  * MPSAFE
558  */
559 int
560 vop_fsync(struct vop_ops *ops, struct vnode *vp, int waitfor, int flags)
561 {
562 	struct vop_fsync_args ap;
563 	VFS_MPLOCK_DECLARE;
564 	int error;
565 
566 	ap.a_head.a_desc = &vop_fsync_desc;
567 	ap.a_head.a_ops = ops;
568 	ap.a_vp = vp;
569 	ap.a_waitfor = waitfor;
570 	ap.a_flags = flags;
571 
572 	VFS_MPLOCK(vp->v_mount);
573 	DO_OPS(ops, error, &ap, vop_fsync);
574 	VFS_MPUNLOCK(vp->v_mount);
575 	return(error);
576 }
577 
578 /*
579  * MPSAFE
580  */
581 int
582 vop_old_remove(struct vop_ops *ops, struct vnode *dvp,
583 	struct vnode *vp, struct componentname *cnp)
584 {
585 	struct vop_old_remove_args ap;
586 	VFS_MPLOCK_DECLARE;
587 	int error;
588 
589 	ap.a_head.a_desc = &vop_old_remove_desc;
590 	ap.a_head.a_ops = ops;
591 	ap.a_dvp = dvp;
592 	ap.a_vp = vp;
593 	ap.a_cnp = cnp;
594 
595 	VFS_MPLOCK(dvp->v_mount);
596 	DO_OPS(ops, error, &ap, vop_old_remove);
597 	VFS_MPUNLOCK(dvp->v_mount);
598 	return(error);
599 }
600 
601 /*
602  * MPSAFE
603  */
604 int
605 vop_old_link(struct vop_ops *ops, struct vnode *tdvp,
606 	struct vnode *vp, struct componentname *cnp)
607 {
608 	struct vop_old_link_args ap;
609 	VFS_MPLOCK_DECLARE;
610 	int error;
611 
612 	ap.a_head.a_desc = &vop_old_link_desc;
613 	ap.a_head.a_ops = ops;
614 	ap.a_tdvp = tdvp;
615 	ap.a_vp = vp;
616 	ap.a_cnp = cnp;
617 
618 	VFS_MPLOCK(tdvp->v_mount);
619 	DO_OPS(ops, error, &ap, vop_old_link);
620 	VFS_MPUNLOCK(tdvp->v_mount);
621 	return(error);
622 }
623 
624 /*
625  * MPSAFE
626  */
627 int
628 vop_old_rename(struct vop_ops *ops,
629 	   struct vnode *fdvp, struct vnode *fvp, struct componentname *fcnp,
630 	   struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp)
631 {
632 	struct vop_old_rename_args ap;
633 	VFS_MPLOCK_DECLARE;
634 	int error;
635 
636 	ap.a_head.a_desc = &vop_old_rename_desc;
637 	ap.a_head.a_ops = ops;
638 	ap.a_fdvp = fdvp;
639 	ap.a_fvp = fvp;
640 	ap.a_fcnp = fcnp;
641 	ap.a_tdvp = tdvp;
642 	ap.a_tvp = tvp;
643 	ap.a_tcnp = tcnp;
644 
645 	VFS_MPLOCK(tdvp->v_mount);
646 	DO_OPS(ops, error, &ap, vop_old_rename);
647 	VFS_MPUNLOCK(tdvp->v_mount);
648 	return(error);
649 }
650 
651 /*
652  * MPSAFE
653  */
654 int
655 vop_old_mkdir(struct vop_ops *ops, struct vnode *dvp,
656 	struct vnode **vpp, struct componentname *cnp, struct vattr *vap)
657 {
658 	struct vop_old_mkdir_args ap;
659 	VFS_MPLOCK_DECLARE;
660 	int error;
661 
662 	ap.a_head.a_desc = &vop_old_mkdir_desc;
663 	ap.a_head.a_ops = ops;
664 	ap.a_dvp = dvp;
665 	ap.a_vpp = vpp;
666 	ap.a_cnp = cnp;
667 	ap.a_vap = vap;
668 
669 	VFS_MPLOCK(dvp->v_mount);
670 	DO_OPS(ops, error, &ap, vop_old_mkdir);
671 	VFS_MPUNLOCK(dvp->v_mount);
672 	return(error);
673 }
674 
675 /*
676  * MPSAFE
677  */
678 int
679 vop_old_rmdir(struct vop_ops *ops, struct vnode *dvp,
680 	struct vnode *vp, struct componentname *cnp)
681 {
682 	struct vop_old_rmdir_args ap;
683 	VFS_MPLOCK_DECLARE;
684 	int error;
685 
686 	ap.a_head.a_desc = &vop_old_rmdir_desc;
687 	ap.a_head.a_ops = ops;
688 	ap.a_dvp = dvp;
689 	ap.a_vp = vp;
690 	ap.a_cnp = cnp;
691 
692 	VFS_MPLOCK(dvp->v_mount);
693 	DO_OPS(ops, error, &ap, vop_old_rmdir);
694 	VFS_MPUNLOCK(dvp->v_mount);
695 	return(error);
696 }
697 
698 /*
699  * MPSAFE
700  */
701 int
702 vop_old_symlink(struct vop_ops *ops, struct vnode *dvp,
703 	struct vnode **vpp, struct componentname *cnp,
704 	struct vattr *vap, char *target)
705 {
706 	struct vop_old_symlink_args ap;
707 	VFS_MPLOCK_DECLARE;
708 	int error;
709 
710 	ap.a_head.a_desc = &vop_old_symlink_desc;
711 	ap.a_head.a_ops = ops;
712 	ap.a_dvp = dvp;
713 	ap.a_vpp = vpp;
714 	ap.a_cnp = cnp;
715 	ap.a_vap = vap;
716 	ap.a_target = target;
717 
718 	VFS_MPLOCK(dvp->v_mount);
719 	DO_OPS(ops, error, &ap, vop_old_symlink);
720 	VFS_MPUNLOCK(dvp->v_mount);
721 	return(error);
722 }
723 
724 /*
725  * MPSAFE
726  */
727 int
728 vop_readdir(struct vop_ops *ops, struct vnode *vp, struct uio *uio,
729 	struct ucred *cred, int *eofflag, int *ncookies, off_t **cookies)
730 {
731 	struct vop_readdir_args ap;
732 	VFS_MPLOCK_DECLARE;
733 	int error;
734 
735 	ap.a_head.a_desc = &vop_readdir_desc;
736 	ap.a_head.a_ops = ops;
737 	ap.a_vp = vp;
738 	ap.a_uio = uio;
739 	ap.a_cred = cred;
740 	ap.a_eofflag = eofflag;
741 	ap.a_ncookies = ncookies;
742 	ap.a_cookies = cookies;
743 
744 	VFS_MPLOCK(vp->v_mount);
745 	DO_OPS(ops, error, &ap, vop_readdir);
746 	VFS_MPUNLOCK(vp->v_mount);
747 	return(error);
748 }
749 
750 /*
751  * MPSAFE
752  */
753 int
754 vop_readlink(struct vop_ops *ops, struct vnode *vp, struct uio *uio,
755 	struct ucred *cred)
756 {
757 	struct vop_readlink_args ap;
758 	VFS_MPLOCK_DECLARE;
759 	int error;
760 
761 	ap.a_head.a_desc = &vop_readlink_desc;
762 	ap.a_head.a_ops = ops;
763 	ap.a_vp = vp;
764 	ap.a_uio = uio;
765 	ap.a_cred = cred;
766 
767 	VFS_MPLOCK(vp->v_mount);
768 	DO_OPS(ops, error, &ap, vop_readlink);
769 	VFS_MPUNLOCK(vp->v_mount);
770 	return(error);
771 }
772 
773 /*
774  * MPSAFE
775  */
776 int
777 vop_inactive(struct vop_ops *ops, struct vnode *vp)
778 {
779 	struct vop_inactive_args ap;
780 	struct mount *mp;
781 	VFS_MPLOCK_DECLARE;
782 	int error;
783 
784 	ap.a_head.a_desc = &vop_inactive_desc;
785 	ap.a_head.a_ops = ops;
786 	ap.a_vp = vp;
787 
788 	/*
789 	 * WARNING!  Deactivation of the vnode can cause it to be recycled,
790 	 *	     clearing vp->v_mount.
791 	 */
792 	mp = vp->v_mount;
793 	VFS_MPLOCK_FLAG(mp, MNTK_IN_MPSAFE);
794 	DO_OPS(ops, error, &ap, vop_inactive);
795 	VFS_MPUNLOCK(mp);
796 	return(error);
797 }
798 
799 /*
800  * MPSAFE
801  */
802 int
803 vop_reclaim(struct vop_ops *ops, struct vnode *vp)
804 {
805 	struct vop_reclaim_args ap;
806 	struct mount *mp;
807 	VFS_MPLOCK_DECLARE;
808 	int error;
809 
810 	ap.a_head.a_desc = &vop_reclaim_desc;
811 	ap.a_head.a_ops = ops;
812 	ap.a_vp = vp;
813 
814 	/*
815 	 * WARNING!  Reclamation of the vnode will clear vp->v_mount.
816 	 */
817 	mp = vp->v_mount;
818 	VFS_MPLOCK(mp);
819 	DO_OPS(ops, error, &ap, vop_reclaim);
820 	VFS_MPUNLOCK(mp);
821 	return(error);
822 }
823 
824 /*
825  * MPSAFE
826  */
827 int
828 vop_bmap(struct vop_ops *ops, struct vnode *vp, off_t loffset,
829 	off_t *doffsetp, int *runp, int *runb, buf_cmd_t cmd)
830 {
831 	struct vop_bmap_args ap;
832 	VFS_MPLOCK_DECLARE;
833 	int error;
834 
835 	ap.a_head.a_desc = &vop_bmap_desc;
836 	ap.a_head.a_ops = ops;
837 	ap.a_vp = vp;
838 	ap.a_loffset = loffset;
839 	ap.a_doffsetp = doffsetp;
840 	ap.a_runp = runp;
841 	ap.a_runb = runb;
842 	ap.a_cmd = cmd;
843 
844 	VFS_MPLOCK(vp->v_mount);
845 	DO_OPS(ops, error, &ap, vop_bmap);
846 	VFS_MPUNLOCK(vp->v_mount);
847 	return(error);
848 }
849 
850 /*
851  * MPSAFE
852  */
853 int
854 vop_strategy(struct vop_ops *ops, struct vnode *vp, struct bio *bio)
855 {
856 	struct vop_strategy_args ap;
857 	VFS_MPLOCK_DECLARE;
858 	int error;
859 
860 	ap.a_head.a_desc = &vop_strategy_desc;
861 	ap.a_head.a_ops = ops;
862 	ap.a_vp = vp;
863 	ap.a_bio = bio;
864 
865 	if (vp->v_mount) {
866 		VFS_MPLOCK_FLAG(vp->v_mount, MNTK_SG_MPSAFE);
867 		DO_OPS(ops, error, &ap, vop_strategy);
868 		VFS_MPUNLOCK(vp->v_mount);
869 	} else {
870 		/* ugly hack for swap */
871 		get_mplock();
872 		DO_OPS(ops, error, &ap, vop_strategy);
873 		rel_mplock();
874 	}
875 	return(error);
876 }
877 
878 /*
879  * MPSAFE
880  */
881 int
882 vop_print(struct vop_ops *ops, struct vnode *vp)
883 {
884 	struct vop_print_args ap;
885 	VFS_MPLOCK_DECLARE;
886 	int error;
887 
888 	ap.a_head.a_desc = &vop_print_desc;
889 	ap.a_head.a_ops = ops;
890 	ap.a_vp = vp;
891 
892 	VFS_MPLOCK(vp->v_mount);
893 	DO_OPS(ops, error, &ap, vop_print);
894 	VFS_MPUNLOCK(vp->v_mount);
895 	return(error);
896 }
897 
898 /*
899  * MPSAFE
900  */
901 int
902 vop_pathconf(struct vop_ops *ops, struct vnode *vp, int name,
903 	register_t *retval)
904 {
905 	struct vop_pathconf_args ap;
906 	VFS_MPLOCK_DECLARE;
907 	int error;
908 
909 	ap.a_head.a_desc = &vop_pathconf_desc;
910 	ap.a_head.a_ops = ops;
911 	ap.a_vp = vp;
912 	ap.a_name = name;
913 	ap.a_retval = retval;
914 
915 	VFS_MPLOCK(vp->v_mount);
916 	DO_OPS(ops, error, &ap, vop_pathconf);
917 	VFS_MPUNLOCK(vp->v_mount);
918 	return(error);
919 }
920 
921 /*
922  * MPSAFE
923  */
924 int
925 vop_advlock(struct vop_ops *ops, struct vnode *vp, caddr_t id, int op,
926 	struct flock *fl, int flags)
927 {
928 	struct vop_advlock_args ap;
929 	VFS_MPLOCK_DECLARE;
930 	int error;
931 
932 	ap.a_head.a_desc = &vop_advlock_desc;
933 	ap.a_head.a_ops = ops;
934 	ap.a_vp = vp;
935 	ap.a_id = id;
936 	ap.a_op = op;
937 	ap.a_fl = fl;
938 	ap.a_flags = flags;
939 
940 	VFS_MPLOCK(vp->v_mount);
941 	DO_OPS(ops, error, &ap, vop_advlock);
942 	VFS_MPUNLOCK(vp->v_mount);
943 	return(error);
944 }
945 
946 /*
947  * MPSAFE
948  */
949 int
950 vop_balloc(struct vop_ops *ops, struct vnode *vp, off_t startoffset,
951 	int size, struct ucred *cred, int flags,
952 	struct buf **bpp)
953 {
954 	struct vop_balloc_args ap;
955 	VFS_MPLOCK_DECLARE;
956 	int error;
957 
958 	ap.a_head.a_desc = &vop_balloc_desc;
959 	ap.a_head.a_ops = ops;
960 	ap.a_vp = vp;
961 	ap.a_startoffset = startoffset;
962 	ap.a_size = size;
963 	ap.a_cred = cred;
964 	ap.a_flags = flags;
965 	ap.a_bpp = bpp;
966 
967 	VFS_MPLOCK(vp->v_mount);
968 	DO_OPS(ops, error, &ap, vop_balloc);
969 	VFS_MPUNLOCK(vp->v_mount);
970 	return(error);
971 }
972 
973 /*
974  * MPSAFE
975  */
976 int
977 vop_reallocblks(struct vop_ops *ops, struct vnode *vp,
978 	struct cluster_save *buflist)
979 {
980 	struct vop_reallocblks_args ap;
981 	VFS_MPLOCK_DECLARE;
982 	int error;
983 
984 	ap.a_head.a_desc = &vop_reallocblks_desc;
985 	ap.a_head.a_ops = ops;
986 	ap.a_vp = vp;
987 	ap.a_buflist = buflist;
988 
989 	VFS_MPLOCK(vp->v_mount);
990 	DO_OPS(ops, error, &ap, vop_reallocblks);
991 	VFS_MPUNLOCK(vp->v_mount);
992 	return(error);
993 }
994 
995 /*
996  * MPSAFE
997  */
998 int
999 vop_getpages(struct vop_ops *ops, struct vnode *vp, vm_page_t *m, int count,
1000 	int reqpage, vm_ooffset_t offset, int seqaccess)
1001 {
1002 	struct vop_getpages_args ap;
1003 	VFS_MPLOCK_DECLARE;
1004 	int error;
1005 
1006 	ap.a_head.a_desc = &vop_getpages_desc;
1007 	ap.a_head.a_ops = ops;
1008 	ap.a_vp = vp;
1009 	ap.a_m = m;
1010 	ap.a_count = count;
1011 	ap.a_reqpage = reqpage;
1012 	ap.a_offset = offset;
1013 	ap.a_seqaccess = seqaccess;
1014 
1015 	VFS_MPLOCK(vp->v_mount);
1016 	DO_OPS(ops, error, &ap, vop_getpages);
1017 	VFS_MPUNLOCK(vp->v_mount);
1018 	return(error);
1019 }
1020 
1021 /*
1022  * MPSAFE
1023  */
1024 int
1025 vop_putpages(struct vop_ops *ops, struct vnode *vp, vm_page_t *m, int count,
1026 	int sync, int *rtvals, vm_ooffset_t offset)
1027 {
1028 	struct vop_putpages_args ap;
1029 	VFS_MPLOCK_DECLARE;
1030 	int error;
1031 
1032 	ap.a_head.a_desc = &vop_putpages_desc;
1033 	ap.a_head.a_ops = ops;
1034 	ap.a_vp = vp;
1035 	ap.a_m = m;
1036 	ap.a_count = count;
1037 	ap.a_sync = sync;
1038 	ap.a_rtvals = rtvals;
1039 	ap.a_offset = offset;
1040 
1041 	VFS_MPLOCK(vp->v_mount);
1042 	DO_OPS(ops, error, &ap, vop_putpages);
1043 	VFS_MPUNLOCK(vp->v_mount);
1044 	return(error);
1045 }
1046 
1047 /*
1048  * MPSAFE
1049  */
1050 int
1051 vop_freeblks(struct vop_ops *ops, struct vnode *vp, off_t offset, int length)
1052 {
1053 	struct vop_freeblks_args ap;
1054 	VFS_MPLOCK_DECLARE;
1055 	int error;
1056 
1057 	ap.a_head.a_desc = &vop_freeblks_desc;
1058 	ap.a_head.a_ops = ops;
1059 	ap.a_vp = vp;
1060 	ap.a_offset = offset;
1061 	ap.a_length = length;
1062 
1063 	VFS_MPLOCK(vp->v_mount);
1064 	DO_OPS(ops, error, &ap, vop_freeblks);
1065 	VFS_MPUNLOCK(vp->v_mount);
1066 	return(error);
1067 }
1068 
1069 /*
1070  * MPSAFE
1071  */
1072 int
1073 vop_getacl(struct vop_ops *ops, struct vnode *vp, acl_type_t type,
1074 	struct acl *aclp, struct ucred *cred)
1075 {
1076 	struct vop_getacl_args ap;
1077 	VFS_MPLOCK_DECLARE;
1078 	int error;
1079 
1080 	ap.a_head.a_desc = &vop_getacl_desc;
1081 	ap.a_head.a_ops = ops;
1082 	ap.a_vp = vp;
1083 	ap.a_type = type;
1084 	ap.a_aclp = aclp;
1085 	ap.a_cred = cred;
1086 
1087 	VFS_MPLOCK(vp->v_mount);
1088 	DO_OPS(ops, error, &ap, vop_getacl);
1089 	VFS_MPUNLOCK(vp->v_mount);
1090 	return(error);
1091 }
1092 
1093 /*
1094  * MPSAFE
1095  */
1096 int
1097 vop_setacl(struct vop_ops *ops, struct vnode *vp, acl_type_t type,
1098 	struct acl *aclp, struct ucred *cred)
1099 {
1100 	struct vop_setacl_args ap;
1101 	VFS_MPLOCK_DECLARE;
1102 	int error;
1103 
1104 	ap.a_head.a_desc = &vop_setacl_desc;
1105 	ap.a_head.a_ops = ops;
1106 	ap.a_vp = vp;
1107 	ap.a_type = type;
1108 	ap.a_aclp = aclp;
1109 	ap.a_cred = cred;
1110 
1111 	VFS_MPLOCK(vp->v_mount);
1112 	DO_OPS(ops, error, &ap, vop_setacl);
1113 	VFS_MPUNLOCK(vp->v_mount);
1114 	return(error);
1115 }
1116 
1117 /*
1118  * MPSAFE
1119  */
1120 int
1121 vop_aclcheck(struct vop_ops *ops, struct vnode *vp, acl_type_t type,
1122 	struct acl *aclp, struct ucred *cred)
1123 {
1124 	struct vop_aclcheck_args ap;
1125 	VFS_MPLOCK_DECLARE;
1126 	int error;
1127 
1128 	ap.a_head.a_desc = &vop_aclcheck_desc;
1129 	ap.a_head.a_ops = ops;
1130 	ap.a_vp = vp;
1131 	ap.a_type = type;
1132 	ap.a_aclp = aclp;
1133 	ap.a_cred = cred;
1134 
1135 	VFS_MPLOCK(vp->v_mount);
1136 	DO_OPS(ops, error, &ap, vop_aclcheck);
1137 	VFS_MPUNLOCK(vp->v_mount);
1138 	return(error);
1139 }
1140 
1141 /*
1142  * MPSAFE
1143  */
1144 int
1145 vop_getextattr(struct vop_ops *ops, struct vnode *vp, int attrnamespace,
1146 	       char *attrname, struct uio *uio, struct ucred *cred)
1147 {
1148 	struct vop_getextattr_args ap;
1149 	VFS_MPLOCK_DECLARE;
1150 	int error;
1151 
1152 	ap.a_head.a_desc = &vop_getextattr_desc;
1153 	ap.a_head.a_ops = ops;
1154 	ap.a_vp = vp;
1155 	ap.a_attrnamespace = attrnamespace;
1156 	ap.a_attrname = attrname;
1157 	ap.a_uio = uio;
1158 	ap.a_cred = cred;
1159 
1160 	VFS_MPLOCK(vp->v_mount);
1161 	DO_OPS(ops, error, &ap, vop_getextattr);
1162 	VFS_MPUNLOCK(vp->v_mount);
1163 	return(error);
1164 }
1165 
1166 /*
1167  * MPSAFE
1168  */
1169 int
1170 vop_setextattr(struct vop_ops *ops, struct vnode *vp, int attrnamespace,
1171 	       char *attrname, struct uio *uio, struct ucred *cred)
1172 {
1173 	struct vop_setextattr_args ap;
1174 	VFS_MPLOCK_DECLARE;
1175 	int error;
1176 
1177 	ap.a_head.a_desc = &vop_setextattr_desc;
1178 	ap.a_head.a_ops = ops;
1179 	ap.a_vp = vp;
1180 	ap.a_attrnamespace = attrnamespace;
1181 	ap.a_attrname = attrname;
1182 	ap.a_uio = uio;
1183 	ap.a_cred = cred;
1184 
1185 	VFS_MPLOCK(vp->v_mount);
1186 	DO_OPS(ops, error, &ap, vop_setextattr);
1187 	VFS_MPUNLOCK(vp->v_mount);
1188 	return(error);
1189 }
1190 
1191 /*
1192  * MPSAFE
1193  */
1194 int
1195 vop_mountctl(struct vop_ops *ops, struct vnode *vp, int op, struct file *fp,
1196 	     const void *ctl, int ctllen, void *buf, int buflen, int *res)
1197 {
1198 	struct vop_mountctl_args ap;
1199 	VFS_MPLOCK_DECLARE;
1200 	int error;
1201 
1202 	ap.a_head.a_desc = &vop_mountctl_desc;
1203 	ap.a_head.a_ops = ops;
1204 	ap.a_op = op;
1205 	ap.a_ctl = ctl;
1206 	ap.a_fp = fp;
1207 	ap.a_ctllen = ctllen;
1208 	ap.a_buf = buf;
1209 	ap.a_buflen = buflen;
1210 	ap.a_res = res;
1211 
1212 	VFS_MPLOCK(vp->v_mount);
1213 	DO_OPS(ops, error, &ap, vop_mountctl);
1214 	VFS_MPUNLOCK(vp->v_mount);
1215 	return(error);
1216 }
1217 
1218 /*
1219  * MPSAFE
1220  */
1221 int
1222 vop_markatime(struct vop_ops *ops, struct vnode *vp, struct ucred *cred)
1223 {
1224 	struct vop_markatime_args ap;
1225 	VFS_MPLOCK_DECLARE;
1226 	int error;
1227 
1228 	ap.a_head.a_desc = &vop_markatime_desc;
1229 	ap.a_head.a_ops = ops;
1230 	ap.a_vp = vp;
1231 	ap.a_cred = cred;
1232 
1233 	VFS_MPLOCK(vp->v_mount);
1234 	DO_OPS(ops, error, &ap, vop_markatime);
1235 	VFS_MPUNLOCK(vp->v_mount);
1236 	return(error);
1237 }
1238 
1239 /*
1240  * NEW API FUNCTIONS
1241  *
1242  * nresolve takes a locked ncp, a referenced but unlocked dvp, and a cred,
1243  * and resolves the ncp into a positive or negative hit.
1244  *
1245  * The namecache is automatically adjusted by this function.  The ncp
1246  * is left locked on return.
1247  *
1248  * MPSAFE
1249  */
1250 int
1251 vop_nresolve(struct vop_ops *ops, struct nchandle *nch,
1252 	     struct vnode *dvp, struct ucred *cred)
1253 {
1254 	struct vop_nresolve_args ap;
1255 	VFS_MPLOCK_DECLARE;
1256 	int error;
1257 
1258 	ap.a_head.a_desc = &vop_nresolve_desc;
1259 	ap.a_head.a_ops = ops;
1260 	ap.a_nch = nch;
1261 	ap.a_dvp = dvp;
1262 	ap.a_cred = cred;
1263 
1264 	VFS_MPLOCK(dvp->v_mount);
1265 	DO_OPS(ops, error, &ap, vop_nresolve);
1266 	VFS_MPUNLOCK(dvp->v_mount);
1267 	return(error);
1268 }
1269 
1270 /*
1271  * nlookupdotdot takes an unlocked directory, referenced dvp, and looks
1272  * up "..", returning a locked parent directory in *vpp.  If an error
1273  * occurs *vpp will be NULL.
1274  *
1275  * MPSAFE
1276  */
1277 int
1278 vop_nlookupdotdot(struct vop_ops *ops, struct vnode *dvp,
1279 	struct vnode **vpp, struct ucred *cred, char **fakename)
1280 {
1281 	struct vop_nlookupdotdot_args ap;
1282 	VFS_MPLOCK_DECLARE;
1283 	int error;
1284 
1285 	ap.a_head.a_desc = &vop_nlookupdotdot_desc;
1286 	ap.a_head.a_ops = ops;
1287 	ap.a_dvp = dvp;
1288 	ap.a_vpp = vpp;
1289 	ap.a_cred = cred;
1290 	ap.a_fakename = fakename;
1291 
1292 	VFS_MPLOCK(dvp->v_mount);
1293 	DO_OPS(ops, error, &ap, vop_nlookupdotdot);
1294 	VFS_MPUNLOCK(dvp->v_mount);
1295 	return(error);
1296 }
1297 
1298 /*
1299  * ncreate takes a locked, resolved ncp that typically represents a negative
1300  * cache hit and creates the file or node specified by the ncp, cred, and
1301  * vattr.  If no error occurs a locked vnode is returned in *vpp.
1302  *
1303  * The dvp passed in is referenced but unlocked.
1304  *
1305  * The namecache is automatically adjusted by this function.  The ncp
1306  * is left locked on return.
1307  *
1308  * MPSAFE
1309  */
1310 int
1311 vop_ncreate(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp,
1312 	struct vnode **vpp, struct ucred *cred, struct vattr *vap)
1313 {
1314 	struct vop_ncreate_args ap;
1315 	VFS_MPLOCK_DECLARE;
1316 	int error;
1317 
1318 	ap.a_head.a_desc = &vop_ncreate_desc;
1319 	ap.a_head.a_ops = ops;
1320 	ap.a_nch = nch;
1321 	ap.a_dvp = dvp;
1322 	ap.a_vpp = vpp;
1323 	ap.a_cred = cred;
1324 	ap.a_vap = vap;
1325 
1326 	VFS_MPLOCK(dvp->v_mount);
1327 	DO_OPS(ops, error, &ap, vop_ncreate);
1328 	VFS_MPUNLOCK(dvp->v_mount);
1329 	return(error);
1330 }
1331 
1332 /*
1333  * nmkdir takes a locked, resolved ncp that typically represents a negative
1334  * cache hit and creates the directory specified by the ncp, cred, and
1335  * vattr.  If no error occurs a locked vnode is returned in *vpp.
1336  *
1337  * The dvp passed in is referenced but unlocked.
1338  *
1339  * The namecache is automatically adjusted by this function.  The ncp
1340  * is left locked on return.
1341  *
1342  * MPSAFE
1343  */
1344 int
1345 vop_nmkdir(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp,
1346 	struct vnode **vpp, struct ucred *cred, struct vattr *vap)
1347 {
1348 	struct vop_nmkdir_args ap;
1349 	VFS_MPLOCK_DECLARE;
1350 	int error;
1351 
1352 	ap.a_head.a_desc = &vop_nmkdir_desc;
1353 	ap.a_head.a_ops = ops;
1354 	ap.a_nch = nch;
1355 	ap.a_dvp = dvp;
1356 	ap.a_vpp = vpp;
1357 	ap.a_cred = cred;
1358 	ap.a_vap = vap;
1359 
1360 	VFS_MPLOCK(dvp->v_mount);
1361 	DO_OPS(ops, error, &ap, vop_nmkdir);
1362 	VFS_MPUNLOCK(dvp->v_mount);
1363 	return(error);
1364 }
1365 
1366 /*
1367  * nmknod takes a locked, resolved ncp that typically represents a negative
1368  * cache hit and creates the node specified by the ncp, cred, and
1369  * vattr.  If no error occurs a locked vnode is returned in *vpp.
1370  *
1371  * The dvp passed in is referenced but unlocked.
1372  *
1373  * The namecache is automatically adjusted by this function.  The ncp
1374  * is left locked on return.
1375  *
1376  * MPSAFE
1377  */
1378 int
1379 vop_nmknod(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp,
1380 	struct vnode **vpp, struct ucred *cred, struct vattr *vap)
1381 {
1382 	struct vop_nmknod_args ap;
1383 	VFS_MPLOCK_DECLARE;
1384 	int error;
1385 
1386 	ap.a_head.a_desc = &vop_nmknod_desc;
1387 	ap.a_head.a_ops = ops;
1388 	ap.a_nch = nch;
1389 	ap.a_dvp = dvp;
1390 	ap.a_vpp = vpp;
1391 	ap.a_cred = cred;
1392 	ap.a_vap = vap;
1393 
1394 	VFS_MPLOCK(dvp->v_mount);
1395 	DO_OPS(ops, error, &ap, vop_nmknod);
1396 	VFS_MPUNLOCK(dvp->v_mount);
1397 	return(error);
1398 }
1399 
1400 /*
1401  * nlink takes a locked, resolved ncp that typically represents a negative
1402  * cache hit and creates the node specified by the ncp, cred, and
1403  * existing vnode.  The passed vp must be locked and will remain locked
1404  * on return, as does the ncp, whether an error occurs or not.
1405  *
1406  * The dvp passed in is referenced but unlocked.
1407  *
1408  * The namecache is automatically adjusted by this function.  The ncp
1409  * is left locked on return.
1410  *
1411  * MPSAFE
1412  */
1413 int
1414 vop_nlink(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp,
1415 	  struct vnode *vp, struct ucred *cred)
1416 {
1417 	struct vop_nlink_args ap;
1418 	VFS_MPLOCK_DECLARE;
1419 	int error;
1420 
1421 	ap.a_head.a_desc = &vop_nlink_desc;
1422 	ap.a_head.a_ops = ops;
1423 	ap.a_nch = nch;
1424 	ap.a_dvp = dvp;
1425 	ap.a_vp = vp;
1426 	ap.a_cred = cred;
1427 
1428 	VFS_MPLOCK(dvp->v_mount);
1429 	DO_OPS(ops, error, &ap, vop_nlink);
1430 	VFS_MPUNLOCK(dvp->v_mount);
1431 	return(error);
1432 }
1433 
1434 /*
1435  * nsymlink takes a locked, resolved ncp that typically represents a negative
1436  * cache hit and creates a symbolic link based on cred, vap, and target (the
1437  * contents of the link).  If no error occurs a locked vnode is returned in
1438  * *vpp.
1439  *
1440  * The dvp passed in is referenced but unlocked.
1441  *
1442  * The namecache is automatically adjusted by this function.  The ncp
1443  * is left locked on return.
1444  *
1445  * MPSAFE
1446  */
1447 int
1448 vop_nsymlink(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp,
1449 	struct vnode **vpp, struct ucred *cred,
1450 	struct vattr *vap, char *target)
1451 {
1452 	struct vop_nsymlink_args ap;
1453 	VFS_MPLOCK_DECLARE;
1454 	int error;
1455 
1456 	ap.a_head.a_desc = &vop_nsymlink_desc;
1457 	ap.a_head.a_ops = ops;
1458 	ap.a_nch = nch;
1459 	ap.a_dvp = dvp;
1460 	ap.a_vpp = vpp;
1461 	ap.a_cred = cred;
1462 	ap.a_vap = vap;
1463 	ap.a_target = target;
1464 
1465 	VFS_MPLOCK(dvp->v_mount);
1466 	DO_OPS(ops, error, &ap, vop_nsymlink);
1467 	VFS_MPUNLOCK(dvp->v_mount);
1468 	return(error);
1469 }
1470 
1471 /*
1472  * nwhiteout takes a locked, resolved ncp that can represent a positive or
1473  * negative hit and executes the whiteout function specified in flags.
1474  *
1475  * The dvp passed in is referenced but unlocked.
1476  *
1477  * The namecache is automatically adjusted by this function.  The ncp
1478  * is left locked on return.
1479  *
1480  * MPSAFE
1481  */
1482 int
1483 vop_nwhiteout(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp,
1484 	struct ucred *cred, int flags)
1485 {
1486 	struct vop_nwhiteout_args ap;
1487 	VFS_MPLOCK_DECLARE;
1488 	int error;
1489 
1490 	ap.a_head.a_desc = &vop_nwhiteout_desc;
1491 	ap.a_head.a_ops = ops;
1492 	ap.a_nch = nch;
1493 	ap.a_dvp = dvp;
1494 	ap.a_cred = cred;
1495 	ap.a_flags = flags;
1496 
1497 	VFS_MPLOCK(dvp->v_mount);
1498 	DO_OPS(ops, error, &ap, vop_nwhiteout);
1499 	VFS_MPUNLOCK(dvp->v_mount);
1500 	return(error);
1501 }
1502 
1503 /*
1504  * nremove takes a locked, resolved ncp that generally represents a
1505  * positive hit and removes the file.
1506  *
1507  * The dvp passed in is referenced but unlocked.
1508  *
1509  * The namecache is automatically adjusted by this function.  The ncp
1510  * is left locked on return.
1511  *
1512  * MPSAFE
1513  */
1514 int
1515 vop_nremove(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp,
1516 	    struct ucred *cred)
1517 {
1518 	struct vop_nremove_args ap;
1519 	VFS_MPLOCK_DECLARE;
1520 	int error;
1521 	struct vattr va;
1522 
1523 	ap.a_head.a_desc = &vop_nremove_desc;
1524 	ap.a_head.a_ops = ops;
1525 	ap.a_nch = nch;
1526 	ap.a_dvp = dvp;
1527 	ap.a_cred = cred;
1528 
1529 	if ((error = VOP_GETATTR(nch->ncp->nc_vp, &va)) != 0)
1530 		return (error);
1531 
1532 	VFS_MPLOCK(dvp->v_mount);
1533 	DO_OPS(ops, error, &ap, vop_nremove);
1534 	/* Only update space counters if this is the last hard link */
1535 	if ((error == 0) && (va.va_nlink == 1)) {
1536 		VFS_ACCOUNT(nch->mount, va.va_uid, va.va_gid, -va.va_size);
1537 	}
1538 	VFS_MPUNLOCK(dvp->v_mount);
1539 	return(error);
1540 }
1541 
1542 /*
1543  * nrmdir takes a locked, resolved ncp that generally represents a
1544  * directory and removes the directory.
1545  *
1546  * The dvp passed in is referenced but unlocked.
1547  *
1548  * The namecache is automatically adjusted by this function.  The ncp
1549  * is left locked on return.
1550  *
1551  * MPSAFE
1552  */
1553 int
1554 vop_nrmdir(struct vop_ops *ops, struct nchandle *nch, struct vnode *dvp,
1555 	   struct ucred *cred)
1556 {
1557 	struct vop_nrmdir_args ap;
1558 	VFS_MPLOCK_DECLARE;
1559 	int error;
1560 
1561 	ap.a_head.a_desc = &vop_nrmdir_desc;
1562 	ap.a_head.a_ops = ops;
1563 	ap.a_nch = nch;
1564 	ap.a_dvp = dvp;
1565 	ap.a_cred = cred;
1566 
1567 	VFS_MPLOCK(dvp->v_mount);
1568 	DO_OPS(ops, error, &ap, vop_nrmdir);
1569 	VFS_MPUNLOCK(dvp->v_mount);
1570 	return(error);
1571 }
1572 
1573 /*
1574  * nrename takes TWO locked, resolved ncp's and the cred of the caller
1575  * and renames the source ncp to the target ncp.  The target ncp may
1576  * represent a positive or negative hit.
1577  *
1578  * The fdvp and tdvp passed in are referenced but unlocked.
1579  *
1580  * The namecache is automatically adjusted by this function.  The ncp
1581  * is left locked on return.  The source ncp is typically changed to
1582  * a negative cache hit and the target ncp typically takes on the
1583  * source ncp's underlying file.
1584  *
1585  * MPSAFE
1586  */
1587 int
1588 vop_nrename(struct vop_ops *ops,
1589 	    struct nchandle *fnch, struct nchandle *tnch,
1590 	    struct vnode *fdvp, struct vnode *tdvp,
1591 	    struct ucred *cred)
1592 {
1593 	struct vop_nrename_args ap;
1594 	VFS_MPLOCK_DECLARE;
1595 	int error;
1596 
1597 	ap.a_head.a_desc = &vop_nrename_desc;
1598 	ap.a_head.a_ops = ops;
1599 	ap.a_fnch = fnch;
1600 	ap.a_tnch = tnch;
1601 	ap.a_fdvp = fdvp;
1602 	ap.a_tdvp = tdvp;
1603 	ap.a_cred = cred;
1604 
1605 	VFS_MPLOCK(fdvp->v_mount);
1606 	DO_OPS(ops, error, &ap, vop_nrename);
1607 	VFS_MPUNLOCK(fdvp->v_mount);
1608 	return(error);
1609 }
1610 
1611 /************************************************************************
1612  *		PRIMARY VNODE OPERATIONS FORWARDING CALLS		*
1613  ************************************************************************
1614  *
1615  * These procedures are called from VFSs such as nullfs
1616  * when they wish to forward an operation on one VFS to another.  The
1617  * argument structure/message is modified and then directly passed to the
1618  * appropriate routine.  This routines may also be called by initiators
1619  * who have an argument structure in hand rather then discreet arguments.
1620  *
1621  * MPSAFE - Caller expected to already hold the appropriate vfs lock.
1622  */
1623 int
1624 vop_vnoperate_ap(struct vop_generic_args *ap)
1625 {
1626 	struct vop_ops *ops;
1627 	int error;
1628 
1629 	ops = ap->a_ops;
1630 	error = VOCALL(ops, ap);
1631 
1632 	return (error);
1633 }
1634 
1635 /*
1636  * This routine is called by the cache coherency layer to execute the actual
1637  * VFS operation.  If a journaling layer is present we call though it, else
1638  * we call the native VOP functions.
1639  */
1640 int
1641 vop_cache_operate_ap(struct vop_generic_args *ap)
1642 {
1643 	struct vop_ops *ops;
1644 	int error;
1645 
1646 	ops = ap->a_ops;
1647 	if (ops->head.vv_mount->mnt_vn_journal_ops)
1648 		error = VOCALL(ops->head.vv_mount->mnt_vn_journal_ops, ap);
1649 	else
1650 		error = VOCALL(ops->head.vv_mount->mnt_vn_norm_ops, ap);
1651 	return (error);
1652 }
1653 
1654 
1655 /*
1656  * This routine is called by the journaling layer to execute the actual
1657  * VFS operation.
1658  */
1659 int
1660 vop_journal_operate_ap(struct vop_generic_args *ap)
1661 {
1662 	struct vop_ops *ops;
1663 	int error;
1664 
1665 	ops = ap->a_ops;
1666 	error = VOCALL(ops->head.vv_mount->mnt_vn_norm_ops, ap);
1667 
1668 	return (error);
1669 }
1670 
1671 int
1672 vop_open_ap(struct vop_open_args *ap)
1673 {
1674 	int error;
1675 
1676 	DO_OPS(ap->a_head.a_ops, error, ap, vop_open);
1677 	return(error);
1678 }
1679 
1680 int
1681 vop_close_ap(struct vop_close_args *ap)
1682 {
1683 	int error;
1684 
1685 	DO_OPS(ap->a_head.a_ops, error, ap, vop_close);
1686 	return(error);
1687 }
1688 
1689 int
1690 vop_access_ap(struct vop_access_args *ap)
1691 {
1692 	int error;
1693 
1694 	DO_OPS(ap->a_head.a_ops, error, ap, vop_access);
1695 	return(error);
1696 }
1697 
1698 int
1699 vop_getattr_ap(struct vop_getattr_args *ap)
1700 {
1701 	int error;
1702 
1703 	DO_OPS(ap->a_head.a_ops, error, ap, vop_getattr);
1704 	return(error);
1705 }
1706 
1707 int
1708 vop_setattr_ap(struct vop_setattr_args *ap)
1709 {
1710 	int error;
1711 
1712 	DO_OPS(ap->a_head.a_ops, error, ap, vop_setattr);
1713 	return(error);
1714 }
1715 
1716 int
1717 vop_read_ap(struct vop_read_args *ap)
1718 {
1719 	int error;
1720 
1721 	DO_OPS(ap->a_head.a_ops, error, ap, vop_read);
1722 	return(error);
1723 }
1724 
1725 int
1726 vop_write_ap(struct vop_write_args *ap)
1727 {
1728 	int error;
1729 
1730 	DO_OPS(ap->a_head.a_ops, error, ap, vop_write);
1731 	return(error);
1732 }
1733 
1734 int
1735 vop_ioctl_ap(struct vop_ioctl_args *ap)
1736 {
1737 	int error;
1738 
1739 	DO_OPS(ap->a_head.a_ops, error, ap, vop_ioctl);
1740 	return(error);
1741 }
1742 
1743 int
1744 vop_poll_ap(struct vop_poll_args *ap)
1745 {
1746 	int error;
1747 
1748 	DO_OPS(ap->a_head.a_ops, error, ap, vop_poll);
1749 	return(error);
1750 }
1751 
1752 int
1753 vop_kqfilter_ap(struct vop_kqfilter_args *ap)
1754 {
1755 	int error;
1756 
1757 	DO_OPS(ap->a_head.a_ops, error, ap, vop_kqfilter);
1758 	return(error);
1759 }
1760 
1761 int
1762 vop_mmap_ap(struct vop_mmap_args *ap)
1763 {
1764 	int error;
1765 
1766 	DO_OPS(ap->a_head.a_ops, error, ap, vop_mmap);
1767 	return(error);
1768 }
1769 
1770 int
1771 vop_fsync_ap(struct vop_fsync_args *ap)
1772 {
1773 	int error;
1774 
1775 	DO_OPS(ap->a_head.a_ops, error, ap, vop_fsync);
1776 	return(error);
1777 }
1778 
1779 int
1780 vop_readdir_ap(struct vop_readdir_args *ap)
1781 {
1782 	int error;
1783 
1784 	DO_OPS(ap->a_head.a_ops, error, ap, vop_readdir);
1785 	return(error);
1786 }
1787 
1788 int
1789 vop_readlink_ap(struct vop_readlink_args *ap)
1790 {
1791 	int error;
1792 
1793 	DO_OPS(ap->a_head.a_ops, error, ap, vop_readlink);
1794 	return(error);
1795 }
1796 
1797 int
1798 vop_inactive_ap(struct vop_inactive_args *ap)
1799 {
1800 	int error;
1801 
1802 	DO_OPS(ap->a_head.a_ops, error, ap, vop_inactive);
1803 	return(error);
1804 }
1805 
1806 int
1807 vop_reclaim_ap(struct vop_reclaim_args *ap)
1808 {
1809 	int error;
1810 
1811 	DO_OPS(ap->a_head.a_ops, error, ap, vop_reclaim);
1812 	return(error);
1813 }
1814 
1815 int
1816 vop_bmap_ap(struct vop_bmap_args *ap)
1817 {
1818 	int error;
1819 
1820 	DO_OPS(ap->a_head.a_ops, error, ap, vop_bmap);
1821 	return(error);
1822 }
1823 
1824 int
1825 vop_strategy_ap(struct vop_strategy_args *ap)
1826 {
1827 	int error;
1828 
1829 	DO_OPS(ap->a_head.a_ops, error, ap, vop_strategy);
1830 	return(error);
1831 }
1832 
1833 int
1834 vop_print_ap(struct vop_print_args *ap)
1835 {
1836 	int error;
1837 
1838 	DO_OPS(ap->a_head.a_ops, error, ap, vop_print);
1839 	return(error);
1840 }
1841 
1842 int
1843 vop_pathconf_ap(struct vop_pathconf_args *ap)
1844 {
1845 	int error;
1846 
1847 	DO_OPS(ap->a_head.a_ops, error, ap, vop_pathconf);
1848 	return(error);
1849 }
1850 
1851 int
1852 vop_advlock_ap(struct vop_advlock_args *ap)
1853 {
1854 	int error;
1855 
1856 	DO_OPS(ap->a_head.a_ops, error, ap, vop_advlock);
1857 	return(error);
1858 }
1859 
1860 int
1861 vop_balloc_ap(struct vop_balloc_args *ap)
1862 {
1863 	int error;
1864 
1865 	DO_OPS(ap->a_head.a_ops, error, ap, vop_balloc);
1866 	return(error);
1867 }
1868 
1869 int
1870 vop_reallocblks_ap(struct vop_reallocblks_args *ap)
1871 {
1872 	int error;
1873 
1874 	DO_OPS(ap->a_head.a_ops, error, ap, vop_reallocblks);
1875 	return(error);
1876 }
1877 
1878 int
1879 vop_getpages_ap(struct vop_getpages_args *ap)
1880 {
1881 	int error;
1882 
1883 	DO_OPS(ap->a_head.a_ops, error, ap, vop_getpages);
1884 	return(error);
1885 }
1886 
1887 int
1888 vop_putpages_ap(struct vop_putpages_args *ap)
1889 {
1890 	int error;
1891 
1892 	DO_OPS(ap->a_head.a_ops, error, ap, vop_putpages);
1893 	return(error);
1894 }
1895 
1896 int
1897 vop_freeblks_ap(struct vop_freeblks_args *ap)
1898 {
1899 	int error;
1900 
1901 	DO_OPS(ap->a_head.a_ops, error, ap, vop_freeblks);
1902 	return(error);
1903 }
1904 
1905 int
1906 vop_getacl_ap(struct vop_getacl_args *ap)
1907 {
1908 	int error;
1909 
1910 	DO_OPS(ap->a_head.a_ops, error, ap, vop_getacl);
1911 	return(error);
1912 }
1913 
1914 int
1915 vop_setacl_ap(struct vop_setacl_args *ap)
1916 {
1917 	int error;
1918 
1919 	DO_OPS(ap->a_head.a_ops, error, ap, vop_setacl);
1920 	return(error);
1921 }
1922 
1923 int
1924 vop_aclcheck_ap(struct vop_aclcheck_args *ap)
1925 {
1926 	int error;
1927 
1928 	DO_OPS(ap->a_head.a_ops, error, ap, vop_aclcheck);
1929 	return(error);
1930 }
1931 
1932 int
1933 vop_getextattr_ap(struct vop_getextattr_args *ap)
1934 {
1935 	int error;
1936 
1937 	DO_OPS(ap->a_head.a_ops, error, ap, vop_getextattr);
1938 	return(error);
1939 }
1940 
1941 int
1942 vop_setextattr_ap(struct vop_setextattr_args *ap)
1943 {
1944 	int error;
1945 
1946 	DO_OPS(ap->a_head.a_ops, error, ap, vop_setextattr);
1947 	return(error);
1948 }
1949 
1950 int
1951 vop_mountctl_ap(struct vop_mountctl_args *ap)
1952 {
1953 	int error;
1954 
1955 	DO_OPS(ap->a_head.a_ops, error, ap, vop_mountctl);
1956 	return(error);
1957 }
1958 
1959 int
1960 vop_markatime_ap(struct vop_markatime_args *ap)
1961 {
1962 	int error;
1963 
1964 	DO_OPS(ap->a_head.a_ops, error, ap, vop_markatime);
1965 	return(error);
1966 }
1967 
1968 int
1969 vop_nresolve_ap(struct vop_nresolve_args *ap)
1970 {
1971 	int error;
1972 
1973 	DO_OPS(ap->a_head.a_ops, error, ap, vop_nresolve);
1974 	return(error);
1975 }
1976 
1977 int
1978 vop_nlookupdotdot_ap(struct vop_nlookupdotdot_args *ap)
1979 {
1980 	int error;
1981 
1982 	DO_OPS(ap->a_head.a_ops, error, ap, vop_nlookupdotdot);
1983 	return(error);
1984 }
1985 
1986 int
1987 vop_ncreate_ap(struct vop_ncreate_args *ap)
1988 {
1989 	int error;
1990 
1991 	DO_OPS(ap->a_head.a_ops, error, ap, vop_ncreate);
1992 	return(error);
1993 }
1994 
1995 int
1996 vop_nmkdir_ap(struct vop_nmkdir_args *ap)
1997 {
1998 	int error;
1999 
2000 	DO_OPS(ap->a_head.a_ops, error, ap, vop_nmkdir);
2001 	return(error);
2002 }
2003 
2004 int
2005 vop_nmknod_ap(struct vop_nmknod_args *ap)
2006 {
2007 	int error;
2008 
2009 	DO_OPS(ap->a_head.a_ops, error, ap, vop_nmknod);
2010 	return(error);
2011 }
2012 
2013 int
2014 vop_nlink_ap(struct vop_nlink_args *ap)
2015 {
2016 	int error;
2017 
2018 	DO_OPS(ap->a_head.a_ops, error, ap, vop_nlink);
2019 	return(error);
2020 }
2021 
2022 int
2023 vop_nsymlink_ap(struct vop_nsymlink_args *ap)
2024 {
2025 	int error;
2026 
2027 	DO_OPS(ap->a_head.a_ops, error, ap, vop_nsymlink);
2028 	return(error);
2029 }
2030 
2031 int
2032 vop_nwhiteout_ap(struct vop_nwhiteout_args *ap)
2033 {
2034 	int error;
2035 
2036 	DO_OPS(ap->a_head.a_ops, error, ap, vop_nwhiteout);
2037 	return(error);
2038 }
2039 
2040 int
2041 vop_nremove_ap(struct vop_nremove_args *ap)
2042 {
2043 	int error;
2044 
2045 	DO_OPS(ap->a_head.a_ops, error, ap, vop_nremove);
2046 	return(error);
2047 }
2048 
2049 int
2050 vop_nrmdir_ap(struct vop_nrmdir_args *ap)
2051 {
2052 	int error;
2053 
2054 	DO_OPS(ap->a_head.a_ops, error, ap, vop_nrmdir);
2055 	return(error);
2056 }
2057 
2058 int
2059 vop_nrename_ap(struct vop_nrename_args *ap)
2060 {
2061 	int error;
2062 
2063 	DO_OPS(ap->a_head.a_ops, error, ap, vop_nrename);
2064 	return(error);
2065 }
2066 
2067