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