union_vnops.c revision 1.15 1 /* $NetBSD: union_vnops.c,v 1.15 2006/04/15 03:56:25 christos Exp $ */
2
3 /*
4 * Copyright (c) 1992, 1993, 1994, 1995
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Jan-Simon Pendry.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)union_vnops.c 8.33 (Berkeley) 7/31/95
35 */
36
37 /*
38 * Copyright (c) 1992, 1993, 1994, 1995 Jan-Simon Pendry.
39 *
40 * This code is derived from software contributed to Berkeley by
41 * Jan-Simon Pendry.
42 *
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
45 * are met:
46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in the
50 * documentation and/or other materials provided with the distribution.
51 * 3. All advertising materials mentioning features or use of this software
52 * must display the following acknowledgement:
53 * This product includes software developed by the University of
54 * California, Berkeley and its contributors.
55 * 4. Neither the name of the University nor the names of its contributors
56 * may be used to endorse or promote products derived from this software
57 * without specific prior written permission.
58 *
59 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * SUCH DAMAGE.
70 *
71 * @(#)union_vnops.c 8.33 (Berkeley) 7/31/95
72 */
73
74 #include <sys/cdefs.h>
75 __KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.15 2006/04/15 03:56:25 christos Exp $");
76
77 #include <sys/param.h>
78 #include <sys/systm.h>
79 #include <sys/proc.h>
80 #include <sys/file.h>
81 #include <sys/time.h>
82 #include <sys/stat.h>
83 #include <sys/vnode.h>
84 #include <sys/mount.h>
85 #include <sys/namei.h>
86 #include <sys/malloc.h>
87 #include <sys/buf.h>
88 #include <sys/queue.h>
89 #include <sys/lock.h>
90 #include <fs/union/union.h>
91 #include <miscfs/genfs/genfs.h>
92
93 int union_lookup(void *);
94 int union_create(void *);
95 int union_whiteout(void *);
96 int union_mknod(void *);
97 int union_open(void *);
98 int union_close(void *);
99 int union_access(void *);
100 int union_getattr(void *);
101 int union_setattr(void *);
102 int union_read(void *);
103 int union_write(void *);
104 int union_lease(void *);
105 int union_ioctl(void *);
106 int union_poll(void *);
107 int union_revoke(void *);
108 int union_mmap(void *);
109 int union_fsync(void *);
110 int union_seek(void *);
111 int union_remove(void *);
112 int union_link(void *);
113 int union_rename(void *);
114 int union_mkdir(void *);
115 int union_rmdir(void *);
116 int union_symlink(void *);
117 int union_readdir(void *);
118 int union_readlink(void *);
119 int union_abortop(void *);
120 int union_inactive(void *);
121 int union_reclaim(void *);
122 int union_lock(void *);
123 int union_unlock(void *);
124 int union_bmap(void *);
125 int union_print(void *);
126 int union_islocked(void *);
127 int union_pathconf(void *);
128 int union_advlock(void *);
129 int union_strategy(void *);
130 int union_getpages(void *);
131 int union_putpages(void *);
132 int union_kqfilter(void *);
133
134 static void union_fixup(struct union_node *);
135 static int union_lookup1(struct vnode *, struct vnode **,
136 struct vnode **, struct componentname *);
137
138
139 /*
140 * Global vfs data structures
141 */
142 int (**union_vnodeop_p)(void *);
143 const struct vnodeopv_entry_desc union_vnodeop_entries[] = {
144 { &vop_default_desc, vn_default_error },
145 { &vop_lookup_desc, union_lookup }, /* lookup */
146 { &vop_create_desc, union_create }, /* create */
147 { &vop_whiteout_desc, union_whiteout }, /* whiteout */
148 { &vop_mknod_desc, union_mknod }, /* mknod */
149 { &vop_open_desc, union_open }, /* open */
150 { &vop_close_desc, union_close }, /* close */
151 { &vop_access_desc, union_access }, /* access */
152 { &vop_getattr_desc, union_getattr }, /* getattr */
153 { &vop_setattr_desc, union_setattr }, /* setattr */
154 { &vop_read_desc, union_read }, /* read */
155 { &vop_write_desc, union_write }, /* write */
156 { &vop_lease_desc, union_lease }, /* lease */
157 { &vop_ioctl_desc, union_ioctl }, /* ioctl */
158 { &vop_poll_desc, union_poll }, /* select */
159 { &vop_revoke_desc, union_revoke }, /* revoke */
160 { &vop_mmap_desc, union_mmap }, /* mmap */
161 { &vop_fsync_desc, union_fsync }, /* fsync */
162 { &vop_seek_desc, union_seek }, /* seek */
163 { &vop_remove_desc, union_remove }, /* remove */
164 { &vop_link_desc, union_link }, /* link */
165 { &vop_rename_desc, union_rename }, /* rename */
166 { &vop_mkdir_desc, union_mkdir }, /* mkdir */
167 { &vop_rmdir_desc, union_rmdir }, /* rmdir */
168 { &vop_symlink_desc, union_symlink }, /* symlink */
169 { &vop_readdir_desc, union_readdir }, /* readdir */
170 { &vop_readlink_desc, union_readlink }, /* readlink */
171 { &vop_abortop_desc, union_abortop }, /* abortop */
172 { &vop_inactive_desc, union_inactive }, /* inactive */
173 { &vop_reclaim_desc, union_reclaim }, /* reclaim */
174 { &vop_lock_desc, union_lock }, /* lock */
175 { &vop_unlock_desc, union_unlock }, /* unlock */
176 { &vop_bmap_desc, union_bmap }, /* bmap */
177 { &vop_strategy_desc, union_strategy }, /* strategy */
178 { &vop_print_desc, union_print }, /* print */
179 { &vop_islocked_desc, union_islocked }, /* islocked */
180 { &vop_pathconf_desc, union_pathconf }, /* pathconf */
181 { &vop_advlock_desc, union_advlock }, /* advlock */
182 { &vop_getpages_desc, union_getpages }, /* getpages */
183 { &vop_putpages_desc, union_putpages }, /* putpages */
184 { &vop_kqfilter_desc, union_kqfilter }, /* kqfilter */
185 #ifdef notdef
186 { &vop_bwrite_desc, union_bwrite }, /* bwrite */
187 #endif
188 { NULL, NULL }
189 };
190 const struct vnodeopv_desc union_vnodeop_opv_desc =
191 { &union_vnodeop_p, union_vnodeop_entries };
192
193 #define FIXUP(un) { \
194 if (((un)->un_flags & UN_ULOCK) == 0) { \
195 union_fixup(un); \
196 } \
197 }
198
199 static void
200 union_fixup(un)
201 struct union_node *un;
202 {
203
204 vn_lock(un->un_uppervp, LK_EXCLUSIVE | LK_RETRY);
205 un->un_flags |= UN_ULOCK;
206 }
207
208 static int
209 union_lookup1(udvp, dvpp, vpp, cnp)
210 struct vnode *udvp;
211 struct vnode **dvpp;
212 struct vnode **vpp;
213 struct componentname *cnp;
214 {
215 int error;
216 struct vnode *tdvp;
217 struct vnode *dvp;
218 struct mount *mp;
219
220 dvp = *dvpp;
221
222 /*
223 * If stepping up the directory tree, check for going
224 * back across the mount point, in which case do what
225 * lookup would do by stepping back down the mount
226 * hierarchy.
227 */
228 if (cnp->cn_flags & ISDOTDOT) {
229 while ((dvp != udvp) && (dvp->v_flag & VROOT)) {
230 /*
231 * Don't do the NOCROSSMOUNT check
232 * at this level. By definition,
233 * union fs deals with namespaces, not
234 * filesystems.
235 */
236 tdvp = dvp;
237 *dvpp = dvp = dvp->v_mount->mnt_vnodecovered;
238 vput(tdvp);
239 VREF(dvp);
240 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
241 }
242 }
243
244 error = VOP_LOOKUP(dvp, &tdvp, cnp);
245 if (error)
246 return (error);
247
248 /*
249 * The parent directory will have been unlocked, unless lookup
250 * found the last component. In which case, re-lock the node
251 * here to allow it to be unlocked again (phew) in union_lookup.
252 */
253 if (dvp != tdvp && !(cnp->cn_flags & ISLASTCN))
254 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
255
256 dvp = tdvp;
257
258 /*
259 * Lastly check if the current node is a mount point in
260 * which case walk up the mount hierarchy making sure not to
261 * bump into the root of the mount tree (ie. dvp != udvp).
262 */
263 while (dvp != udvp && (dvp->v_type == VDIR) &&
264 (mp = dvp->v_mountedhere)) {
265
266 if (vfs_busy(mp, 0, 0))
267 continue;
268
269 error = VFS_ROOT(mp, &tdvp);
270 vfs_unbusy(mp);
271 if (error) {
272 vput(dvp);
273 return (error);
274 }
275
276 vput(dvp);
277 dvp = tdvp;
278 }
279
280 *vpp = dvp;
281 return (0);
282 }
283
284 int
285 union_lookup(v)
286 void *v;
287 {
288 struct vop_lookup_args /* {
289 struct vnodeop_desc *a_desc;
290 struct vnode *a_dvp;
291 struct vnode **a_vpp;
292 struct componentname *a_cnp;
293 } */ *ap = v;
294 int error;
295 int uerror, lerror;
296 struct vnode *uppervp, *lowervp;
297 struct vnode *upperdvp, *lowerdvp;
298 struct vnode *dvp = ap->a_dvp;
299 struct union_node *dun = VTOUNION(dvp);
300 struct componentname *cnp = ap->a_cnp;
301 int lockparent = cnp->cn_flags & LOCKPARENT;
302 struct union_mount *um = MOUNTTOUNIONMOUNT(dvp->v_mount);
303 struct ucred *saved_cred = NULL;
304 int iswhiteout;
305 struct vattr va;
306
307 #ifdef notyet
308 if (cnp->cn_namelen == 3 &&
309 cnp->cn_nameptr[2] == '.' &&
310 cnp->cn_nameptr[1] == '.' &&
311 cnp->cn_nameptr[0] == '.') {
312 dvp = *ap->a_vpp = LOWERVP(ap->a_dvp);
313 if (dvp == NULLVP)
314 return (ENOENT);
315 VREF(dvp);
316 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
317 if (!lockparent || !(cnp->cn_flags & ISLASTCN))
318 VOP_UNLOCK(ap->a_dvp, 0);
319 return (0);
320 }
321 #endif
322
323 if ((cnp->cn_flags & ISLASTCN) &&
324 (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
325 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
326 return (EROFS);
327
328 cnp->cn_flags |= LOCKPARENT;
329
330 upperdvp = dun->un_uppervp;
331 lowerdvp = dun->un_lowervp;
332 uppervp = NULLVP;
333 lowervp = NULLVP;
334 iswhiteout = 0;
335
336 /*
337 * do the lookup in the upper level.
338 * if that level comsumes additional pathnames,
339 * then assume that something special is going
340 * on and just return that vnode.
341 */
342 if (upperdvp != NULLVP) {
343 FIXUP(dun);
344 /*
345 * If we're doing `..' in the underlying filesystem,
346 * we must drop our lock on the union node before
347 * going up the tree in the lower file system--if we block
348 * on the lowervp lock, and that's held by someone else
349 * coming down the tree and who's waiting for our lock,
350 * we would be hosed.
351 */
352 if (cnp->cn_flags & ISDOTDOT) {
353 /* retain lock on underlying VP */
354 dun->un_flags |= UN_KLOCK;
355 VOP_UNLOCK(dvp, 0);
356 }
357 uerror = union_lookup1(um->um_uppervp, &upperdvp,
358 &uppervp, cnp);
359
360 if (cnp->cn_flags & ISDOTDOT) {
361 if (dun->un_uppervp == upperdvp) {
362 /*
363 * we got the underlying bugger back locked...
364 * now take back the union node lock. Since we
365 * hold the uppervp lock, we can diddle union
366 * locking flags at will. :)
367 */
368 dun->un_flags |= UN_ULOCK;
369 }
370 /*
371 * if upperdvp got swapped out, it means we did
372 * some mount point magic, and we do not have
373 * dun->un_uppervp locked currently--so we get it
374 * locked here (don't set the UN_ULOCK flag).
375 */
376 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
377 }
378 if (cnp->cn_consume != 0) {
379 *ap->a_vpp = uppervp;
380 if (!lockparent)
381 cnp->cn_flags &= ~LOCKPARENT;
382 return (uerror);
383 }
384 if (uerror == ENOENT || uerror == EJUSTRETURN) {
385 if (cnp->cn_flags & ISWHITEOUT) {
386 iswhiteout = 1;
387 } else if (lowerdvp != NULLVP) {
388 lerror = VOP_GETATTR(upperdvp, &va,
389 cnp->cn_cred, cnp->cn_lwp);
390 if (lerror == 0 && (va.va_flags & OPAQUE))
391 iswhiteout = 1;
392 }
393 }
394 } else {
395 uerror = ENOENT;
396 }
397
398 /*
399 * in a similar way to the upper layer, do the lookup
400 * in the lower layer. this time, if there is some
401 * component magic going on, then vput whatever we got
402 * back from the upper layer and return the lower vnode
403 * instead.
404 */
405 if (lowerdvp != NULLVP && !iswhiteout) {
406 int nameiop;
407
408 vn_lock(lowerdvp, LK_EXCLUSIVE | LK_RETRY);
409
410 /*
411 * Only do a LOOKUP on the bottom node, since
412 * we won't be making changes to it anyway.
413 */
414 nameiop = cnp->cn_nameiop;
415 cnp->cn_nameiop = LOOKUP;
416 if (um->um_op == UNMNT_BELOW) {
417 saved_cred = cnp->cn_cred;
418 cnp->cn_cred = um->um_cred;
419 }
420 /*
421 * we shouldn't have to worry about locking interactions
422 * between the lower layer and our union layer (w.r.t.
423 * `..' processing) because we don't futz with lowervp
424 * locks in the union-node instantiation code path.
425 */
426 lerror = union_lookup1(um->um_lowervp, &lowerdvp,
427 &lowervp, cnp);
428 if (um->um_op == UNMNT_BELOW)
429 cnp->cn_cred = saved_cred;
430 cnp->cn_nameiop = nameiop;
431
432 if (lowervp != lowerdvp)
433 VOP_UNLOCK(lowerdvp, 0);
434
435 if (cnp->cn_consume != 0) {
436 if (uppervp != NULLVP) {
437 if (uppervp == upperdvp)
438 vrele(uppervp);
439 else
440 vput(uppervp);
441 uppervp = NULLVP;
442 }
443 *ap->a_vpp = lowervp;
444 if (!lockparent)
445 cnp->cn_flags &= ~LOCKPARENT;
446 return (lerror);
447 }
448 } else {
449 lerror = ENOENT;
450 if ((cnp->cn_flags & ISDOTDOT) && dun->un_pvp != NULLVP) {
451 lowervp = LOWERVP(dun->un_pvp);
452 if (lowervp != NULLVP) {
453 VREF(lowervp);
454 vn_lock(lowervp, LK_EXCLUSIVE | LK_RETRY);
455 lerror = 0;
456 }
457 }
458 }
459
460 if (!lockparent)
461 cnp->cn_flags &= ~LOCKPARENT;
462
463 /*
464 * EJUSTRETURN is used by underlying filesystems to indicate that
465 * a directory modification op was started successfully.
466 * This will only happen in the upper layer, since
467 * the lower layer only does LOOKUPs.
468 * If this union is mounted read-only, bounce it now.
469 */
470
471 if ((uerror == EJUSTRETURN) && (cnp->cn_flags & ISLASTCN) &&
472 (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
473 ((cnp->cn_nameiop == CREATE) || (cnp->cn_nameiop == RENAME)))
474 uerror = EROFS;
475
476 /*
477 * at this point, we have uerror and lerror indicating
478 * possible errors with the lookups in the upper and lower
479 * layers. additionally, uppervp and lowervp are (locked)
480 * references to existing vnodes in the upper and lower layers.
481 *
482 * there are now three cases to consider.
483 * 1. if both layers returned an error, then return whatever
484 * error the upper layer generated.
485 *
486 * 2. if the top layer failed and the bottom layer succeeded
487 * then two subcases occur.
488 * a. the bottom vnode is not a directory, in which
489 * case just return a new union vnode referencing
490 * an empty top layer and the existing bottom layer.
491 * b. the bottom vnode is a directory, in which case
492 * create a new directory in the top-level and
493 * continue as in case 3.
494 *
495 * 3. if the top layer succeeded then return a new union
496 * vnode referencing whatever the new top layer and
497 * whatever the bottom layer returned.
498 */
499
500 *ap->a_vpp = NULLVP;
501
502
503 /* case 1. */
504 if ((uerror != 0) && (lerror != 0)) {
505 return (uerror);
506 }
507
508 /* case 2. */
509 if (uerror != 0 /* && (lerror == 0) */ ) {
510 if (lowervp->v_type == VDIR) { /* case 2b. */
511 /*
512 * We may be racing another process to make the
513 * upper-level shadow directory. Be careful with
514 * locks/etc!
515 */
516 if (upperdvp) {
517 dun->un_flags &= ~UN_ULOCK;
518 VOP_UNLOCK(upperdvp, 0);
519 uerror = union_mkshadow(um, upperdvp, cnp,
520 &uppervp);
521 vn_lock(upperdvp, LK_EXCLUSIVE | LK_RETRY);
522 dun->un_flags |= UN_ULOCK;
523 }
524 if (uerror) {
525 if (lowervp != NULLVP) {
526 vput(lowervp);
527 lowervp = NULLVP;
528 }
529 return (uerror);
530 }
531 }
532 }
533
534 if (lowervp != NULLVP)
535 VOP_UNLOCK(lowervp, 0);
536
537 error = union_allocvp(ap->a_vpp, dvp->v_mount, dvp, upperdvp, cnp,
538 uppervp, lowervp, 1);
539
540 if (error) {
541 if (uppervp != NULLVP)
542 vput(uppervp);
543 if (lowervp != NULLVP)
544 vrele(lowervp);
545 } else {
546 if (*ap->a_vpp != dvp)
547 if (!lockparent || !(cnp->cn_flags & ISLASTCN))
548 VOP_UNLOCK(dvp, 0);
549 if (cnp->cn_namelen == 1 &&
550 cnp->cn_nameptr[0] == '.' &&
551 *ap->a_vpp != dvp) {
552 panic("union_lookup -> . (%p) != startdir (%p)",
553 ap->a_vpp, dvp);
554 }
555 }
556
557 return (error);
558 }
559
560 int
561 union_create(v)
562 void *v;
563 {
564 struct vop_create_args /* {
565 struct vnode *a_dvp;
566 struct vnode **a_vpp;
567 struct componentname *a_cnp;
568 struct vattr *a_vap;
569 } */ *ap = v;
570 struct union_node *un = VTOUNION(ap->a_dvp);
571 struct vnode *dvp = un->un_uppervp;
572 struct componentname *cnp = ap->a_cnp;
573
574 if (dvp != NULLVP) {
575 int error;
576 struct vnode *vp;
577 struct mount *mp;
578
579 FIXUP(un);
580
581 VREF(dvp);
582 un->un_flags |= UN_KLOCK;
583 mp = ap->a_dvp->v_mount;
584 vput(ap->a_dvp);
585 error = VOP_CREATE(dvp, &vp, cnp, ap->a_vap);
586 if (error)
587 return (error);
588
589 error = union_allocvp(ap->a_vpp, mp, NULLVP, NULLVP, cnp, vp,
590 NULLVP, 1);
591 if (error)
592 vput(vp);
593 return (error);
594 }
595
596 vput(ap->a_dvp);
597 return (EROFS);
598 }
599
600 int
601 union_whiteout(v)
602 void *v;
603 {
604 struct vop_whiteout_args /* {
605 struct vnode *a_dvp;
606 struct componentname *a_cnp;
607 int a_flags;
608 } */ *ap = v;
609 struct union_node *un = VTOUNION(ap->a_dvp);
610 struct componentname *cnp = ap->a_cnp;
611
612 if (un->un_uppervp == NULLVP)
613 return (EOPNOTSUPP);
614
615 FIXUP(un);
616 return (VOP_WHITEOUT(un->un_uppervp, cnp, ap->a_flags));
617 }
618
619 int
620 union_mknod(v)
621 void *v;
622 {
623 struct vop_mknod_args /* {
624 struct vnode *a_dvp;
625 struct vnode **a_vpp;
626 struct componentname *a_cnp;
627 struct vattr *a_vap;
628 } */ *ap = v;
629 struct union_node *un = VTOUNION(ap->a_dvp);
630 struct vnode *dvp = un->un_uppervp;
631 struct componentname *cnp = ap->a_cnp;
632
633 if (dvp != NULLVP) {
634 int error;
635 struct vnode *vp;
636 struct mount *mp;
637
638 FIXUP(un);
639
640 VREF(dvp);
641 un->un_flags |= UN_KLOCK;
642 mp = ap->a_dvp->v_mount;
643 vput(ap->a_dvp);
644 error = VOP_MKNOD(dvp, &vp, cnp, ap->a_vap);
645 if (error)
646 return (error);
647
648 error = union_allocvp(ap->a_vpp, mp, NULLVP, NULLVP,
649 cnp, vp, NULLVP, 1);
650 if (error)
651 vput(vp);
652 return (error);
653 }
654
655 vput(ap->a_dvp);
656 return (EROFS);
657 }
658
659 int
660 union_open(v)
661 void *v;
662 {
663 struct vop_open_args /* {
664 struct vnodeop_desc *a_desc;
665 struct vnode *a_vp;
666 int a_mode;
667 struct ucred *a_cred;
668 struct lwp *a_l;
669 } */ *ap = v;
670 struct union_node *un = VTOUNION(ap->a_vp);
671 struct vnode *tvp;
672 int mode = ap->a_mode;
673 struct ucred *cred = ap->a_cred;
674 struct lwp *l = ap->a_l;
675 int error;
676
677 /*
678 * If there is an existing upper vp then simply open that.
679 */
680 tvp = un->un_uppervp;
681 if (tvp == NULLVP) {
682 /*
683 * If the lower vnode is being opened for writing, then
684 * copy the file contents to the upper vnode and open that,
685 * otherwise can simply open the lower vnode.
686 */
687 tvp = un->un_lowervp;
688 if ((ap->a_mode & FWRITE) && (tvp->v_type == VREG)) {
689 error = union_copyup(un, (mode&O_TRUNC) == 0, cred, l);
690 if (error == 0)
691 error = VOP_OPEN(un->un_uppervp, mode, cred, l);
692 return (error);
693 }
694
695 /*
696 * Just open the lower vnode, but check for nodev mount flag
697 */
698 if ((tvp->v_type == VBLK || tvp->v_type == VCHR) &&
699 (ap->a_vp->v_mount->mnt_flag & MNT_NODEV))
700 return ENXIO;
701 un->un_openl++;
702 vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY);
703 error = VOP_OPEN(tvp, mode, cred, l);
704 VOP_UNLOCK(tvp, 0);
705
706 return (error);
707 }
708 /*
709 * Just open the upper vnode, checking for nodev mount flag first
710 */
711 if ((tvp->v_type == VBLK || tvp->v_type == VCHR) &&
712 (ap->a_vp->v_mount->mnt_flag & MNT_NODEV))
713 return ENXIO;
714
715 FIXUP(un);
716
717 error = VOP_OPEN(tvp, mode, cred, l);
718
719 return (error);
720 }
721
722 int
723 union_close(v)
724 void *v;
725 {
726 struct vop_close_args /* {
727 struct vnode *a_vp;
728 int a_fflag;
729 struct ucred *a_cred;
730 struct lwp *a_l;
731 } */ *ap = v;
732 struct union_node *un = VTOUNION(ap->a_vp);
733 struct vnode *vp;
734
735 vp = un->un_uppervp;
736 if (vp == NULLVP) {
737 #ifdef UNION_DIAGNOSTIC
738 if (un->un_openl <= 0)
739 panic("union: un_openl cnt");
740 #endif
741 --un->un_openl;
742 vp = un->un_lowervp;
743 }
744
745 #ifdef DIAGNOSTIC
746 if (vp == NULLVP) {
747 vprint("empty union vnode", vp);
748 panic("union_close empty vnode");
749 }
750 #endif
751
752 ap->a_vp = vp;
753 return (VCALL(vp, VOFFSET(vop_close), ap));
754 }
755
756 /*
757 * Check access permission on the union vnode.
758 * The access check being enforced is to check
759 * against both the underlying vnode, and any
760 * copied vnode. This ensures that no additional
761 * file permissions are given away simply because
762 * the user caused an implicit file copy.
763 */
764 int
765 union_access(v)
766 void *v;
767 {
768 struct vop_access_args /* {
769 struct vnodeop_desc *a_desc;
770 struct vnode *a_vp;
771 int a_mode;
772 struct ucred *a_cred;
773 struct lwp *a_l;
774 } */ *ap = v;
775 struct vnode *vp = ap->a_vp;
776 struct union_node *un = VTOUNION(vp);
777 int error = EACCES;
778 struct union_mount *um = MOUNTTOUNIONMOUNT(vp->v_mount);
779
780 /*
781 * Disallow write attempts on read-only file systems;
782 * unless the file is a socket, fifo, or a block or
783 * character device resident on the file system.
784 */
785 if (ap->a_mode & VWRITE) {
786 switch (vp->v_type) {
787 case VDIR:
788 case VLNK:
789 case VREG:
790 if (vp->v_mount->mnt_flag & MNT_RDONLY)
791 return (EROFS);
792 break;
793 case VBAD:
794 case VBLK:
795 case VCHR:
796 case VSOCK:
797 case VFIFO:
798 case VNON:
799 default:
800 break;
801 }
802 }
803
804
805 if ((vp = un->un_uppervp) != NULLVP) {
806 FIXUP(un);
807 ap->a_vp = vp;
808 return (VCALL(vp, VOFFSET(vop_access), ap));
809 }
810
811 if ((vp = un->un_lowervp) != NULLVP) {
812 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
813 ap->a_vp = vp;
814 error = VCALL(vp, VOFFSET(vop_access), ap);
815 if (error == 0) {
816 if (um->um_op == UNMNT_BELOW) {
817 ap->a_cred = um->um_cred;
818 error = VCALL(vp, VOFFSET(vop_access), ap);
819 }
820 }
821 VOP_UNLOCK(vp, 0);
822 if (error)
823 return (error);
824 }
825
826 return (error);
827 }
828
829 /*
830 * We handle getattr only to change the fsid and
831 * track object sizes
832 */
833 int
834 union_getattr(v)
835 void *v;
836 {
837 struct vop_getattr_args /* {
838 struct vnode *a_vp;
839 struct vattr *a_vap;
840 struct ucred *a_cred;
841 struct lwp *a_l;
842 } */ *ap = v;
843 int error;
844 struct union_node *un = VTOUNION(ap->a_vp);
845 struct vnode *vp = un->un_uppervp;
846 struct vattr *vap;
847 struct vattr va;
848
849
850 /*
851 * Some programs walk the filesystem hierarchy by counting
852 * links to directories to avoid stat'ing all the time.
853 * This means the link count on directories needs to be "correct".
854 * The only way to do that is to call getattr on both layers
855 * and fix up the link count. The link count will not necessarily
856 * be accurate but will be large enough to defeat the tree walkers.
857 *
858 * To make life more interesting, some filesystems don't keep
859 * track of link counts in the expected way, and return a
860 * link count of `1' for those directories; if either of the
861 * component directories returns a link count of `1', we return a 1.
862 */
863
864 vap = ap->a_vap;
865
866 vp = un->un_uppervp;
867 if (vp != NULLVP) {
868 /*
869 * It's not clear whether VOP_GETATTR is to be
870 * called with the vnode locked or not. stat() calls
871 * it with (vp) locked, and fstat calls it with
872 * (vp) unlocked.
873 * In the mean time, compensate here by checking
874 * the union_node's lock flag.
875 */
876 if (un->un_flags & UN_LOCKED)
877 FIXUP(un);
878
879 error = VOP_GETATTR(vp, vap, ap->a_cred, ap->a_l);
880 if (error)
881 return (error);
882 union_newsize(ap->a_vp, vap->va_size, VNOVAL);
883 }
884
885 if (vp == NULLVP) {
886 vp = un->un_lowervp;
887 } else if (vp->v_type == VDIR) {
888 vp = un->un_lowervp;
889 if (vp != NULLVP)
890 vap = &va;
891 } else {
892 vp = NULLVP;
893 }
894
895 if (vp != NULLVP) {
896 error = VOP_GETATTR(vp, vap, ap->a_cred, ap->a_l);
897 if (error)
898 return (error);
899 union_newsize(ap->a_vp, VNOVAL, vap->va_size);
900 }
901
902 if ((vap != ap->a_vap) && (vap->va_type == VDIR)) {
903 /*
904 * Link count manipulation:
905 * - If both return "2", return 2 (no subdirs)
906 * - If one or the other return "1", return "1" (ENOCLUE)
907 */
908 if ((ap->a_vap->va_nlink == 2) &&
909 (vap->va_nlink == 2))
910 ;
911 else if (ap->a_vap->va_nlink != 1) {
912 if (vap->va_nlink == 1)
913 ap->a_vap->va_nlink = 1;
914 else
915 ap->a_vap->va_nlink += vap->va_nlink;
916 }
917 }
918 ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsidx.__fsid_val[0];
919 return (0);
920 }
921
922 int
923 union_setattr(v)
924 void *v;
925 {
926 struct vop_setattr_args /* {
927 struct vnode *a_vp;
928 struct vattr *a_vap;
929 struct ucred *a_cred;
930 struct lwp *a_l;
931 } */ *ap = v;
932 struct vattr *vap = ap->a_vap;
933 struct vnode *vp = ap->a_vp;
934 struct union_node *un = VTOUNION(vp);
935 int error;
936
937 if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
938 vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
939 vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
940 (vp->v_mount->mnt_flag & MNT_RDONLY))
941 return (EROFS);
942 if (vap->va_size != VNOVAL) {
943 switch (vp->v_type) {
944 case VDIR:
945 return (EISDIR);
946 case VCHR:
947 case VBLK:
948 case VSOCK:
949 case VFIFO:
950 break;
951 case VREG:
952 case VLNK:
953 default:
954 /*
955 * Disallow write attempts if the filesystem is
956 * mounted read-only.
957 */
958 if (vp->v_mount->mnt_flag & MNT_RDONLY)
959 return (EROFS);
960 }
961 }
962
963 /*
964 * Handle case of truncating lower object to zero size,
965 * by creating a zero length upper object. This is to
966 * handle the case of open with O_TRUNC and O_CREAT.
967 */
968 if ((un->un_uppervp == NULLVP) &&
969 /* assert(un->un_lowervp != NULLVP) */
970 (un->un_lowervp->v_type == VREG)) {
971 error = union_copyup(un, (vap->va_size != 0),
972 ap->a_cred, ap->a_l);
973 if (error)
974 return (error);
975 }
976
977 /*
978 * Try to set attributes in upper layer,
979 * otherwise return read-only filesystem error.
980 */
981 if (un->un_uppervp != NULLVP) {
982 FIXUP(un);
983 error = VOP_SETATTR(un->un_uppervp, vap,
984 ap->a_cred, ap->a_l);
985 if ((error == 0) && (vap->va_size != VNOVAL))
986 union_newsize(ap->a_vp, vap->va_size, VNOVAL);
987 } else {
988 error = EROFS;
989 }
990
991 return (error);
992 }
993
994 int
995 union_read(v)
996 void *v;
997 {
998 struct vop_read_args /* {
999 struct vnode *a_vp;
1000 struct uio *a_uio;
1001 int a_ioflag;
1002 struct ucred *a_cred;
1003 } */ *ap = v;
1004 int error;
1005 struct vnode *vp = OTHERVP(ap->a_vp);
1006 int dolock = (vp == LOWERVP(ap->a_vp));
1007
1008 if (dolock)
1009 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1010 else
1011 FIXUP(VTOUNION(ap->a_vp));
1012 error = VOP_READ(vp, ap->a_uio, ap->a_ioflag, ap->a_cred);
1013 if (dolock)
1014 VOP_UNLOCK(vp, 0);
1015
1016 /*
1017 * XXX
1018 * perhaps the size of the underlying object has changed under
1019 * our feet. take advantage of the offset information present
1020 * in the uio structure.
1021 */
1022 if (error == 0) {
1023 struct union_node *un = VTOUNION(ap->a_vp);
1024 off_t cur = ap->a_uio->uio_offset;
1025
1026 if (vp == un->un_uppervp) {
1027 if (cur > un->un_uppersz)
1028 union_newsize(ap->a_vp, cur, VNOVAL);
1029 } else {
1030 if (cur > un->un_lowersz)
1031 union_newsize(ap->a_vp, VNOVAL, cur);
1032 }
1033 }
1034
1035 return (error);
1036 }
1037
1038 int
1039 union_write(v)
1040 void *v;
1041 {
1042 struct vop_read_args /* {
1043 struct vnode *a_vp;
1044 struct uio *a_uio;
1045 int a_ioflag;
1046 struct ucred *a_cred;
1047 } */ *ap = v;
1048 int error;
1049 struct vnode *vp;
1050 struct union_node *un = VTOUNION(ap->a_vp);
1051
1052 vp = UPPERVP(ap->a_vp);
1053 if (vp == NULLVP)
1054 panic("union: missing upper layer in write");
1055
1056 FIXUP(un);
1057 error = VOP_WRITE(vp, ap->a_uio, ap->a_ioflag, ap->a_cred);
1058
1059 /*
1060 * the size of the underlying object may be changed by the
1061 * write.
1062 */
1063 if (error == 0) {
1064 off_t cur = ap->a_uio->uio_offset;
1065
1066 if (cur > un->un_uppersz)
1067 union_newsize(ap->a_vp, cur, VNOVAL);
1068 }
1069
1070 return (error);
1071 }
1072
1073 int
1074 union_lease(v)
1075 void *v;
1076 {
1077 struct vop_lease_args /* {
1078 struct vnode *a_vp;
1079 struct lwp *a_l;
1080 struct ucred *a_cred;
1081 int a_flag;
1082 } */ *ap = v;
1083 struct vnode *ovp = OTHERVP(ap->a_vp);
1084
1085 ap->a_vp = ovp;
1086 return (VCALL(ovp, VOFFSET(vop_lease), ap));
1087 }
1088
1089 int
1090 union_ioctl(v)
1091 void *v;
1092 {
1093 struct vop_ioctl_args /* {
1094 struct vnode *a_vp;
1095 int a_command;
1096 void *a_data;
1097 int a_fflag;
1098 struct ucred *a_cred;
1099 struct lwp *a_l;
1100 } */ *ap = v;
1101 struct vnode *ovp = OTHERVP(ap->a_vp);
1102
1103 ap->a_vp = ovp;
1104 return (VCALL(ovp, VOFFSET(vop_ioctl), ap));
1105 }
1106
1107 int
1108 union_poll(v)
1109 void *v;
1110 {
1111 struct vop_poll_args /* {
1112 struct vnode *a_vp;
1113 int a_events;
1114 struct lwp *a_l;
1115 } */ *ap = v;
1116 struct vnode *ovp = OTHERVP(ap->a_vp);
1117
1118 ap->a_vp = ovp;
1119 return (VCALL(ovp, VOFFSET(vop_poll), ap));
1120 }
1121
1122 int
1123 union_revoke(v)
1124 void *v;
1125 {
1126 struct vop_revoke_args /* {
1127 struct vnode *a_vp;
1128 int a_flags;
1129 struct proc *a_p;
1130 } */ *ap = v;
1131 struct vnode *vp = ap->a_vp;
1132
1133 if (UPPERVP(vp))
1134 VOP_REVOKE(UPPERVP(vp), ap->a_flags);
1135 if (LOWERVP(vp))
1136 VOP_REVOKE(LOWERVP(vp), ap->a_flags);
1137 vgone(vp);
1138 return (0);
1139 }
1140
1141 int
1142 union_mmap(v)
1143 void *v;
1144 {
1145 struct vop_mmap_args /* {
1146 struct vnode *a_vp;
1147 int a_fflags;
1148 struct ucred *a_cred;
1149 struct lwp *a_l;
1150 } */ *ap = v;
1151 struct vnode *ovp = OTHERVP(ap->a_vp);
1152
1153 ap->a_vp = ovp;
1154 return (VCALL(ovp, VOFFSET(vop_mmap), ap));
1155 }
1156
1157 int
1158 union_fsync(v)
1159 void *v;
1160 {
1161 struct vop_fsync_args /* {
1162 struct vnode *a_vp;
1163 struct ucred *a_cred;
1164 int a_flags;
1165 off_t offhi;
1166 off_t offlo;
1167 struct lwp *a_l;
1168 } */ *ap = v;
1169 int error = 0;
1170 struct lwp *l;
1171 struct vnode *targetvp;
1172
1173 /*
1174 * If vinvalbuf is calling us, it's a "shallow fsync" -- don't
1175 * bother syncing the underlying vnodes, since (a) they'll be
1176 * fsync'ed when reclaimed and (b) we could deadlock if
1177 * they're locked; otherwise, pass it through to the
1178 * underlying layer.
1179 */
1180 if (ap->a_flags & FSYNC_RECLAIM)
1181 return 0;
1182
1183 targetvp = OTHERVP(ap->a_vp);
1184 l = ap->a_l;
1185
1186 if (targetvp != NULLVP) {
1187 int dolock = (targetvp == LOWERVP(ap->a_vp));
1188
1189 if (dolock)
1190 vn_lock(targetvp, LK_EXCLUSIVE | LK_RETRY);
1191 else
1192 FIXUP(VTOUNION(ap->a_vp));
1193 error = VOP_FSYNC(targetvp, ap->a_cred, ap->a_flags,
1194 ap->a_offlo, ap->a_offhi, l);
1195 if (dolock)
1196 VOP_UNLOCK(targetvp, 0);
1197 }
1198
1199 return (error);
1200 }
1201
1202 int
1203 union_seek(v)
1204 void *v;
1205 {
1206 struct vop_seek_args /* {
1207 struct vnode *a_vp;
1208 off_t a_oldoff;
1209 off_t a_newoff;
1210 struct ucred *a_cred;
1211 } */ *ap = v;
1212 struct vnode *ovp = OTHERVP(ap->a_vp);
1213
1214 ap->a_vp = ovp;
1215 return (VCALL(ovp, VOFFSET(vop_seek), ap));
1216 }
1217
1218 int
1219 union_remove(v)
1220 void *v;
1221 {
1222 struct vop_remove_args /* {
1223 struct vnode *a_dvp;
1224 struct vnode *a_vp;
1225 struct componentname *a_cnp;
1226 } */ *ap = v;
1227 int error;
1228 struct union_node *dun = VTOUNION(ap->a_dvp);
1229 struct union_node *un = VTOUNION(ap->a_vp);
1230 struct componentname *cnp = ap->a_cnp;
1231
1232 if (dun->un_uppervp == NULLVP)
1233 panic("union remove: null upper vnode");
1234
1235 if (un->un_uppervp != NULLVP) {
1236 struct vnode *dvp = dun->un_uppervp;
1237 struct vnode *vp = un->un_uppervp;
1238
1239 FIXUP(dun);
1240 VREF(dvp);
1241 dun->un_flags |= UN_KLOCK;
1242 vput(ap->a_dvp);
1243 FIXUP(un);
1244 VREF(vp);
1245 un->un_flags |= UN_KLOCK;
1246 vput(ap->a_vp);
1247
1248 if (union_dowhiteout(un, cnp->cn_cred, cnp->cn_lwp))
1249 cnp->cn_flags |= DOWHITEOUT;
1250 error = VOP_REMOVE(dvp, vp, cnp);
1251 if (!error)
1252 union_removed_upper(un);
1253 } else {
1254 FIXUP(dun);
1255 error = union_mkwhiteout(
1256 MOUNTTOUNIONMOUNT(UNIONTOV(dun)->v_mount),
1257 dun->un_uppervp, ap->a_cnp, un->un_path);
1258 vput(ap->a_dvp);
1259 vput(ap->a_vp);
1260 }
1261
1262 return (error);
1263 }
1264
1265 int
1266 union_link(v)
1267 void *v;
1268 {
1269 struct vop_link_args /* {
1270 struct vnode *a_dvp;
1271 struct vnode *a_vp;
1272 struct componentname *a_cnp;
1273 } */ *ap = v;
1274 int error = 0;
1275 struct componentname *cnp = ap->a_cnp;
1276 struct lwp *l = cnp->cn_lwp;
1277 struct union_node *dun;
1278 struct vnode *vp;
1279 struct vnode *dvp;
1280
1281 dun = VTOUNION(ap->a_dvp);
1282
1283 #ifdef DIAGNOSTIC
1284 if (!(ap->a_cnp->cn_flags & LOCKPARENT)) {
1285 printf("union_link called without LOCKPARENT set!\n");
1286 error = EIO; /* need some error code for "caller is a bozo" */
1287 } else
1288 #endif
1289
1290
1291 if (ap->a_dvp->v_op != ap->a_vp->v_op) {
1292 vp = ap->a_vp;
1293 } else {
1294 struct union_node *un = VTOUNION(ap->a_vp);
1295 if (un->un_uppervp == NULLVP) {
1296 /*
1297 * Needs to be copied before we can link it.
1298 */
1299 vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
1300 if (dun->un_uppervp == un->un_dirvp) {
1301 dun->un_flags &= ~UN_ULOCK;
1302 VOP_UNLOCK(dun->un_uppervp, 0);
1303 }
1304 error = union_copyup(un, 1, cnp->cn_cred, l);
1305 if (dun->un_uppervp == un->un_dirvp) {
1306 /*
1307 * During copyup, we dropped the lock on the
1308 * dir and invalidated any saved namei lookup
1309 * state for the directory we'll be entering
1310 * the link in. We need to re-run the lookup
1311 * in that directory to reset any state needed
1312 * for VOP_LINK.
1313 * Call relookup on the union-layer to reset
1314 * the state.
1315 */
1316 vp = NULLVP;
1317 if (dun->un_uppervp == NULLVP)
1318 panic("union: null upperdvp?");
1319 /*
1320 * relookup starts with an unlocked node,
1321 * and since LOCKPARENT is set returns
1322 * the starting directory locked.
1323 */
1324 VOP_UNLOCK(ap->a_dvp, 0);
1325 error = relookup(ap->a_dvp, &vp, ap->a_cnp);
1326 if (error) {
1327 vrele(ap->a_dvp);
1328 VOP_UNLOCK(ap->a_vp, 0);
1329 return EROFS; /* ? */
1330 }
1331 if (vp != NULLVP) {
1332 /*
1333 * The name we want to create has
1334 * mysteriously appeared (a race?)
1335 */
1336 error = EEXIST;
1337 VOP_UNLOCK(ap->a_vp, 0);
1338 goto croak;
1339 }
1340 }
1341 VOP_UNLOCK(ap->a_vp, 0);
1342 }
1343 vp = un->un_uppervp;
1344 }
1345
1346 dvp = dun->un_uppervp;
1347 if (dvp == NULLVP)
1348 error = EROFS;
1349
1350 if (error) {
1351 croak:
1352 vput(ap->a_dvp);
1353 return (error);
1354 }
1355
1356 FIXUP(dun);
1357 VREF(dvp);
1358 dun->un_flags |= UN_KLOCK;
1359 vput(ap->a_dvp);
1360
1361 return (VOP_LINK(dvp, vp, cnp));
1362 }
1363
1364 int
1365 union_rename(v)
1366 void *v;
1367 {
1368 struct vop_rename_args /* {
1369 struct vnode *a_fdvp;
1370 struct vnode *a_fvp;
1371 struct componentname *a_fcnp;
1372 struct vnode *a_tdvp;
1373 struct vnode *a_tvp;
1374 struct componentname *a_tcnp;
1375 } */ *ap = v;
1376 int error;
1377
1378 struct vnode *fdvp = ap->a_fdvp;
1379 struct vnode *fvp = ap->a_fvp;
1380 struct vnode *tdvp = ap->a_tdvp;
1381 struct vnode *tvp = ap->a_tvp;
1382
1383 if (fdvp->v_op == union_vnodeop_p) { /* always true */
1384 struct union_node *un = VTOUNION(fdvp);
1385 if (un->un_uppervp == NULLVP) {
1386 /*
1387 * this should never happen in normal
1388 * operation but might if there was
1389 * a problem creating the top-level shadow
1390 * directory.
1391 */
1392 error = EXDEV;
1393 goto bad;
1394 }
1395
1396 fdvp = un->un_uppervp;
1397 VREF(fdvp);
1398 vrele(ap->a_fdvp);
1399 }
1400
1401 if (fvp->v_op == union_vnodeop_p) { /* always true */
1402 struct union_node *un = VTOUNION(fvp);
1403 if (un->un_uppervp == NULLVP) {
1404 /* XXX: should do a copyup */
1405 error = EXDEV;
1406 goto bad;
1407 }
1408
1409 if (un->un_lowervp != NULLVP)
1410 ap->a_fcnp->cn_flags |= DOWHITEOUT;
1411
1412 fvp = un->un_uppervp;
1413 VREF(fvp);
1414 vrele(ap->a_fvp);
1415 }
1416
1417 if (tdvp->v_op == union_vnodeop_p) {
1418 struct union_node *un = VTOUNION(tdvp);
1419 if (un->un_uppervp == NULLVP) {
1420 /*
1421 * this should never happen in normal
1422 * operation but might if there was
1423 * a problem creating the top-level shadow
1424 * directory.
1425 */
1426 error = EXDEV;
1427 goto bad;
1428 }
1429
1430 tdvp = un->un_uppervp;
1431 VREF(tdvp);
1432 un->un_flags |= UN_KLOCK;
1433 vput(ap->a_tdvp);
1434 }
1435
1436 if (tvp != NULLVP && tvp->v_op == union_vnodeop_p) {
1437 struct union_node *un = VTOUNION(tvp);
1438
1439 tvp = un->un_uppervp;
1440 if (tvp != NULLVP) {
1441 VREF(tvp);
1442 un->un_flags |= UN_KLOCK;
1443 }
1444 vput(ap->a_tvp);
1445 }
1446
1447 return (VOP_RENAME(fdvp, fvp, ap->a_fcnp, tdvp, tvp, ap->a_tcnp));
1448
1449 bad:
1450 vrele(fdvp);
1451 vrele(fvp);
1452 vput(tdvp);
1453 if (tvp != NULLVP)
1454 vput(tvp);
1455
1456 return (error);
1457 }
1458
1459 int
1460 union_mkdir(v)
1461 void *v;
1462 {
1463 struct vop_mkdir_args /* {
1464 struct vnode *a_dvp;
1465 struct vnode **a_vpp;
1466 struct componentname *a_cnp;
1467 struct vattr *a_vap;
1468 } */ *ap = v;
1469 struct union_node *un = VTOUNION(ap->a_dvp);
1470 struct vnode *dvp = un->un_uppervp;
1471 struct componentname *cnp = ap->a_cnp;
1472
1473 if (dvp != NULLVP) {
1474 int error;
1475 struct vnode *vp;
1476
1477 FIXUP(un);
1478 VREF(dvp);
1479 un->un_flags |= UN_KLOCK;
1480 VOP_UNLOCK(ap->a_dvp, 0);
1481 error = VOP_MKDIR(dvp, &vp, cnp, ap->a_vap);
1482 if (error) {
1483 vrele(ap->a_dvp);
1484 return (error);
1485 }
1486
1487 error = union_allocvp(ap->a_vpp, ap->a_dvp->v_mount, ap->a_dvp,
1488 NULLVP, cnp, vp, NULLVP, 1);
1489 vrele(ap->a_dvp);
1490 if (error)
1491 vput(vp);
1492 return (error);
1493 }
1494
1495 vput(ap->a_dvp);
1496 return (EROFS);
1497 }
1498
1499 int
1500 union_rmdir(v)
1501 void *v;
1502 {
1503 struct vop_rmdir_args /* {
1504 struct vnode *a_dvp;
1505 struct vnode *a_vp;
1506 struct componentname *a_cnp;
1507 } */ *ap = v;
1508 int error;
1509 struct union_node *dun = VTOUNION(ap->a_dvp);
1510 struct union_node *un = VTOUNION(ap->a_vp);
1511 struct componentname *cnp = ap->a_cnp;
1512
1513 if (dun->un_uppervp == NULLVP)
1514 panic("union rmdir: null upper vnode");
1515
1516 if (un->un_uppervp != NULLVP) {
1517 struct vnode *dvp = dun->un_uppervp;
1518 struct vnode *vp = un->un_uppervp;
1519
1520 FIXUP(dun);
1521 VREF(dvp);
1522 dun->un_flags |= UN_KLOCK;
1523 vput(ap->a_dvp);
1524 FIXUP(un);
1525 VREF(vp);
1526 un->un_flags |= UN_KLOCK;
1527 vput(ap->a_vp);
1528
1529 if (union_dowhiteout(un, cnp->cn_cred, cnp->cn_lwp))
1530 cnp->cn_flags |= DOWHITEOUT;
1531 error = VOP_RMDIR(dvp, vp, ap->a_cnp);
1532 if (!error)
1533 union_removed_upper(un);
1534 } else {
1535 FIXUP(dun);
1536 error = union_mkwhiteout(
1537 MOUNTTOUNIONMOUNT(UNIONTOV(dun)->v_mount),
1538 dun->un_uppervp, ap->a_cnp, un->un_path);
1539 vput(ap->a_dvp);
1540 vput(ap->a_vp);
1541 }
1542
1543 return (error);
1544 }
1545
1546 int
1547 union_symlink(v)
1548 void *v;
1549 {
1550 struct vop_symlink_args /* {
1551 struct vnode *a_dvp;
1552 struct vnode **a_vpp;
1553 struct componentname *a_cnp;
1554 struct vattr *a_vap;
1555 char *a_target;
1556 } */ *ap = v;
1557 struct union_node *un = VTOUNION(ap->a_dvp);
1558 struct vnode *dvp = un->un_uppervp;
1559 struct componentname *cnp = ap->a_cnp;
1560
1561 if (dvp != NULLVP) {
1562 int error;
1563
1564 FIXUP(un);
1565 VREF(dvp);
1566 un->un_flags |= UN_KLOCK;
1567 vput(ap->a_dvp);
1568 error = VOP_SYMLINK(dvp, ap->a_vpp, cnp, ap->a_vap,
1569 ap->a_target);
1570 return (error);
1571 }
1572
1573 vput(ap->a_dvp);
1574 return (EROFS);
1575 }
1576
1577 /*
1578 * union_readdir works in concert with getdirentries and
1579 * readdir(3) to provide a list of entries in the unioned
1580 * directories. getdirentries is responsible for walking
1581 * down the union stack. readdir(3) is responsible for
1582 * eliminating duplicate names from the returned data stream.
1583 */
1584 int
1585 union_readdir(v)
1586 void *v;
1587 {
1588 struct vop_readdir_args /* {
1589 struct vnodeop_desc *a_desc;
1590 struct vnode *a_vp;
1591 struct uio *a_uio;
1592 struct ucred *a_cred;
1593 int *a_eofflag;
1594 u_long *a_cookies;
1595 int a_ncookies;
1596 } */ *ap = v;
1597 struct union_node *un = VTOUNION(ap->a_vp);
1598 struct vnode *uvp = un->un_uppervp;
1599
1600 if (uvp == NULLVP)
1601 return (0);
1602
1603 FIXUP(un);
1604 ap->a_vp = uvp;
1605 return (VCALL(uvp, VOFFSET(vop_readdir), ap));
1606 }
1607
1608 int
1609 union_readlink(v)
1610 void *v;
1611 {
1612 struct vop_readlink_args /* {
1613 struct vnode *a_vp;
1614 struct uio *a_uio;
1615 struct ucred *a_cred;
1616 } */ *ap = v;
1617 int error;
1618 struct vnode *vp = OTHERVP(ap->a_vp);
1619 int dolock = (vp == LOWERVP(ap->a_vp));
1620
1621 if (dolock)
1622 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1623 else
1624 FIXUP(VTOUNION(ap->a_vp));
1625 ap->a_vp = vp;
1626 error = VCALL(vp, VOFFSET(vop_readlink), ap);
1627 if (dolock)
1628 VOP_UNLOCK(vp, 0);
1629
1630 return (error);
1631 }
1632
1633 int
1634 union_abortop(v)
1635 void *v;
1636 {
1637 struct vop_abortop_args /* {
1638 struct vnode *a_dvp;
1639 struct componentname *a_cnp;
1640 } */ *ap = v;
1641 int error;
1642 struct vnode *vp = OTHERVP(ap->a_dvp);
1643 struct union_node *un = VTOUNION(ap->a_dvp);
1644 int islocked = un->un_flags & UN_LOCKED;
1645 int dolock = (vp == LOWERVP(ap->a_dvp));
1646
1647 if (islocked) {
1648 if (dolock)
1649 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1650 else
1651 FIXUP(VTOUNION(ap->a_dvp));
1652 }
1653 ap->a_dvp = vp;
1654 error = VCALL(vp, VOFFSET(vop_abortop), ap);
1655 if (islocked && dolock)
1656 VOP_UNLOCK(vp, 0);
1657
1658 return (error);
1659 }
1660
1661 int
1662 union_inactive(v)
1663 void *v;
1664 {
1665 struct vop_inactive_args /* {
1666 const struct vnodeop_desc *a_desc;
1667 struct vnode *a_vp;
1668 struct lwp *a_l;
1669 } */ *ap = v;
1670 struct vnode *vp = ap->a_vp;
1671 struct union_node *un = VTOUNION(vp);
1672 struct vnode **vpp;
1673
1674 /*
1675 * Do nothing (and _don't_ bypass).
1676 * Wait to vrele lowervp until reclaim,
1677 * so that until then our union_node is in the
1678 * cache and reusable.
1679 *
1680 * NEEDSWORK: Someday, consider inactive'ing
1681 * the lowervp and then trying to reactivate it
1682 * with capabilities (v_id)
1683 * like they do in the name lookup cache code.
1684 * That's too much work for now.
1685 */
1686
1687 if (un->un_dircache != 0) {
1688 for (vpp = un->un_dircache; *vpp != NULLVP; vpp++)
1689 vrele(*vpp);
1690 free(un->un_dircache, M_TEMP);
1691 un->un_dircache = 0;
1692 }
1693
1694 VOP_UNLOCK(vp, 0);
1695
1696 if ((un->un_flags & UN_CACHED) == 0)
1697 vgone(vp);
1698
1699 return (0);
1700 }
1701
1702 int
1703 union_reclaim(v)
1704 void *v;
1705 {
1706 struct vop_reclaim_args /* {
1707 struct vnode *a_vp;
1708 } */ *ap = v;
1709
1710 union_freevp(ap->a_vp);
1711
1712 return (0);
1713 }
1714
1715 int
1716 union_lock(v)
1717 void *v;
1718 {
1719 struct vop_lock_args /* {
1720 struct vnode *a_vp;
1721 int a_flags;
1722 } */ *ap = v;
1723 struct vnode *vp = ap->a_vp;
1724 int flags = ap->a_flags;
1725 struct union_node *un;
1726 int error;
1727 #ifdef DIAGNOSTIC
1728 int drain = 0;
1729 #endif
1730
1731 genfs_nolock(ap);
1732 /*
1733 * Need to do real lockmgr-style locking here.
1734 * in the mean time, draining won't work quite right,
1735 * which could lead to a few race conditions.
1736 * the following test was here, but is not quite right, we
1737 * still need to take the lock:
1738 if ((flags & LK_TYPE_MASK) == LK_DRAIN)
1739 return (0);
1740 */
1741 flags &= ~LK_INTERLOCK;
1742
1743 un = VTOUNION(vp);
1744 #ifdef DIAGNOSTIC
1745 if (un->un_flags & (UN_DRAINING|UN_DRAINED)) {
1746 if (un->un_flags & UN_DRAINED)
1747 panic("union: %p: warning: locking decommissioned lock", vp);
1748 if ((flags & LK_TYPE_MASK) != LK_RELEASE)
1749 panic("union: %p: non-release on draining lock: %d",
1750 vp, flags & LK_TYPE_MASK);
1751 un->un_flags &= ~UN_DRAINING;
1752 if ((flags & LK_REENABLE) == 0)
1753 un->un_flags |= UN_DRAINED;
1754 }
1755 #endif
1756
1757 /*
1758 * Don't pass DRAIN through to sub-vnode lock; keep track of
1759 * DRAIN state at this level, and just get an exclusive lock
1760 * on the underlying vnode.
1761 */
1762 if ((flags & LK_TYPE_MASK) == LK_DRAIN) {
1763 #ifdef DIAGNOSTIC
1764 drain = 1;
1765 #endif
1766 flags = LK_EXCLUSIVE | (flags & ~LK_TYPE_MASK);
1767 }
1768 start:
1769 un = VTOUNION(vp);
1770
1771 if (un->un_uppervp != NULLVP) {
1772 if (((un->un_flags & UN_ULOCK) == 0) &&
1773 (vp->v_usecount != 0)) {
1774 /*
1775 * We MUST always use the order of: take upper
1776 * vp lock, manipulate union node flags, drop
1777 * upper vp lock. This code must not be an
1778 */
1779 error = vn_lock(un->un_uppervp, flags);
1780 if (error)
1781 return (error);
1782 un->un_flags |= UN_ULOCK;
1783 }
1784 #ifdef DIAGNOSTIC
1785 if (un->un_flags & UN_KLOCK) {
1786 vprint("union: dangling klock", vp);
1787 panic("union: dangling upper lock (%p)", vp);
1788 }
1789 #endif
1790 }
1791
1792 /* XXX ignores LK_NOWAIT */
1793 if (un->un_flags & UN_LOCKED) {
1794 #ifdef DIAGNOSTIC
1795 if (curproc && un->un_pid == curproc->p_pid &&
1796 un->un_pid > -1 && curproc->p_pid > -1)
1797 panic("union: locking against myself");
1798 #endif
1799 un->un_flags |= UN_WANTED;
1800 tsleep(&un->un_flags, PINOD, "unionlk2", 0);
1801 goto start;
1802 }
1803
1804 #ifdef DIAGNOSTIC
1805 if (curproc)
1806 un->un_pid = curproc->p_pid;
1807 else
1808 un->un_pid = -1;
1809 if (drain)
1810 un->un_flags |= UN_DRAINING;
1811 #endif
1812
1813 un->un_flags |= UN_LOCKED;
1814 return (0);
1815 }
1816
1817 /*
1818 * When operations want to vput() a union node yet retain a lock on
1819 * the upper vnode (say, to do some further operations like link(),
1820 * mkdir(), ...), they set UN_KLOCK on the union node, then call
1821 * vput() which calls VOP_UNLOCK() and comes here. union_unlock()
1822 * unlocks the union node (leaving the upper vnode alone), clears the
1823 * KLOCK flag, and then returns to vput(). The caller then does whatever
1824 * is left to do with the upper vnode, and ensures that it gets unlocked.
1825 *
1826 * If UN_KLOCK isn't set, then the upper vnode is unlocked here.
1827 */
1828 int
1829 union_unlock(v)
1830 void *v;
1831 {
1832 struct vop_unlock_args /* {
1833 struct vnode *a_vp;
1834 int a_flags;
1835 } */ *ap = v;
1836 struct union_node *un = VTOUNION(ap->a_vp);
1837
1838 #ifdef DIAGNOSTIC
1839 if ((un->un_flags & UN_LOCKED) == 0)
1840 panic("union: unlock unlocked node");
1841 if (curproc && un->un_pid != curproc->p_pid &&
1842 curproc->p_pid > -1 && un->un_pid > -1)
1843 panic("union: unlocking other process's union node");
1844 if (un->un_flags & UN_DRAINED)
1845 panic("union: %p: warning: unlocking decommissioned lock", ap->a_vp);
1846 #endif
1847
1848 un->un_flags &= ~UN_LOCKED;
1849
1850 if ((un->un_flags & (UN_ULOCK|UN_KLOCK)) == UN_ULOCK)
1851 VOP_UNLOCK(un->un_uppervp, 0);
1852
1853 un->un_flags &= ~(UN_ULOCK|UN_KLOCK);
1854
1855 if (un->un_flags & UN_WANTED) {
1856 un->un_flags &= ~UN_WANTED;
1857 wakeup( &un->un_flags);
1858 }
1859
1860 #ifdef DIAGNOSTIC
1861 un->un_pid = 0;
1862 if (un->un_flags & UN_DRAINING) {
1863 un->un_flags |= UN_DRAINED;
1864 un->un_flags &= ~UN_DRAINING;
1865 }
1866 #endif
1867 genfs_nounlock(ap);
1868
1869 return (0);
1870 }
1871
1872 int
1873 union_bmap(v)
1874 void *v;
1875 {
1876 struct vop_bmap_args /* {
1877 struct vnode *a_vp;
1878 daddr_t a_bn;
1879 struct vnode **a_vpp;
1880 daddr_t *a_bnp;
1881 int *a_runp;
1882 } */ *ap = v;
1883 int error;
1884 struct vnode *vp = OTHERVP(ap->a_vp);
1885 int dolock = (vp == LOWERVP(ap->a_vp));
1886
1887 if (dolock)
1888 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1889 else
1890 FIXUP(VTOUNION(ap->a_vp));
1891 ap->a_vp = vp;
1892 error = VCALL(vp, VOFFSET(vop_bmap), ap);
1893 if (dolock)
1894 VOP_UNLOCK(vp, 0);
1895
1896 return (error);
1897 }
1898
1899 int
1900 union_print(v)
1901 void *v;
1902 {
1903 struct vop_print_args /* {
1904 struct vnode *a_vp;
1905 } */ *ap = v;
1906 struct vnode *vp = ap->a_vp;
1907
1908 printf("\ttag VT_UNION, vp=%p, uppervp=%p, lowervp=%p\n",
1909 vp, UPPERVP(vp), LOWERVP(vp));
1910 if (UPPERVP(vp) != NULLVP)
1911 vprint("union: upper", UPPERVP(vp));
1912 if (LOWERVP(vp) != NULLVP)
1913 vprint("union: lower", LOWERVP(vp));
1914 if (VTOUNION(vp)->un_dircache) {
1915 struct vnode **vpp;
1916 for (vpp = VTOUNION(vp)->un_dircache; *vpp != NULLVP; vpp++)
1917 vprint("dircache:", *vpp);
1918 }
1919
1920 return (0);
1921 }
1922
1923 int
1924 union_islocked(v)
1925 void *v;
1926 {
1927 struct vop_islocked_args /* {
1928 struct vnode *a_vp;
1929 } */ *ap = v;
1930
1931 return ((VTOUNION(ap->a_vp)->un_flags & UN_LOCKED) ? 1 : 0);
1932 }
1933
1934 int
1935 union_pathconf(v)
1936 void *v;
1937 {
1938 struct vop_pathconf_args /* {
1939 struct vnode *a_vp;
1940 int a_name;
1941 int *a_retval;
1942 } */ *ap = v;
1943 int error;
1944 struct vnode *vp = OTHERVP(ap->a_vp);
1945 int dolock = (vp == LOWERVP(ap->a_vp));
1946
1947 if (dolock)
1948 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1949 else
1950 FIXUP(VTOUNION(ap->a_vp));
1951 ap->a_vp = vp;
1952 error = VCALL(vp, VOFFSET(vop_pathconf), ap);
1953 if (dolock)
1954 VOP_UNLOCK(vp, 0);
1955
1956 return (error);
1957 }
1958
1959 int
1960 union_advlock(v)
1961 void *v;
1962 {
1963 struct vop_advlock_args /* {
1964 struct vnode *a_vp;
1965 void *a_id;
1966 int a_op;
1967 struct flock *a_fl;
1968 int a_flags;
1969 } */ *ap = v;
1970 struct vnode *ovp = OTHERVP(ap->a_vp);
1971
1972 ap->a_vp = ovp;
1973 return (VCALL(ovp, VOFFSET(vop_advlock), ap));
1974 }
1975
1976
1977 /*
1978 * XXX - vop_strategy must be hand coded because it has no
1979 * vnode in its arguments.
1980 * This goes away with a merged VM/buffer cache.
1981 */
1982 int
1983 union_strategy(v)
1984 void *v;
1985 {
1986 struct vop_strategy_args /* {
1987 struct vnode *a_vp;
1988 struct buf *a_bp;
1989 } */ *ap = v;
1990 struct vnode *ovp = OTHERVP(ap->a_vp);
1991 struct buf *bp = ap->a_bp;
1992
1993 #ifdef DIAGNOSTIC
1994 if (ovp == NULLVP)
1995 panic("union_strategy: nil vp");
1996 if (((bp->b_flags & B_READ) == 0) &&
1997 (ovp == LOWERVP(bp->b_vp)))
1998 panic("union_strategy: writing to lowervp");
1999 #endif
2000
2001 return (VOP_STRATEGY(ovp, bp));
2002 }
2003
2004 int
2005 union_getpages(v)
2006 void *v;
2007 {
2008 struct vop_getpages_args /* {
2009 struct vnode *a_vp;
2010 voff_t a_offset;
2011 struct vm_page **a_m;
2012 int *a_count;
2013 int a_centeridx;
2014 vm_prot_t a_access_type;
2015 int a_advice;
2016 int a_flags;
2017 } */ *ap = v;
2018 struct vnode *vp = ap->a_vp;
2019 int error;
2020
2021 /*
2022 * just pass the request on to the underlying layer.
2023 */
2024
2025 if (ap->a_flags & PGO_LOCKED) {
2026 return EBUSY;
2027 }
2028 ap->a_vp = OTHERVP(vp);
2029 simple_unlock(&vp->v_interlock);
2030 simple_lock(&ap->a_vp->v_interlock);
2031 error = VCALL(ap->a_vp, VOFFSET(vop_getpages), ap);
2032 return error;
2033 }
2034
2035 int
2036 union_putpages(v)
2037 void *v;
2038 {
2039 struct vop_putpages_args /* {
2040 struct vnode *a_vp;
2041 voff_t a_offlo;
2042 voff_t a_offhi;
2043 int a_flags;
2044 } */ *ap = v;
2045 struct vnode *vp = ap->a_vp;
2046 int error;
2047
2048 /*
2049 * just pass the request on to the underlying layer.
2050 */
2051
2052 ap->a_vp = OTHERVP(vp);
2053 simple_unlock(&vp->v_interlock);
2054 simple_lock(&ap->a_vp->v_interlock);
2055 error = VCALL(ap->a_vp, VOFFSET(vop_putpages), ap);
2056 return error;
2057 }
2058
2059 int
2060 union_kqfilter(void *v)
2061 {
2062 struct vop_kqfilter_args /* {
2063 struct vnode *a_vp;
2064 struct knote *a_kn;
2065 } */ *ap = v;
2066 int error;
2067
2068 /*
2069 * We watch either the upper layer file (if it already exists),
2070 * or the lower layer one. If there is lower layer file only
2071 * at this moment, we will keep watching that lower layer file
2072 * even if upper layer file would be created later on.
2073 */
2074 if (UPPERVP(ap->a_vp))
2075 error = VOP_KQFILTER(UPPERVP(ap->a_vp), ap->a_kn);
2076 else if (LOWERVP(ap->a_vp))
2077 error = VOP_KQFILTER(LOWERVP(ap->a_vp), ap->a_kn);
2078 else {
2079 /* panic? */
2080 error = EOPNOTSUPP;
2081 }
2082
2083 return (error);
2084 }
2085