kernel/getsockaddr: Remove a COMPAT_43 removal leftover.
[dragonfly.git] / sys / kern / vfs_vopops.c
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