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