Merge from vendor branch SENDMAIL:
[dragonfly.git] / sys / vfs / union / union_vnops.c
1 /*
2  * Copyright (c) 1992, 1993, 1994, 1995 Jan-Simon Pendry.
3  * Copyright (c) 1992, 1993, 1994, 1995
4  *      The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * Jan-Simon Pendry.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by the University of
20  *      California, Berkeley and its contributors.
21  * 4. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  *      @(#)union_vnops.c       8.32 (Berkeley) 6/23/95
38  * $FreeBSD: src/sys/miscfs/union/union_vnops.c,v 1.72 1999/12/15 23:02:14 eivind Exp $
39  * $DragonFly: src/sys/vfs/union/union_vnops.c,v 1.33 2006/08/12 00:26:22 dillon Exp $
40  */
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/proc.h>
45 #include <sys/fcntl.h>
46 #include <sys/stat.h>
47 #include <sys/kernel.h>
48 #include <sys/vnode.h>
49 #include <sys/mount.h>
50 #include <sys/namei.h>
51 #include <sys/malloc.h>
52 #include <sys/buf.h>
53 #include <sys/lock.h>
54 #include <sys/sysctl.h>
55 #include "union.h"
56
57 #include <vm/vm.h>
58 #include <vm/vnode_pager.h>
59
60 #include <vm/vm_page.h>
61 #include <vm/vm_object.h>
62
63 int uniondebug = 0;
64
65 #if UDEBUG_ENABLED
66 SYSCTL_INT(_vfs, OID_AUTO, uniondebug, CTLFLAG_RW, &uniondebug, 0, "");
67 #else
68 SYSCTL_INT(_vfs, OID_AUTO, uniondebug, CTLFLAG_RD, &uniondebug, 0, "");
69 #endif
70
71 static int      union_access (struct vop_access_args *ap);
72 static int      union_advlock (struct vop_advlock_args *ap);
73 static int      union_bmap (struct vop_bmap_args *ap);
74 static int      union_close (struct vop_close_args *ap);
75 static int      union_create (struct vop_old_create_args *ap);
76 static int      union_fsync (struct vop_fsync_args *ap);
77 static int      union_getattr (struct vop_getattr_args *ap);
78 static int      union_inactive (struct vop_inactive_args *ap);
79 static int      union_ioctl (struct vop_ioctl_args *ap);
80 static int      union_link (struct vop_old_link_args *ap);
81 static int      union_lookup (struct vop_old_lookup_args *ap);
82 static int      union_lookup1 (struct vnode *udvp, struct vnode **dvp,
83                                    struct vnode **vpp,
84                                    struct componentname *cnp);
85 static int      union_mkdir (struct vop_old_mkdir_args *ap);
86 static int      union_mknod (struct vop_old_mknod_args *ap);
87 static int      union_mmap (struct vop_mmap_args *ap);
88 static int      union_open (struct vop_open_args *ap);
89 static int      union_pathconf (struct vop_pathconf_args *ap);
90 static int      union_print (struct vop_print_args *ap);
91 static int      union_read (struct vop_read_args *ap);
92 static int      union_readdir (struct vop_readdir_args *ap);
93 static int      union_readlink (struct vop_readlink_args *ap);
94 static int      union_reclaim (struct vop_reclaim_args *ap);
95 static int      union_remove (struct vop_old_remove_args *ap);
96 static int      union_rename (struct vop_old_rename_args *ap);
97 static int      union_revoke (struct vop_revoke_args *ap);
98 static int      union_rmdir (struct vop_old_rmdir_args *ap);
99 static int      union_poll (struct vop_poll_args *ap);
100 static int      union_setattr (struct vop_setattr_args *ap);
101 static int      union_strategy (struct vop_strategy_args *ap);
102 static int      union_getpages (struct vop_getpages_args *ap);
103 static int      union_putpages (struct vop_putpages_args *ap);
104 static int      union_symlink (struct vop_old_symlink_args *ap);
105 static int      union_whiteout (struct vop_old_whiteout_args *ap);
106 static int      union_write (struct vop_read_args *ap);
107
108 static __inline
109 struct vnode *
110 union_lock_upper(struct union_node *un, struct thread *td)
111 {
112         struct vnode *uppervp;
113
114         if ((uppervp = un->un_uppervp) != NULL) {
115                 vref(uppervp);
116                 vn_lock(uppervp, LK_EXCLUSIVE | LK_CANRECURSE | LK_RETRY);
117         }
118         KASSERT((uppervp == NULL || uppervp->v_usecount > 0), ("uppervp usecount is 0"));
119         return(uppervp);
120 }
121
122 static __inline
123 void
124 union_unlock_upper(struct vnode *uppervp, struct thread *td)
125 {
126         vput(uppervp);
127 }
128
129 static __inline
130 struct vnode *
131 union_lock_other(struct union_node *un, struct thread *td)
132 {
133         struct vnode *vp;
134
135         if (un->un_uppervp != NULL) {
136                 vp = union_lock_upper(un, td);
137         } else if ((vp = un->un_lowervp) != NULL) {
138                 vref(vp);
139                 vn_lock(vp, LK_EXCLUSIVE | LK_CANRECURSE | LK_RETRY);
140         }
141         return(vp);
142 }
143
144 static __inline
145 void
146 union_unlock_other(struct vnode *vp, struct thread *td)
147 {
148         vput(vp);
149 }
150
151 /*
152  *      union_lookup:
153  *
154  *      udvp    must be exclusively locked on call and will remain 
155  *              exclusively locked on return.  This is the mount point 
156  *              for out filesystem.
157  *
158  *      dvp     Our base directory, locked and referenced.
159  *              The passed dvp will be dereferenced and unlocked on return
160  *              and a new dvp will be returned which is locked and 
161  *              referenced in the same variable.
162  *
163  *      vpp     is filled in with the result if no error occured,
164  *              locked and ref'd.
165  *
166  *              If an error is returned, *vpp is set to NULLVP.  If no
167  *              error occurs, *vpp is returned with a reference and an
168  *              exclusive lock.
169  */
170
171 static int
172 union_lookup1(struct vnode *udvp, struct vnode **pdvp, struct vnode **vpp,
173               struct componentname *cnp)
174 {
175         int error;
176         struct thread *td = cnp->cn_td;
177         struct vnode *dvp = *pdvp;
178         struct vnode *tdvp;
179         struct mount *mp;
180
181         /*
182          * If stepping up the directory tree, check for going
183          * back across the mount point, in which case do what
184          * lookup would do by stepping back down the mount
185          * hierarchy.
186          */
187         if (cnp->cn_flags & CNP_ISDOTDOT) {
188                 while ((dvp != udvp) && (dvp->v_flag & VROOT)) {
189                         /*
190                          * Don't do the NOCROSSMOUNT check
191                          * at this level.  By definition,
192                          * union fs deals with namespaces, not
193                          * filesystems.
194                          */
195                         tdvp = dvp;
196                         dvp = dvp->v_mount->mnt_vnodecovered;
197                         vref(dvp);
198                         vput(tdvp);
199                         vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
200                 }
201         }
202
203         /*
204          * Set return dvp to be the upperdvp 'parent directory.
205          */
206         *pdvp = dvp;
207
208         /*
209          * If the VOP_LOOKUP call generates an error, tdvp is invalid and no
210          * changes will have been made to dvp, so we are set to return.
211          */
212
213         error = VOP_LOOKUP(dvp, &tdvp, cnp);
214         if (error) {
215                 UDEBUG(("dvp %p error %d flags %lx\n", dvp, error, cnp->cn_flags));
216                 *vpp = NULL;
217                 return (error);
218         }
219
220         /*
221          * The parent directory will have been unlocked, unless lookup
222          * found the last component or if dvp == tdvp (tdvp must be locked).
223          *
224          * We want our dvp to remain locked and ref'd.  We also want tdvp
225          * to remain locked and ref'd.
226          */
227         UDEBUG(("parentdir %p result %p flag %lx\n", dvp, tdvp, cnp->cn_flags));
228
229 #if 0
230         if (dvp != tdvp && (cnp->cn_flags & CNP_XXXISLASTCN) == 0)
231                 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
232 #endif
233
234         /*
235          * Lastly check if the current node is a mount point in
236          * which case walk up the mount hierarchy making sure not to
237          * bump into the root of the mount tree (ie. dvp != udvp).
238          *
239          * We use dvp as a temporary variable here, it is no longer related
240          * to the dvp above.  However, we have to ensure that both *pdvp and
241          * tdvp are locked on return.
242          */
243
244         dvp = tdvp;
245         while (
246             dvp != udvp && 
247             (dvp->v_type == VDIR) &&
248             (mp = dvp->v_mountedhere)
249         ) {
250                 int relock_pdvp = 0;
251
252                 if (vfs_busy(mp, 0))
253                         continue;
254
255                 if (dvp == *pdvp)
256                         relock_pdvp = 1;
257                 vput(dvp);
258                 dvp = NULL;
259                 error = VFS_ROOT(mp, &dvp);
260
261                 vfs_unbusy(mp);
262
263                 if (relock_pdvp)
264                         vn_lock(*pdvp, LK_EXCLUSIVE | LK_RETRY);
265
266                 if (error) {
267                         *vpp = NULL;
268                         return (error);
269                 }
270         }
271         *vpp = dvp;
272         return (0);
273 }
274
275 /*
276  * union_lookup(struct vnode *a_dvp, struct vnode **a_vpp,
277  *              struct componentname *a_cnp)
278  */
279 static int
280 union_lookup(struct vop_old_lookup_args *ap)
281 {
282         int error;
283         int uerror, lerror;
284         struct vnode *uppervp, *lowervp;
285         struct vnode *upperdvp, *lowerdvp;
286         struct vnode *dvp = ap->a_dvp;          /* starting dir */
287         struct union_node *dun = VTOUNION(dvp); /* associated union node */
288         struct componentname *cnp = ap->a_cnp;
289         struct thread *td = cnp->cn_td;
290         int lockparent = cnp->cn_flags & CNP_LOCKPARENT;
291         struct union_mount *um = MOUNTTOUNIONMOUNT(dvp->v_mount);
292         struct ucred *saved_cred = NULL;
293         int iswhiteout;
294         struct vattr va;
295
296         *ap->a_vpp = NULLVP;
297
298         /*
299          * Disallow write attemps to the filesystem mounted read-only.
300          */
301         if ((dvp->v_mount->mnt_flag & MNT_RDONLY) &&
302             (cnp->cn_nameiop == NAMEI_DELETE || cnp->cn_nameiop == NAMEI_RENAME)) {
303                 return (EROFS);
304         }
305
306         /*
307          * For any lookup's we do, always return with the parent locked
308          */
309         cnp->cn_flags |= CNP_LOCKPARENT;
310
311         lowerdvp = dun->un_lowervp;
312         uppervp = NULLVP;
313         lowervp = NULLVP;
314         iswhiteout = 0;
315
316         uerror = ENOENT;
317         lerror = ENOENT;
318
319         /*
320          * Get a private lock on uppervp and a reference, effectively 
321          * taking it out of the union_node's control.
322          *
323          * We must lock upperdvp while holding our lock on dvp
324          * to avoid a deadlock.
325          */
326         upperdvp = union_lock_upper(dun, td);
327
328         /*
329          * do the lookup in the upper level.
330          * if that level comsumes additional pathnames,
331          * then assume that something special is going
332          * on and just return that vnode.
333          */
334         if (upperdvp != NULLVP) {
335                 /*
336                  * We do not have to worry about the DOTDOT case, we've
337                  * already unlocked dvp.
338                  */
339                 UDEBUG(("A %p\n", upperdvp));
340
341                 /*
342                  * Do the lookup.   We must supply a locked and referenced
343                  * upperdvp to the function and will get a new locked and
344                  * referenced upperdvp back with the old having been 
345                  * dereferenced.
346                  *
347                  * If an error is returned, uppervp will be NULLVP.  If no
348                  * error occurs, uppervp will be the locked and referenced
349                  * return vnode or possibly NULL, depending on what is being
350                  * requested.  It is possible that the returned uppervp
351                  * will be the same as upperdvp.
352                  */
353                 uerror = union_lookup1(um->um_uppervp, &upperdvp, &uppervp, cnp);
354                 UDEBUG((
355                     "uerror %d upperdvp %p %d/%d, uppervp %p ref=%d/lck=%d\n",
356                     uerror,
357                     upperdvp,
358                     upperdvp->v_usecount,
359                     vn_islocked(upperdvp),
360                     uppervp,
361                     (uppervp ? uppervp->v_usecount : -99),
362                     (uppervp ? vn_islocked(uppervp) : -99)
363                 ));
364
365                 /*
366                  * Disallow write attemps to the filesystem mounted read-only.
367                  */
368                 if (uerror == EJUSTRETURN && 
369                     (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
370                     (cnp->cn_nameiop == NAMEI_CREATE || cnp->cn_nameiop == NAMEI_RENAME)) {
371                         error = EROFS;
372                         goto out;
373                 }
374
375                 /*
376                  * Special case.  If cn_consume != 0 skip out.  The result
377                  * of the lookup is transfered to our return variable.  If
378                  * an error occured we have to throw away the results.
379                  */
380
381                 if (cnp->cn_consume != 0) {
382                         if ((error = uerror) == 0) {
383                                 *ap->a_vpp = uppervp;
384                                 uppervp = NULL;
385                         }
386                         goto out;
387                 }
388
389                 /*
390                  * Calculate whiteout, fall through
391                  */
392
393                 if (uerror == ENOENT || uerror == EJUSTRETURN) {
394                         if (cnp->cn_flags & CNP_ISWHITEOUT) {
395                                 iswhiteout = 1;
396                         } else if (lowerdvp != NULLVP) {
397                                 int terror;
398
399                                 terror = VOP_GETATTR(upperdvp, &va);
400                                 if (terror == 0 && (va.va_flags & OPAQUE))
401                                         iswhiteout = 1;
402                         }
403                 }
404         }
405
406         /*
407          * in a similar way to the upper layer, do the lookup
408          * in the lower layer.   this time, if there is some
409          * component magic going on, then vput whatever we got
410          * back from the upper layer and return the lower vnode
411          * instead.
412          */
413
414         if (lowerdvp != NULLVP && !iswhiteout) {
415                 int nameiop;
416
417                 UDEBUG(("B %p\n", lowerdvp));
418
419                 /*
420                  * Force only LOOKUPs on the lower node, since
421                  * we won't be making changes to it anyway.
422                  */
423                 nameiop = cnp->cn_nameiop;
424                 cnp->cn_nameiop = NAMEI_LOOKUP;
425                 if (um->um_op == UNMNT_BELOW) {
426                         saved_cred = cnp->cn_cred;
427                         cnp->cn_cred = um->um_cred;
428                 }
429
430                 /*
431                  * We shouldn't have to worry about locking interactions
432                  * between the lower layer and our union layer (w.r.t.
433                  * `..' processing) because we don't futz with lowervp
434                  * locks in the union-node instantiation code path.
435                  *
436                  * union_lookup1() requires lowervp to be locked on entry,
437                  * and it will be unlocked on return.  The ref count will
438                  * not change.  On return lowervp doesn't represent anything
439                  * to us so we NULL it out.
440                  */
441                 vref(lowerdvp);
442                 vn_lock(lowerdvp, LK_EXCLUSIVE | LK_RETRY);
443                 lerror = union_lookup1(um->um_lowervp, &lowerdvp, &lowervp, cnp);
444                 if (lowerdvp == lowervp)
445                         vrele(lowerdvp);
446                 else
447                         vput(lowerdvp);
448                 lowerdvp = NULL;        /* lowerdvp invalid after vput */
449
450                 if (um->um_op == UNMNT_BELOW)
451                         cnp->cn_cred = saved_cred;
452                 cnp->cn_nameiop = nameiop;
453
454                 if (cnp->cn_consume != 0 || lerror == EACCES) {
455                         if ((error = lerror) == 0) {
456                                 *ap->a_vpp = lowervp;
457                                 lowervp = NULL;
458                         }
459                         goto out;
460                 }
461         } else {
462                 UDEBUG(("C %p\n", lowerdvp));
463                 if ((cnp->cn_flags & CNP_ISDOTDOT) && dun->un_pvp != NULLVP) {
464                         if ((lowervp = LOWERVP(dun->un_pvp)) != NULL) {
465                                 vref(lowervp);
466                                 vn_lock(lowervp, LK_EXCLUSIVE | LK_RETRY);
467                                 lerror = 0;
468                         }
469                 }
470         }
471
472         /*
473          * Ok.  Now we have uerror, uppervp, upperdvp, lerror, and lowervp.
474          *
475          * 1. If both layers returned an error, select the upper layer.
476          *
477          * 2. If the upper layer faile and the bottom layer succeeded,
478          *    two subcases occur:
479          *
480          *      a.  The bottom vnode is not a directory, in which case
481          *          just return a new union vnode referencing an
482          *          empty top layer and the existing bottom layer.
483          *
484          *      b.  The button vnode is a directory, in which case
485          *          create a new directory in the top layer and
486          *          and fall through to case 3.
487          *
488          * 3. If the top layer succeeded then return a new union
489          *    vnode referencing whatever the new top layer and
490          *    whatever the bottom layer returned.
491          */
492
493         /* case 1. */
494         if ((uerror != 0) && (lerror != 0)) {
495                 error = uerror;
496                 goto out;
497         }
498
499         /* case 2. */
500         if (uerror != 0 /* && (lerror == 0) */ ) {
501                 if (lowervp->v_type == VDIR) { /* case 2b. */
502                         KASSERT(uppervp == NULL, ("uppervp unexpectedly non-NULL"));
503                         /*
504                          * oops, uppervp has a problem, we may have to shadow.
505                          */
506                         uerror = union_mkshadow(um, upperdvp, cnp, &uppervp);
507                         if (uerror) {
508                                 error = uerror;
509                                 goto out;
510                         }
511                 }
512         }
513
514         /*
515          * Must call union_allocvp with both the upper and lower vnodes
516          * referenced and the upper vnode locked.   ap->a_vpp is returned 
517          * referenced and locked.  lowervp, uppervp, and upperdvp are 
518          * absorbed by union_allocvp() whether it succeeds or fails.
519          *
520          * upperdvp is the parent directory of uppervp which may be
521          * different, depending on the path, from dvp->un_uppervp.  That's
522          * why it is a separate argument.  Note that it must be unlocked.
523          *
524          * dvp must be locked on entry to the call and will be locked on
525          * return.
526          */
527
528         if (uppervp && uppervp != upperdvp)
529                 vn_unlock(uppervp);
530         if (lowervp)
531                 vn_unlock(lowervp);
532         if (upperdvp)
533                 vn_unlock(upperdvp);
534
535         error = union_allocvp(ap->a_vpp, dvp->v_mount, dvp, upperdvp, cnp,
536                               uppervp, lowervp, 1);
537
538         UDEBUG(("Create %p = %p %p refs=%d\n", *ap->a_vpp, uppervp, lowervp, (*ap->a_vpp) ? ((*ap->a_vpp)->v_usecount) : -99));
539
540         uppervp = NULL;
541         upperdvp = NULL;
542         lowervp = NULL;
543
544         /* 
545          *      Termination Code
546          *
547          *      - put away any extra junk laying around.  Note that lowervp
548          *        (if not NULL) will never be the same as *ap->a_vp and 
549          *        neither will uppervp, because when we set that state we 
550          *        NULL-out lowervp or uppervp.  On the otherhand, upperdvp
551          *        may match uppervp or *ap->a_vpp.
552          *
553          *      - relock/unlock dvp if appropriate.
554          */
555
556 out:
557         if (upperdvp) {
558                 if (upperdvp == uppervp || upperdvp == *ap->a_vpp)
559                         vrele(upperdvp);
560                 else
561                         vput(upperdvp);
562         }
563
564         if (uppervp)
565                 vput(uppervp);
566
567         if (lowervp)
568                 vput(lowervp);
569
570         /*
571          * Restore LOCKPARENT state
572          */
573
574         if (!lockparent)
575                 cnp->cn_flags &= ~CNP_LOCKPARENT;
576
577         UDEBUG(("Out %d vpp %p/%d lower %p upper %p\n", error, *ap->a_vpp,
578                 ((*ap->a_vpp) ? (*ap->a_vpp)->v_usecount : -99),
579                 lowervp, uppervp));
580
581         /*
582          * dvp lock state, determine whether to relock dvp.  dvp is expected
583          * to be locked on return if:
584          *
585          *      - there was an error (except not EJUSTRETURN), or
586          *      - we hit the last component and lockparent is true
587          *
588          * dvp_is_locked is the current state of the dvp lock, not counting
589          * the possibility that *ap->a_vpp == dvp (in which case it is locked
590          * anyway).  Note that *ap->a_vpp == dvp only if no error occured.
591          */
592
593         if (*ap->a_vpp != dvp) {
594                 if ((error == 0 || error == EJUSTRETURN) && !lockparent) {
595                         vn_unlock(dvp);
596                 }
597         }
598
599         /*
600          * Diagnostics
601          */
602
603 #ifdef DIAGNOSTIC
604         if (cnp->cn_namelen == 1 &&
605             cnp->cn_nameptr[0] == '.' &&
606             *ap->a_vpp != dvp) {
607                 panic("union_lookup returning . (%p) not same as startdir (%p)", ap->a_vpp, dvp);
608         }
609 #endif
610
611         return (error);
612 }
613
614 /*
615  *      union_create:
616  *
617  * a_dvp is locked on entry and remains locked on return.  a_vpp is returned
618  * locked if no error occurs, otherwise it is garbage.
619  *
620  * union_create(struct vnode *a_dvp, struct vnode **a_vpp,
621  *              struct componentname *a_cnp, struct vattr *a_vap)
622  */
623 static int
624 union_create(struct vop_old_create_args *ap)
625 {
626         struct union_node *dun = VTOUNION(ap->a_dvp);
627         struct componentname *cnp = ap->a_cnp;
628         struct thread *td = cnp->cn_td;
629         struct vnode *dvp;
630         int error = EROFS;
631
632         if ((dvp = union_lock_upper(dun, td)) != NULL) {
633                 struct vnode *vp;
634                 struct mount *mp;
635
636                 error = VOP_CREATE(dvp, &vp, cnp, ap->a_vap);
637                 if (error == 0) {
638                         mp = ap->a_dvp->v_mount;
639                         vn_unlock(vp);
640                         UDEBUG(("ALLOCVP-1 FROM %p REFS %d\n", vp, vp->v_usecount));
641                         error = union_allocvp(ap->a_vpp, mp, NULLVP, NULLVP,
642                                 cnp, vp, NULLVP, 1);
643                         UDEBUG(("ALLOCVP-2B FROM %p REFS %d\n", *ap->a_vpp, vp->v_usecount));
644                 }
645                 union_unlock_upper(dvp, td);
646         }
647         return (error);
648 }
649
650 /*
651  * union_whiteout(struct vnode *a_dvp, struct componentname *a_cnp,
652  *                int a_flags)
653  */
654 static int
655 union_whiteout(struct vop_old_whiteout_args *ap)
656 {
657         struct union_node *un = VTOUNION(ap->a_dvp);
658         struct componentname *cnp = ap->a_cnp;
659         struct vnode *uppervp;
660         int error = EOPNOTSUPP;
661
662         if ((uppervp = union_lock_upper(un, cnp->cn_td)) != NULLVP) {
663                 error = VOP_WHITEOUT(un->un_uppervp, cnp, ap->a_flags);
664                 union_unlock_upper(uppervp, cnp->cn_td);
665         }
666         return(error);
667 }
668
669 /*
670  *      union_mknod:
671  *
672  *      a_dvp is locked on entry and should remain locked on return.
673  *      a_vpp is garbagre whether an error occurs or not.
674  *
675  * union_mknod(struct vnode *a_dvp, struct vnode **a_vpp,
676  *              struct componentname *a_cnp, struct vattr *a_vap)
677  */
678 static int
679 union_mknod(struct vop_old_mknod_args *ap)
680 {
681         struct union_node *dun = VTOUNION(ap->a_dvp);
682         struct componentname *cnp = ap->a_cnp;
683         struct vnode *dvp;
684         int error = EROFS;
685
686         if ((dvp = union_lock_upper(dun, cnp->cn_td)) != NULL) {
687                 error = VOP_MKNOD(dvp, ap->a_vpp, cnp, ap->a_vap);
688                 union_unlock_upper(dvp, cnp->cn_td);
689         }
690         return (error);
691 }
692
693 /*
694  *      union_open:
695  *
696  *      run open VOP.  When opening the underlying vnode we have to mimic
697  *      vn_open.  What we *really* need to do to avoid screwups if the
698  *      open semantics change is to call vn_open().  For example, ufs blows
699  *      up if you open a file but do not vmio it prior to writing.
700  *
701  * union_open(struct vnode *a_vp, int a_mode,
702  *            struct ucred *a_cred, struct thread *a_td)
703  */
704 static int
705 union_open(struct vop_open_args *ap)
706 {
707         struct union_node *un = VTOUNION(ap->a_vp);
708         struct vnode *tvp;
709         int mode = ap->a_mode;
710         struct ucred *cred = ap->a_cred;
711         struct thread *td = ap->a_td;
712         int error = 0;
713         int tvpisupper = 1;
714
715         /*
716          * If there is an existing upper vp then simply open that.
717          * The upper vp takes precedence over the lower vp.  When opening
718          * a lower vp for writing copy it to the uppervp and then open the
719          * uppervp.
720          *
721          * At the end of this section tvp will be left locked.
722          */
723         if ((tvp = union_lock_upper(un, td)) == NULLVP) {
724                 /*
725                  * If the lower vnode is being opened for writing, then
726                  * copy the file contents to the upper vnode and open that,
727                  * otherwise can simply open the lower vnode.
728                  */
729                 tvp = un->un_lowervp;
730                 if ((ap->a_mode & FWRITE) && (tvp->v_type == VREG)) {
731                         int docopy = !(mode & O_TRUNC);
732                         error = union_copyup(un, docopy, cred, td);
733                         tvp = union_lock_upper(un, td);
734                 } else {
735                         un->un_openl++;
736                         vref(tvp);
737                         vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY);
738                         tvpisupper = 0;
739                 }
740         }
741
742         /*
743          * We are holding the correct vnode, open it.  Note
744          * that in DragonFly, VOP_OPEN is responsible for associating
745          * a VM object with the vnode if the vnode is mappable or the
746          * underlying filesystem uses buffer cache calls on it.
747          */
748         if (error == 0)
749                 error = VOP_OPEN(tvp, mode, cred, NULL);
750
751         /*
752          * Release any locks held
753          */
754         if (tvpisupper) {
755                 if (tvp)
756                         union_unlock_upper(tvp, td);
757         } else {
758                 vput(tvp);
759         }
760         return (error);
761 }
762
763 /*
764  *      union_close:
765  *
766  *      It is unclear whether a_vp is passed locked or unlocked.  Whatever
767  *      the case we do not change it.
768  *
769  * union_close(struct vnode *a_vp, int a_fflag, struct ucred *a_cred,
770  *              struct thread *a_td)
771  */
772 static int
773 union_close(struct vop_close_args *ap)
774 {
775         struct union_node *un = VTOUNION(ap->a_vp);
776         struct vnode *vp;
777
778         if ((vp = un->un_uppervp) == NULLVP) {
779 #ifdef UNION_DIAGNOSTIC
780                 if (un->un_openl <= 0)
781                         panic("union: un_openl cnt");
782 #endif
783                 --un->un_openl;
784                 vp = un->un_lowervp;
785         }
786         ap->a_head.a_ops = *vp->v_ops;
787         ap->a_vp = vp;
788         return(vop_close_ap(ap));
789 }
790
791 /*
792  * Check access permission on the union vnode.
793  * The access check being enforced is to check
794  * against both the underlying vnode, and any
795  * copied vnode.  This ensures that no additional
796  * file permissions are given away simply because
797  * the user caused an implicit file copy.
798  *
799  * union_access(struct vnode *a_vp, int a_mode,
800  *              struct ucred *a_cred, struct thread *a_td)
801  */
802 static int
803 union_access(struct vop_access_args *ap)
804 {
805         struct union_node *un = VTOUNION(ap->a_vp);
806         struct thread *td = ap->a_td;
807         int error = EACCES;
808         struct vnode *vp;
809
810         /*
811          * Disallow write attempts on filesystems mounted read-only.
812          */
813         if ((ap->a_mode & VWRITE) && 
814             (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)) {
815                 switch (ap->a_vp->v_type) {
816                 case VREG: 
817                 case VDIR:
818                 case VLNK:
819                         return (EROFS);
820                 default:
821                         break;
822                 }
823         }
824
825         if ((vp = union_lock_upper(un, td)) != NULLVP) {
826                 ap->a_head.a_ops = *vp->v_ops;
827                 ap->a_vp = vp;
828                 error = vop_access_ap(ap);
829                 union_unlock_upper(vp, td);
830                 return(error);
831         }
832
833         if ((vp = un->un_lowervp) != NULLVP) {
834                 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
835                 ap->a_head.a_ops = *vp->v_ops;
836                 ap->a_vp = vp;
837
838                 /*
839                  * Remove VWRITE from a_mode if our mount point is RW, because
840                  * we want to allow writes and lowervp may be read-only.
841                  */
842                 if ((un->un_vnode->v_mount->mnt_flag & MNT_RDONLY) == 0)
843                         ap->a_mode &= ~VWRITE;
844
845                 error = vop_access_ap(ap);
846                 if (error == 0) {
847                         struct union_mount *um;
848
849                         um = MOUNTTOUNIONMOUNT(un->un_vnode->v_mount);
850
851                         if (um->um_op == UNMNT_BELOW) {
852                                 ap->a_cred = um->um_cred;
853                                 error = vop_access_ap(ap);
854                         }
855                 }
856                 vn_unlock(vp);
857         }
858         return(error);
859 }
860
861 /*
862  * We handle getattr only to change the fsid and
863  * track object sizes
864  *
865  * It's not clear whether VOP_GETATTR is to be
866  * called with the vnode locked or not.  stat() calls
867  * it with (vp) locked, and fstat calls it with
868  * (vp) unlocked. 
869  *
870  * Because of this we cannot use our normal locking functions
871  * if we do not intend to lock the main a_vp node.  At the moment
872  * we are running without any specific locking at all, but beware
873  * to any programmer that care must be taken if locking is added
874  * to this function.
875  *
876  * union_getattr(struct vnode *a_vp, struct vattr *a_vap,
877  *               struct ucred *a_cred, struct thread *a_td)
878  */
879 static int
880 union_getattr(struct vop_getattr_args *ap)
881 {
882         int error;
883         struct union_node *un = VTOUNION(ap->a_vp);
884         struct vnode *vp;
885         struct vattr *vap;
886         struct vattr va;
887
888         /*
889          * Some programs walk the filesystem hierarchy by counting
890          * links to directories to avoid stat'ing all the time.
891          * This means the link count on directories needs to be "correct".
892          * The only way to do that is to call getattr on both layers
893          * and fix up the link count.  The link count will not necessarily
894          * be accurate but will be large enough to defeat the tree walkers.
895          */
896
897         vap = ap->a_vap;
898
899         if ((vp = un->un_uppervp) != NULLVP) {
900                 error = VOP_GETATTR(vp, vap);
901                 if (error)
902                         return (error);
903                 /* XXX isn't this dangerouso without a lock? */
904                 union_newsize(ap->a_vp, vap->va_size, VNOVAL);
905         }
906
907         if (vp == NULLVP) {
908                 vp = un->un_lowervp;
909         } else if (vp->v_type == VDIR && un->un_lowervp != NULLVP) {
910                 vp = un->un_lowervp;
911                 vap = &va;
912         } else {
913                 vp = NULLVP;
914         }
915
916         if (vp != NULLVP) {
917                 error = VOP_GETATTR(vp, vap);
918                 if (error)
919                         return (error);
920                 /* XXX isn't this dangerous without a lock? */
921                 union_newsize(ap->a_vp, VNOVAL, vap->va_size);
922         }
923
924         if ((vap != ap->a_vap) && (vap->va_type == VDIR))
925                 ap->a_vap->va_nlink += vap->va_nlink;
926         return (0);
927 }
928
929 /*
930  * union_setattr(struct vnode *a_vp, struct vattr *a_vap,
931  *               struct ucred *a_cred, struct thread *a_td)
932  */
933 static int
934 union_setattr(struct vop_setattr_args *ap)
935 {
936         struct union_node *un = VTOUNION(ap->a_vp);
937         struct thread *td = ap->a_td;
938         struct vattr *vap = ap->a_vap;
939         struct vnode *uppervp;
940         int error;
941
942         /*
943          * Disallow write attempts on filesystems mounted read-only.
944          */
945         if ((ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) &&
946             (vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
947              vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
948              vap->va_mtime.tv_sec != VNOVAL || 
949              vap->va_mode != (mode_t)VNOVAL)) {
950                 return (EROFS);
951         }
952
953         /*
954          * Handle case of truncating lower object to zero size,
955          * by creating a zero length upper object.  This is to
956          * handle the case of open with O_TRUNC and O_CREAT.
957          */
958         if (un->un_uppervp == NULLVP && (un->un_lowervp->v_type == VREG)) {
959                 error = union_copyup(un, (ap->a_vap->va_size != 0),
960                             ap->a_cred, ap->a_td);
961                 if (error)
962                         return (error);
963         }
964
965         /*
966          * Try to set attributes in upper layer,
967          * otherwise return read-only filesystem error.
968          */
969         error = EROFS;
970         if ((uppervp = union_lock_upper(un, td)) != NULLVP) {
971                 error = VOP_SETATTR(un->un_uppervp, ap->a_vap, ap->a_cred);
972                 if ((error == 0) && (ap->a_vap->va_size != VNOVAL))
973                         union_newsize(ap->a_vp, ap->a_vap->va_size, VNOVAL);
974                 union_unlock_upper(uppervp, td);
975         }
976         return (error);
977 }
978
979 /*
980  *      union_getpages:
981  */
982
983 static int
984 union_getpages(struct vop_getpages_args *ap)
985 {
986         int r;
987
988         r = vnode_pager_generic_getpages(ap->a_vp, ap->a_m, 
989                 ap->a_count, ap->a_reqpage);
990         return(r);
991 }
992
993 /*
994  *      union_putpages:
995  */
996
997 static int
998 union_putpages(struct vop_putpages_args *ap)
999 {
1000         int r;
1001
1002         r = vnode_pager_generic_putpages(ap->a_vp, ap->a_m, ap->a_count,
1003                 ap->a_sync, ap->a_rtvals);
1004         return(r);
1005 }
1006
1007 /*
1008  * union_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
1009  *            struct ucred *a_cred)
1010  */
1011 static int
1012 union_read(struct vop_read_args *ap)
1013 {
1014         struct union_node *un = VTOUNION(ap->a_vp);
1015         struct thread *td = ap->a_uio->uio_td;
1016         struct vnode *uvp;
1017         int error;
1018
1019         uvp = union_lock_other(un, td);
1020         KASSERT(uvp != NULL, ("union_read: backing vnode missing!"));
1021
1022         if (ap->a_vp->v_flag & VOBJBUF)
1023                 union_vm_coherency(ap->a_vp, ap->a_uio, 0);
1024
1025         error = VOP_READ(uvp, ap->a_uio, ap->a_ioflag, ap->a_cred);
1026         union_unlock_other(uvp, td);
1027
1028         /*
1029          * XXX
1030          * perhaps the size of the underlying object has changed under
1031          * our feet.  take advantage of the offset information present
1032          * in the uio structure.
1033          */
1034         if (error == 0) {
1035                 struct union_node *un = VTOUNION(ap->a_vp);
1036                 off_t cur = ap->a_uio->uio_offset;
1037
1038                 if (uvp == un->un_uppervp) {
1039                         if (cur > un->un_uppersz)
1040                                 union_newsize(ap->a_vp, cur, VNOVAL);
1041                 } else {
1042                         if (cur > un->un_lowersz)
1043                                 union_newsize(ap->a_vp, VNOVAL, cur);
1044                 }
1045         }
1046         return (error);
1047 }
1048
1049 /*
1050  * union_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
1051  *              struct ucred *a_cred)
1052  */
1053 static int
1054 union_write(struct vop_read_args *ap)
1055 {
1056         struct union_node *un = VTOUNION(ap->a_vp);
1057         struct thread *td = ap->a_uio->uio_td;
1058         struct vnode *uppervp;
1059         int error;
1060
1061         if ((uppervp = union_lock_upper(un, td)) == NULLVP)
1062                 panic("union: missing upper layer in write");
1063
1064         /*
1065          * Since our VM pages are associated with our vnode rather then
1066          * the real vnode, and since we do not run our reads and writes 
1067          * through our own VM cache, we have a VM/VFS coherency problem. 
1068          * We solve them by invalidating or flushing the associated VM
1069          * pages prior to allowing a normal read or write to occur.
1070          *
1071          * VM-backed writes (UIO_NOCOPY) have to be converted to normal
1072          * writes because we are not cache-coherent.  Normal writes need
1073          * to be made coherent with our VM-backing store, which we do by
1074          * first flushing any dirty VM pages associated with the write
1075          * range, and then destroying any clean VM pages associated with
1076          * the write range.
1077          */
1078
1079         if (ap->a_uio->uio_segflg == UIO_NOCOPY) {
1080                 ap->a_uio->uio_segflg = UIO_SYSSPACE;
1081         } else if (ap->a_vp->v_flag & VOBJBUF) {
1082                 union_vm_coherency(ap->a_vp, ap->a_uio, 1);
1083         }
1084
1085         error = VOP_WRITE(uppervp, ap->a_uio, ap->a_ioflag, ap->a_cred);
1086
1087         /*
1088          * the size of the underlying object may be changed by the
1089          * write.
1090          */
1091         if (error == 0) {
1092                 off_t cur = ap->a_uio->uio_offset;
1093
1094                 if (cur > un->un_uppersz)
1095                         union_newsize(ap->a_vp, cur, VNOVAL);
1096         }
1097         union_unlock_upper(uppervp, td);
1098         return (error);
1099 }
1100
1101 /*
1102  * union_ioctl(struct vnode *a_vp, int a_command, caddr_t a_data, int a_fflag,
1103  *              struct ucred *a_cred, struct thread *a_td)
1104  */
1105 static int
1106 union_ioctl(struct vop_ioctl_args *ap)
1107 {
1108         struct vnode *ovp = OTHERVP(ap->a_vp);
1109
1110         ap->a_head.a_ops = *ovp->v_ops;
1111         ap->a_vp = ovp;
1112         return(vop_ioctl_ap(ap));
1113 }
1114
1115 /*
1116  * union_poll(struct vnode *a_vp, int a_events, struct ucred *a_cred,
1117  *            struct thread *a_td)
1118  */
1119 static int
1120 union_poll(struct vop_poll_args *ap)
1121 {
1122         struct vnode *ovp = OTHERVP(ap->a_vp);
1123
1124         ap->a_head.a_ops = *ovp->v_ops;
1125         ap->a_vp = ovp;
1126         return(vop_poll_ap(ap));
1127 }
1128
1129 /*
1130  * union_revoke(struct vnode *a_vp, int a_flags, struct thread *a_td)
1131  */
1132 static int
1133 union_revoke(struct vop_revoke_args *ap)
1134 {
1135         struct vnode *vp = ap->a_vp;
1136         struct vnode *vx;
1137
1138         if ((vx = UPPERVP(vp)) != NULL) {
1139                 vx_get(vx);
1140                 VOP_REVOKE(vx, ap->a_flags);
1141                 vx_put(vx);
1142         }
1143         if ((vx = LOWERVP(vp)) != NULL) {
1144                 vx_get(vx);
1145                 VOP_REVOKE(vx, ap->a_flags);
1146                 vx_put(vx);
1147         }
1148         vgone(vp);
1149         return (0);
1150 }
1151
1152 /*
1153  * union_mmap(struct vnode *a_vp, int a_fflags, struct ucred *a_cred,
1154  *            struct thread *a_td)
1155  */
1156 static int
1157 union_mmap(struct vop_mmap_args *ap)
1158 {
1159         struct vnode *ovp = OTHERVP(ap->a_vp);
1160
1161         ap->a_head.a_ops = *ovp->v_ops;
1162         ap->a_vp = ovp;
1163         return (vop_mmap_ap(ap));
1164 }
1165
1166 /*
1167  * union_fsync(struct vnode *a_vp, struct ucred *a_cred, int a_waitfor,
1168  *              struct thread *a_td)
1169  */
1170 static int
1171 union_fsync(struct vop_fsync_args *ap)
1172 {
1173         int error = 0;
1174         struct thread *td = ap->a_td;
1175         struct vnode *targetvp;
1176         struct union_node *un = VTOUNION(ap->a_vp);
1177
1178         if ((targetvp = union_lock_other(un, td)) != NULLVP) {
1179                 error = VOP_FSYNC(targetvp, ap->a_waitfor);
1180                 union_unlock_other(targetvp, td);
1181         }
1182
1183         return (error);
1184 }
1185
1186 /*
1187  *      union_remove:
1188  *
1189  *      Remove the specified cnp.  The dvp and vp are passed to us locked
1190  *      and must remain locked on return.
1191  *
1192  * union_remove(struct vnode *a_dvp, struct vnode *a_vp,
1193  *              struct componentname *a_cnp)
1194  */
1195 static int
1196 union_remove(struct vop_old_remove_args *ap)
1197 {
1198         struct union_node *dun = VTOUNION(ap->a_dvp);
1199         struct union_node *un = VTOUNION(ap->a_vp);
1200         struct componentname *cnp = ap->a_cnp;
1201         struct thread *td = cnp->cn_td;
1202         struct vnode *uppervp;
1203         struct vnode *upperdvp;
1204         int error;
1205
1206         if ((upperdvp = union_lock_upper(dun, td)) == NULLVP)
1207                 panic("union remove: null upper vnode");
1208
1209         if ((uppervp = union_lock_upper(un, td)) != NULLVP) {
1210                 if (union_dowhiteout(un, cnp->cn_cred, td))
1211                         cnp->cn_flags |= CNP_DOWHITEOUT;
1212                 error = VOP_REMOVE(upperdvp, uppervp, cnp);
1213 #if 0
1214                 /* XXX */
1215                 if (!error)
1216                         union_removed_upper(un);
1217 #endif
1218                 union_unlock_upper(uppervp, td);
1219         } else {
1220                 error = union_mkwhiteout(
1221                             MOUNTTOUNIONMOUNT(ap->a_dvp->v_mount),
1222                             upperdvp, ap->a_cnp, un->un_path);
1223         }
1224         union_unlock_upper(upperdvp, td);
1225         return (error);
1226 }
1227
1228 /*
1229  *      union_link:
1230  *
1231  *      tdvp will be locked on entry, vp will not be locked on entry.
1232  *      tdvp should remain locked on return and vp should remain unlocked
1233  *      on return.
1234  *
1235  * union_link(struct vnode *a_tdvp, struct vnode *a_vp,
1236  *            struct componentname *a_cnp)
1237  */
1238 static int
1239 union_link(struct vop_old_link_args *ap)
1240 {
1241         struct componentname *cnp = ap->a_cnp;
1242         struct thread *td = cnp->cn_td;
1243         struct union_node *dun = VTOUNION(ap->a_tdvp);
1244         struct vnode *vp;
1245         struct vnode *tdvp;
1246         int error = 0;
1247
1248         if (ap->a_tdvp->v_ops != ap->a_vp->v_ops) {
1249                 vp = ap->a_vp;
1250         } else {
1251                 struct union_node *tun = VTOUNION(ap->a_vp);
1252
1253                 if (tun->un_uppervp == NULLVP) {
1254                         vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
1255 #if 0
1256                         if (dun->un_uppervp == tun->un_dirvp) {
1257                                 if (dun->un_flags & UN_ULOCK) {
1258                                         dun->un_flags &= ~UN_ULOCK;
1259                                         vn_unlock(dun->un_uppervp);
1260                                 }
1261                         }
1262 #endif
1263                         error = union_copyup(tun, 1, cnp->cn_cred, td);
1264 #if 0
1265                         if (dun->un_uppervp == tun->un_dirvp) {
1266                                 vn_lock(dun->un_uppervp, 
1267                                         LK_EXCLUSIVE | LK_RETRY);
1268                                 dun->un_flags |= UN_ULOCK;
1269                         }
1270 #endif
1271                         vn_unlock(ap->a_vp);
1272                 }
1273                 vp = tun->un_uppervp;
1274         }
1275
1276         if (error)
1277                 return (error);
1278
1279         /*
1280          * Make sure upper is locked, then unlock the union directory we were 
1281          * called with to avoid a deadlock while we are calling VOP_LINK on 
1282          * the upper (with tdvp locked and vp not locked).  Our ap->a_tdvp
1283          * is expected to be locked on return.
1284          */
1285
1286         if ((tdvp = union_lock_upper(dun, td)) == NULLVP)
1287                 return (EROFS);
1288
1289         vn_unlock(ap->a_tdvp);  /* unlock calling node */
1290         error = VOP_LINK(tdvp, vp, cnp); /* call link on upper */
1291
1292         /*
1293          * We have to unlock tdvp prior to relocking our calling node in
1294          * order to avoid a deadlock.
1295          */
1296         union_unlock_upper(tdvp, td);
1297         vn_lock(ap->a_tdvp, LK_EXCLUSIVE | LK_RETRY);
1298         return (error);
1299 }
1300
1301 /*
1302  * union_rename(struct vnode *a_fdvp, struct vnode *a_fvp,
1303  *              struct componentname *a_fcnp, struct vnode *a_tdvp,
1304  *              struct vnode *a_tvp, struct componentname *a_tcnp)
1305  */
1306 static int
1307 union_rename(struct vop_old_rename_args *ap)
1308 {
1309         int error;
1310         struct vnode *fdvp = ap->a_fdvp;
1311         struct vnode *fvp = ap->a_fvp;
1312         struct vnode *tdvp = ap->a_tdvp;
1313         struct vnode *tvp = ap->a_tvp;
1314
1315         /*
1316          * Figure out what fdvp to pass to our upper or lower vnode.  If we
1317          * replace the fdvp, release the original one and ref the new one.
1318          */
1319
1320         if (fdvp->v_tag == VT_UNION) {  /* always true */
1321                 struct union_node *un = VTOUNION(fdvp);
1322                 if (un->un_uppervp == NULLVP) {
1323                         /*
1324                          * this should never happen in normal
1325                          * operation but might if there was
1326                          * a problem creating the top-level shadow
1327                          * directory.
1328                          */
1329                         error = EXDEV;
1330                         goto bad;
1331                 }
1332                 fdvp = un->un_uppervp;
1333                 vref(fdvp);
1334                 vrele(ap->a_fdvp);
1335         }
1336
1337         /*
1338          * Figure out what fvp to pass to our upper or lower vnode.  If we
1339          * replace the fvp, release the original one and ref the new one.
1340          */
1341
1342         if (fvp->v_tag == VT_UNION) {   /* always true */
1343                 struct union_node *un = VTOUNION(fvp);
1344 #if 0
1345                 struct union_mount *um = MOUNTTOUNIONMOUNT(fvp->v_mount);
1346 #endif
1347
1348                 if (un->un_uppervp == NULLVP) {
1349                         switch(fvp->v_type) {
1350                         case VREG:
1351                                 vn_lock(un->un_vnode, LK_EXCLUSIVE | LK_RETRY);
1352                                 error = union_copyup(un, 1, ap->a_fcnp->cn_cred, ap->a_fcnp->cn_td);
1353                                 vn_unlock(un->un_vnode);
1354                                 if (error)
1355                                         goto bad;
1356                                 break;
1357                         case VDIR:
1358                                 /*
1359                                  * XXX not yet.
1360                                  *
1361                                  * There is only one way to rename a directory
1362                                  * based in the lowervp, and that is to copy
1363                                  * the entire directory hierarchy.  Otherwise
1364                                  * it would not last across a reboot.
1365                                  */
1366 #if 0
1367                                 vrele(fvp);
1368                                 fvp = NULL;
1369                                 vn_lock(fdvp, LK_EXCLUSIVE | LK_RETRY);
1370                                 error = union_mkshadow(um, fdvp, 
1371                                             ap->a_fcnp, &un->un_uppervp);
1372                                 vn_unlock(fdvp);
1373                                 if (un->un_uppervp)
1374                                         vn_unlock(un->un_uppervp);
1375                                 if (error)
1376                                         goto bad;
1377                                 break;
1378 #endif
1379                         default:
1380                                 error = EXDEV;
1381                                 goto bad;
1382                         }
1383                 }
1384
1385                 if (un->un_lowervp != NULLVP)
1386                         ap->a_fcnp->cn_flags |= CNP_DOWHITEOUT;
1387                 fvp = un->un_uppervp;
1388                 vref(fvp);
1389                 vrele(ap->a_fvp);
1390         }
1391
1392         /*
1393          * Figure out what tdvp (destination directory) to pass to the
1394          * lower level.  If we replace it with uppervp, we need to vput the 
1395          * old one.  The exclusive lock is transfered to what we will pass
1396          * down in the VOP_RENAME and we replace uppervp with a simple
1397          * reference.
1398          */
1399
1400         if (tdvp->v_tag == VT_UNION) {
1401                 struct union_node *un = VTOUNION(tdvp);
1402
1403                 if (un->un_uppervp == NULLVP) {
1404                         /*
1405                          * this should never happen in normal
1406                          * operation but might if there was
1407                          * a problem creating the top-level shadow
1408                          * directory.
1409                          */
1410                         error = EXDEV;
1411                         goto bad;
1412                 }
1413
1414                 /*
1415                  * new tdvp is a lock and reference on uppervp, put away
1416                  * the old tdvp.
1417                  */
1418                 tdvp = union_lock_upper(un, ap->a_tcnp->cn_td);
1419                 vput(ap->a_tdvp);
1420         }
1421
1422         /*
1423          * Figure out what tvp (destination file) to pass to the
1424          * lower level.
1425          *
1426          * If the uppervp file does not exist put away the (wrong)
1427          * file and change tvp to NULL.
1428          */
1429
1430         if (tvp != NULLVP && tvp->v_tag == VT_UNION) {
1431                 struct union_node *un = VTOUNION(tvp);
1432
1433                 tvp = union_lock_upper(un, ap->a_tcnp->cn_td);
1434                 vput(ap->a_tvp);
1435                 /* note: tvp may be NULL */
1436         }
1437
1438         /*
1439          * VOP_RENAME releases/vputs prior to returning, so we have no
1440          * cleanup to do.
1441          */
1442
1443         return (VOP_RENAME(fdvp, fvp, ap->a_fcnp, tdvp, tvp, ap->a_tcnp));
1444
1445         /*
1446          * Error.  We still have to release / vput the various elements.
1447          */
1448
1449 bad:
1450         vrele(fdvp);
1451         if (fvp)
1452                 vrele(fvp);
1453         vput(tdvp);
1454         if (tvp != NULLVP) {
1455                 if (tvp != tdvp)
1456                         vput(tvp);
1457                 else
1458                         vrele(tvp);
1459         }
1460         return (error);
1461 }
1462
1463 /*
1464  * union_mkdir(struct vnode *a_dvp, struct vnode **a_vpp,
1465  *              struct componentname *a_cnp, struct vattr *a_vap)
1466  */
1467 static int
1468 union_mkdir(struct vop_old_mkdir_args *ap)
1469 {
1470         struct union_node *dun = VTOUNION(ap->a_dvp);
1471         struct componentname *cnp = ap->a_cnp;
1472         struct thread *td = cnp->cn_td;
1473         struct vnode *upperdvp;
1474         int error = EROFS;
1475
1476         if ((upperdvp = union_lock_upper(dun, td)) != NULLVP) {
1477                 struct vnode *vp;
1478
1479                 error = VOP_MKDIR(upperdvp, &vp, cnp, ap->a_vap);
1480                 union_unlock_upper(upperdvp, td);
1481
1482                 if (error == 0) {
1483                         vn_unlock(vp);
1484                         UDEBUG(("ALLOCVP-2 FROM %p REFS %d\n", vp, vp->v_usecount));
1485                         error = union_allocvp(ap->a_vpp, ap->a_dvp->v_mount,
1486                                 ap->a_dvp, NULLVP, cnp, vp, NULLVP, 1);
1487                         UDEBUG(("ALLOCVP-2B FROM %p REFS %d\n", *ap->a_vpp, vp->v_usecount));
1488                 }
1489         }
1490         return (error);
1491 }
1492
1493 /*
1494  * union_rmdir(struct vnode *a_dvp, struct vnode *a_vp,
1495  *              struct componentname *a_cnp)
1496  */
1497 static int
1498 union_rmdir(struct vop_old_rmdir_args *ap)
1499 {
1500         struct union_node *dun = VTOUNION(ap->a_dvp);
1501         struct union_node *un = VTOUNION(ap->a_vp);
1502         struct componentname *cnp = ap->a_cnp;
1503         struct thread *td = cnp->cn_td;
1504         struct vnode *upperdvp;
1505         struct vnode *uppervp;
1506         int error;
1507
1508         if ((upperdvp = union_lock_upper(dun, td)) == NULLVP)
1509                 panic("union rmdir: null upper vnode");
1510
1511         if ((uppervp = union_lock_upper(un, td)) != NULLVP) {
1512                 if (union_dowhiteout(un, cnp->cn_cred, td))
1513                         cnp->cn_flags |= CNP_DOWHITEOUT;
1514                 error = VOP_RMDIR(upperdvp, uppervp, ap->a_cnp);
1515                 union_unlock_upper(uppervp, td);
1516         } else {
1517                 error = union_mkwhiteout(
1518                             MOUNTTOUNIONMOUNT(ap->a_dvp->v_mount),
1519                             dun->un_uppervp, ap->a_cnp, un->un_path);
1520         }
1521         union_unlock_upper(upperdvp, td);
1522         return (error);
1523 }
1524
1525 /*
1526  *      union_symlink:
1527  *
1528  *      dvp is locked on entry and remains locked on return.  a_vpp is garbage
1529  *      (unused).
1530  *
1531  * union_symlink(struct vnode *a_dvp, struct vnode **a_vpp,
1532  *              struct componentname *a_cnp, struct vattr *a_vap,
1533  *              char *a_target)
1534  */
1535 static int
1536 union_symlink(struct vop_old_symlink_args *ap)
1537 {
1538         struct union_node *dun = VTOUNION(ap->a_dvp);
1539         struct componentname *cnp = ap->a_cnp;
1540         struct thread *td = cnp->cn_td;
1541         struct vnode *dvp;
1542         int error = EROFS;
1543
1544         if ((dvp = union_lock_upper(dun, td)) != NULLVP) {
1545                 error = VOP_SYMLINK(dvp, ap->a_vpp, cnp, ap->a_vap,
1546                             ap->a_target);
1547                 union_unlock_upper(dvp, td);
1548         }
1549         return (error);
1550 }
1551
1552 /*
1553  * union_readdir works in concert with getdirentries and
1554  * readdir(3) to provide a list of entries in the unioned
1555  * directories.  getdirentries is responsible for walking
1556  * down the union stack.  readdir(3) is responsible for
1557  * eliminating duplicate names from the returned data stream.
1558  *
1559  * union_readdir(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred,
1560  *               int *a_eofflag, u_long *a_cookies, int a_ncookies)
1561  */
1562 static int
1563 union_readdir(struct vop_readdir_args *ap)
1564 {
1565         struct union_node *un = VTOUNION(ap->a_vp);
1566         struct thread *td = ap->a_uio->uio_td;
1567         struct vnode *uvp;
1568         int error = 0;
1569
1570         if ((uvp = union_lock_upper(un, td)) != NULLVP) {
1571                 ap->a_head.a_ops = *uvp->v_ops;
1572                 ap->a_vp = uvp;
1573                 error = vop_readdir_ap(ap);
1574                 union_unlock_upper(uvp, td);
1575         }
1576         return(error);
1577 }
1578
1579 /*
1580  * union_readlink(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred)
1581  */
1582 static int
1583 union_readlink(struct vop_readlink_args *ap)
1584 {
1585         int error;
1586         struct union_node *un = VTOUNION(ap->a_vp);
1587         struct uio *uio = ap->a_uio;
1588         struct thread *td = uio->uio_td;
1589         struct vnode *vp;
1590
1591         vp = union_lock_other(un, td);
1592         KASSERT(vp != NULL, ("union_readlink: backing vnode missing!"));
1593
1594         ap->a_head.a_ops = *vp->v_ops;
1595         ap->a_vp = vp;
1596         error = vop_readlink_ap(ap);
1597         union_unlock_other(vp, td);
1598
1599         return (error);
1600 }
1601
1602 /*
1603  *      union_inactive:
1604  *
1605  *      Called with the vnode locked.  We are expected to unlock the vnode.
1606  *
1607  * union_inactive(struct vnode *a_vp, struct thread *a_td)
1608  */
1609 static int
1610 union_inactive(struct vop_inactive_args *ap)
1611 {
1612         struct vnode *vp = ap->a_vp;
1613         /*struct thread *td = ap->a_td;*/
1614         struct union_node *un = VTOUNION(vp);
1615         struct vnode **vpp;
1616
1617         /*
1618          * Do nothing (and _don't_ bypass).
1619          * Wait to vrele lowervp until reclaim,
1620          * so that until then our union_node is in the
1621          * cache and reusable.
1622          *
1623          * NEEDSWORK: Someday, consider inactive'ing
1624          * the lowervp and then trying to reactivate it
1625          * with capabilities (v_id)
1626          * like they do in the name lookup cache code.
1627          * That's too much work for now.
1628          */
1629
1630         if (un->un_dircache != 0) {
1631                 for (vpp = un->un_dircache; *vpp != NULLVP; vpp++)
1632                         vrele(*vpp);
1633                 free (un->un_dircache, M_TEMP);
1634                 un->un_dircache = 0;
1635         }
1636
1637 #if 0
1638         if ((un->un_flags & UN_ULOCK) && un->un_uppervp) {
1639                 un->un_flags &= ~UN_ULOCK;
1640                 vn_unlock(un->un_uppervp);
1641         }
1642 #endif
1643
1644         if ((un->un_flags & UN_CACHED) == 0)
1645                 vgone(vp);
1646
1647         return (0);
1648 }
1649
1650 /*
1651  * union_reclaim(struct vnode *a_vp)
1652  */
1653 static int
1654 union_reclaim(struct vop_reclaim_args *ap)
1655 {
1656         union_freevp(ap->a_vp);
1657
1658         return (0);
1659 }
1660
1661 /*
1662  *      union_bmap:
1663  *
1664  *      There isn't much we can do.  We cannot push through to the real vnode
1665  *      to get to the underlying device because this will bypass data
1666  *      cached by the real vnode.
1667  *
1668  *      For some reason we cannot return the 'real' vnode either, it seems
1669  *      to blow up memory maps.
1670  *
1671  * union_bmap(struct vnode *a_vp, off_t a_loffset, struct vnode **a_vpp,
1672  *            off_t *a_doffsetp, int *a_runp, int *a_runb)
1673  */
1674 static int
1675 union_bmap(struct vop_bmap_args *ap)
1676 {
1677         return(EOPNOTSUPP);
1678 }
1679
1680 /*
1681  * union_print(struct vnode *a_vp)
1682  */
1683 static int
1684 union_print(struct vop_print_args *ap)
1685 {
1686         struct vnode *vp = ap->a_vp;
1687
1688         printf("\ttag VT_UNION, vp=%p, uppervp=%p, lowervp=%p\n",
1689                         vp, UPPERVP(vp), LOWERVP(vp));
1690         if (UPPERVP(vp) != NULLVP)
1691                 vprint("union: upper", UPPERVP(vp));
1692         if (LOWERVP(vp) != NULLVP)
1693                 vprint("union: lower", LOWERVP(vp));
1694
1695         return (0);
1696 }
1697
1698 /*
1699  * union_pathconf(struct vnode *a_vp, int a_name, int *a_retval)
1700  */
1701 static int
1702 union_pathconf(struct vop_pathconf_args *ap)
1703 {
1704         int error;
1705         struct thread *td = curthread;          /* XXX */
1706         struct union_node *un = VTOUNION(ap->a_vp);
1707         struct vnode *vp;
1708
1709         vp = union_lock_other(un, td);
1710         KASSERT(vp != NULL, ("union_pathconf: backing vnode missing!"));
1711
1712         ap->a_head.a_ops = *vp->v_ops;
1713         ap->a_vp = vp;
1714         error = vop_pathconf_ap(ap);
1715         union_unlock_other(vp, td);
1716
1717         return (error);
1718 }
1719
1720 /*
1721  * union_advlock(struct vnode *a_vp, caddr_t a_id, int a_op,
1722  *               struct flock *a_fl, int a_flags)
1723  */
1724 static int
1725 union_advlock(struct vop_advlock_args *ap)
1726 {
1727         struct vnode *ovp = OTHERVP(ap->a_vp);
1728
1729         ap->a_head.a_ops = *ovp->v_ops;
1730         ap->a_vp = ovp;
1731         return (vop_advlock_ap(ap));
1732 }
1733
1734
1735 /*
1736  * XXX - vop_strategy must be hand coded because it has no
1737  * YYY - and it is not coherent with anything
1738  *
1739  * vnode in its arguments.
1740  * This goes away with a merged VM/buffer cache.
1741  *
1742  * union_strategy(struct vnode *a_vp, struct bio *a_bio)
1743  */
1744 static int
1745 union_strategy(struct vop_strategy_args *ap)
1746 {
1747         struct bio *bio = ap->a_bio;
1748         struct buf *bp = bio->bio_buf;
1749         struct vnode *othervp = OTHERVP(ap->a_vp);
1750
1751 #ifdef DIAGNOSTIC
1752         if (othervp == NULLVP)
1753                 panic("union_strategy: nil vp");
1754         if (bp->b_cmd != BUF_CMD_READ && (othervp == LOWERVP(ap->a_vp)))
1755                 panic("union_strategy: writing to lowervp");
1756 #endif
1757         return (vn_strategy(othervp, bio));
1758 }
1759
1760 /*
1761  * Global vfs data structures
1762  */
1763 struct vop_ops union_vnode_vops = {
1764         .vop_default =          vop_defaultop,
1765         .vop_access =           union_access,
1766         .vop_advlock =          union_advlock,
1767         .vop_bmap =             union_bmap,
1768         .vop_close =            union_close,
1769         .vop_old_create =       union_create,
1770         .vop_fsync =            union_fsync,
1771         .vop_getpages =         union_getpages,
1772         .vop_putpages =         union_putpages,
1773         .vop_getattr =          union_getattr,
1774         .vop_inactive =         union_inactive,
1775         .vop_ioctl =            union_ioctl,
1776         .vop_old_link =         union_link,
1777         .vop_old_lookup =       union_lookup,
1778         .vop_old_mkdir =        union_mkdir,
1779         .vop_old_mknod =        union_mknod,
1780         .vop_mmap =             union_mmap,
1781         .vop_open =             union_open,
1782         .vop_pathconf =         union_pathconf,
1783         .vop_poll =             union_poll,
1784         .vop_print =            union_print,
1785         .vop_read =             union_read,
1786         .vop_readdir =          union_readdir,
1787         .vop_readlink =         union_readlink,
1788         .vop_reclaim =          union_reclaim,
1789         .vop_old_remove =       union_remove,
1790         .vop_old_rename =       union_rename,
1791         .vop_revoke =           union_revoke,
1792         .vop_old_rmdir =        union_rmdir,
1793         .vop_setattr =          union_setattr,
1794         .vop_strategy =         union_strategy,
1795         .vop_old_symlink =      union_symlink,
1796         .vop_old_whiteout =     union_whiteout,
1797         .vop_write =            union_write
1798 };
1799