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