View | Details | Raw Unified | Return to bug 27250
Collapse All | Expand All

(-)src/sys/kern/vfs_syscalls.c (-2 / +8 lines)
Lines 81-87 Link Here
81
    const struct timespec *, int));
81
    const struct timespec *, int));
82
static int	usermount = 0;	/* if 1, non-root can mount fs. */
82
static int	usermount = 0;	/* if 1, non-root can mount fs. */
83
83
84
/*
84
int (*union_dircheckp) __P((struct proc *, struct vnode **, struct file *));
85
int (*union_dircheckp) __P((struct proc *, struct vnode **, struct file *));
86
*/
85
87
86
SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, "");
88
SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, "");
87
89
Lines 2854-2860 Link Here
2854
	if ((fp->f_flag & FREAD) == 0)
2859
	if ((fp->f_flag & FREAD) == 0)
2855
		return (EBADF);
2860
		return (EBADF);
2856
	vp = (struct vnode *)fp->f_data;
2861
	vp = (struct vnode *)fp->f_data;
2857
unionread:
2862
/*unionread:*/
2858
	if (vp->v_type != VDIR)
2863
	if (vp->v_type != VDIR)
2859
		return (EINVAL);
2864
		return (EINVAL);
2860
	aiov.iov_base = SCARG(uap, buf);
2865
	aiov.iov_base = SCARG(uap, buf);
Lines 2921-2926 Link Here
2921
	VOP_UNLOCK(vp, 0, p);
2926
	VOP_UNLOCK(vp, 0, p);
2922
	if (error)
2927
	if (error)
2923
		return (error);
2928
		return (error);
2929
/*
2924
	if (SCARG(uap, count) == auio.uio_resid) {
2930
	if (SCARG(uap, count) == auio.uio_resid) {
2925
		if (union_dircheckp) {
2931
		if (union_dircheckp) {
2926
			error = union_dircheckp(p, &vp, fp);
2932
			error = union_dircheckp(p, &vp, fp);
Lines 2940-2945 Link Here
2940
			goto unionread;
2946
			goto unionread;
2941
		}
2947
		}
2942
	}
2948
	}
2949
*/
2943
	error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
2950
	error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
2944
	    sizeof(long));
2951
	    sizeof(long));
2945
	p->p_retval[0] = SCARG(uap, count) - auio.uio_resid;
2952
	p->p_retval[0] = SCARG(uap, count) - auio.uio_resid;
Lines 2980-2986 Link Here
2980
	if ((fp->f_flag & FREAD) == 0)
2987
	if ((fp->f_flag & FREAD) == 0)
2981
		return (EBADF);
2988
		return (EBADF);
2982
	vp = (struct vnode *)fp->f_data;
2989
	vp = (struct vnode *)fp->f_data;
2983
unionread:
2990
/*unionread:*/
2984
	if (vp->v_type != VDIR)
2991
	if (vp->v_type != VDIR)
2985
		return (EINVAL);
2992
		return (EINVAL);
2986
	aiov.iov_base = SCARG(uap, buf);
2993
	aiov.iov_base = SCARG(uap, buf);
Lines 2999-3004 Link Here
2999
	VOP_UNLOCK(vp, 0, p);
3006
	VOP_UNLOCK(vp, 0, p);
3000
	if (error)
3007
	if (error)
3001
		return (error);
3008
		return (error);
3009
/*
3002
	if (SCARG(uap, count) == auio.uio_resid) {
3010
	if (SCARG(uap, count) == auio.uio_resid) {
3003
		if (union_dircheckp) {
3011
		if (union_dircheckp) {
3004
			error = union_dircheckp(p, &vp, fp);
3012
			error = union_dircheckp(p, &vp, fp);
Lines 3018-3023 Link Here
3018
			goto unionread;
3026
			goto unionread;
3019
		}
3027
		}
3020
	}
3028
	}
3029
*/
3021
	if (SCARG(uap, basep) != NULL) {
3030
	if (SCARG(uap, basep) != NULL) {
3022
		error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
3031
		error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
3023
		    sizeof(long));
3032
		    sizeof(long));
(-)src/sys/vm/vm_mmap.c (-1 / +12 lines)
Lines 78-83 Link Here
78
#include <vm/vm_page.h>
78
#include <vm/vm_page.h>
79
#include <vm/vm_kern.h>
79
#include <vm/vm_kern.h>
80
80
81
#include <miscfs/union/union.h>
82
81
#ifndef _SYS_SYSPROTO_H_
83
#ifndef _SYS_SYSPROTO_H_
82
struct sbrk_args {
84
struct sbrk_args {
83
	int incr;
85
	int incr;
Lines 1074-1079 Link Here
1074
	/*
1076
	/*
1075
	 * Lookup/allocate object.
1077
	 * Lookup/allocate object.
1076
	 */
1078
	 */
1079
        vp = (struct vnode *) handle;
1080
#if 1
1081
        if( vp ) {
1082
                while( vp->v_tag == VT_UNION) {
1083
                        vp = OTHERVP(vp);
1084
                }
1085
                handle = (void *)vp;
1086
        }
1087
#endif
1077
	if (flags & MAP_ANON) {
1088
	if (flags & MAP_ANON) {
1078
		type = OBJT_DEFAULT;
1089
		type = OBJT_DEFAULT;
1079
		/*
1090
		/*
Lines 1082-1088 Link Here
1082
		if (handle == 0)
1093
		if (handle == 0)
1083
			foff = 0;
1094
			foff = 0;
1084
	} else {
1095
	} else {
1085
		vp = (struct vnode *) handle;
1096
/*		vp = (struct vnode *) handle; */
1086
		if (vp->v_type == VCHR) {
1097
		if (vp->v_type == VCHR) {
1087
			type = OBJT_DEVICE;
1098
			type = OBJT_DEVICE;
1088
			handle = (void *)(intptr_t)vp->v_rdev;
1099
			handle = (void *)(intptr_t)vp->v_rdev;
(-)src/sys/miscfs/union/union.h (+3 lines)
Lines 97-102 Link Here
97
#endif
103
#endif
98
};
104
};
99
105
106
#define DOCACHE		1	/*union_allocvp argument: default "1"*/
107
108
#define UPPERLOCK	0	/* Need uppervp to lock */
100
/*
109
/*
101
 * XXX UN_ULOCK -	indicates that the uppervp is locked
110
 * XXX UN_ULOCK -	indicates that the uppervp is locked
102
 *
111
 *
(-)src/sys/miscfs/union/union_subr.c (-1 / +15 lines)
Lines 343-349 Link Here
343
{
344
{
344
	int error;
345
	int error;
345
	struct union_node *un = 0;
346
	struct union_node *un = 0;
347
/*
346
	struct vnode *xlowervp = NULLVP;
348
	struct vnode *xlowervp = NULLVP;
349
*/
347
	struct union_mount *um = MOUNTTOUNIONMOUNT(mp);
350
	struct union_mount *um = MOUNTTOUNIONMOUNT(mp);
348
	struct proc *p = (cnp) ? cnp->cn_proc : curproc;
351
	struct proc *p = (cnp) ? cnp->cn_proc : curproc;
349
	int hash = 0;
352
	int hash = 0;
Lines 354-360 Link Here
354
		panic("union: unidentifiable allocation");
357
		panic("union: unidentifiable allocation");
355
358
356
	if (uppervp && lowervp && (uppervp->v_type != lowervp->v_type)) {
359
	if (uppervp && lowervp && (uppervp->v_type != lowervp->v_type)) {
360
/*
357
		xlowervp = lowervp;
361
		xlowervp = lowervp;
362
*/
363
		vrele(lowervp);
358
		lowervp = NULLVP;
364
		lowervp = NULLVP;
359
	}
365
	}
360
366
Lines 597-604 Link Here
597
	}
603
	}
598
604
599
out:
605
out:
606
/*
600
	if (xlowervp)
607
	if (xlowervp)
601
		vrele(xlowervp);
608
		vrele(xlowervp);
609
*/
602
610
603
	if (docache)
611
	if (docache)
604
		union_list_unlock(hash);
612
		union_list_unlock(hash);
Lines 1304-1309 Link Here
1304
/*
1324
/*
1305
 * Module glue to remove #ifdef UNION from vfs_syscalls.c
1325
 * Module glue to remove #ifdef UNION from vfs_syscalls.c
1306
 */
1326
 */
1327
#ifdef NEED_BAD_HACK
1307
static int
1328
static int
1308
union_dircheck(struct proc *p, struct vnode **vp, struct file *fp)
1329
union_dircheck(struct proc *p, struct vnode **vp, struct file *fp)
1309
{
1330
{
Lines 1312-1317 Link Here
1312
	if ((*vp)->v_op == union_vnodeop_p) {
1333
	if ((*vp)->v_op == union_vnodeop_p) {
1313
		struct vnode *lvp;
1334
		struct vnode *lvp;
1314
1335
1336
		if(LOWERVP(*vp) == NULL) {
1337
			return 0;
1338
		}
1315
		lvp = union_dircache(*vp, p);
1339
		lvp = union_dircache(*vp, p);
1316
		if (lvp != NULLVP) {
1340
		if (lvp != NULLVP) {
1317
			struct vattr va;
1341
			struct vattr va;
Lines 1347-1359 Link Here
1347
	}
1371
	}
1348
	return error;
1372
	return error;
1349
}
1373
}
1374
#endif
1350
1375
1376
#ifdef NEED_BAD_HACK
1351
static int
1377
static int
1352
union_modevent(module_t mod, int type, void *data)
1378
union_modevent(module_t mod, int type, void *data)
1353
{
1379
{
1354
	switch (type) {
1380
	switch (type) {
1355
	case MOD_LOAD:
1381
	case MOD_LOAD:
1356
		union_dircheckp = union_dircheck;
1382
		union_dircheckp = union_dircheck; 
1357
		break;
1383
		break;
1358
	case MOD_UNLOAD:
1384
	case MOD_UNLOAD:
1359
		union_dircheckp = NULL;
1385
		union_dircheckp = NULL;
Lines 1371-1373 Link Here
1371
};
1397
};
1372
1398
1373
DECLARE_MODULE(union_dircheck, union_mod, SI_SUB_VFS, SI_ORDER_ANY);
1399
DECLARE_MODULE(union_dircheck, union_mod, SI_SUB_VFS, SI_ORDER_ANY);
1400
#endif
(-)src/sys/miscfs/union/union_vfsops.c (-3 / +33 lines)
Lines 407-413 Link Here
407
		VREF(um->um_lowervp);
412
		VREF(um->um_lowervp);
408
413
409
	error = union_allocvp(vpp, mp, NULLVP, NULLVP, NULL, 
414
	error = union_allocvp(vpp, mp, NULLVP, NULLVP, NULL, 
410
		    um->um_uppervp, um->um_lowervp, 1);
415
		    um->um_uppervp, um->um_lowervp, DOCACHE);
411
	UDEBUG(("error %d\n", error));
416
	UDEBUG(("error %d\n", error));
412
	UDEBUG(("union_root2 UPPERVP %p locked = %d\n", um->um_uppervp,
417
	UDEBUG(("union_root2 UPPERVP %p locked = %d\n", um->um_uppervp,
413
	    VOP_ISLOCKED(um->um_uppervp, NULL)));
418
	    VOP_ISLOCKED(um->um_uppervp, NULL)));
Lines 415-420 Link Here
415
	return (error);
420
	return (error);
416
}
421
}
417
422
423
static void union_statfs_copy( struct statfs *sbp, struct statfs *mstat, struct statfs *main ) {
424
	sbp->f_bsize = mstat->f_bsize;
425
        sbp->f_blocks = mstat->f_blocks;
426
        sbp->f_bfree = mstat->f_bfree;
427
        sbp->f_bavail = mstat->f_bavail;
428
        sbp->f_files = mstat->f_files;
429
        sbp->f_ffree = mstat->f_ffree;
430
        sbp->f_flags = mstat->f_flags;
431
        sbp->f_iosize = mstat->f_iosize;
432
        if (sbp != main) {
433
                sbp->f_type = main->f_type;
434
                bcopy(&main->f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
435
                bcopy(&main->f_mntonname, sbp->f_mntonname, MNAMELEN);
436
                bcopy(&main->f_mntfromname, sbp->f_mntfromname, MNAMELEN);
437
        }
438
}
418
static int
439
static int
419
union_statfs(mp, sbp, p)
440
union_statfs(mp, sbp, p)
420
	struct mount *mp;
441
	struct mount *mp;
Lines 432-440 Link Here
432
	bzero(&mstat, sizeof(mstat));
453
	bzero(&mstat, sizeof(mstat));
433
454
434
	if (um->um_lowervp) {
455
	if (um->um_lowervp) {
456
		if( um->um_lowervp->v_mount == um->um_uppervp->v_mount ) {
457
			error = VFS_STATFS(um->um_uppervp->v_mount, &mstat, p);
458
			union_statfs_copy(sbp, &mstat, &mp->mnt_stat);
459
			return error;
460
		}
435
		error = VFS_STATFS(um->um_lowervp->v_mount, &mstat, p);
461
		error = VFS_STATFS(um->um_lowervp->v_mount, &mstat, p);
436
		if (error)
462
/*uprintf("Lowrvp fsstat return %d\n", error);*/
437
			return (error);
463
		if (error) {
464
			error = VFS_STATFS(um->um_uppervp->v_mount, &mstat, p);
465
			union_statfs_copy(sbp, &mstat, &mp->mnt_stat);
466
			return error;
467
		}
468
	} else {
469
		error = VFS_STATFS(um->um_uppervp->v_mount, &mstat, p);
470
		union_statfs_copy(sbp, &mstat, &mp->mnt_stat);
471
		return error;
438
	}
472
	}
439
473
440
	/* now copy across the "interesting" information and fake the rest */
474
	/* now copy across the "interesting" information and fake the rest */
Lines 452-457 Link Here
452
	sbp->f_ffree = mstat.f_ffree;
486
	sbp->f_ffree = mstat.f_ffree;
453
487
454
	error = VFS_STATFS(um->um_uppervp->v_mount, &mstat, p);
488
	error = VFS_STATFS(um->um_uppervp->v_mount, &mstat, p);
489
/*uprintf("Uppervp fsstat return %d\n", error); */
455
	if (error)
490
	if (error)
456
		return (error);
491
		return (error);
457
492
(-)src/sys/miscfs/union/union_vnops.c (-13 / +103 lines)
Lines 275-280 Link Here
275
	return (0);
275
	return (0);
276
}
276
}
277
277
278
#define NOOPEN_LOWER 0
279
278
static int
280
static int
279
union_lookup(ap)
281
union_lookup(ap)
280
	struct vop_lookup_args /* {
282
	struct vop_lookup_args /* {
Lines 300-305 Link Here
300
302
301
	*ap->a_vpp = NULLVP;
303
	*ap->a_vpp = NULLVP;
302
304
305
/*if ((cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
306
printf("lookup: [%.*s] for %d\ncnp->cn_consume = %d\n",cnp->cn_namelen,cnp->cn_nameptr,cnp->cn_nameiop,cnp->cn_consume);
307
}*/
303
	/*
308
	/*
304
	 * Disallow write attemps to the filesystem mounted read-only.
309
	 * Disallow write attemps to the filesystem mounted read-only.
305
	 */
310
	 */
Lines 367-373 Link Here
367
		    (uppervp ? uppervp->v_usecount : -99),
372
		    (uppervp ? uppervp->v_usecount : -99),
368
		    (uppervp ? VOP_ISLOCKED(uppervp, NULL) : -99)
373
		    (uppervp ? VOP_ISLOCKED(uppervp, NULL) : -99)
369
		));
374
		));
370
375
/*
376
                if(uerror == EACCES) {
377
                        error = uerror;
378
                        goto out;
379
                }
380
*/
371
		/*
381
		/*
372
		 * Disallow write attemps to the filesystem mounted read-only.
382
		 * Disallow write attemps to the filesystem mounted read-only.
373
		 */
383
		 */
Lines 538-546 Link Here
538
		VOP_UNLOCK(lowervp, 0, p);
548
		VOP_UNLOCK(lowervp, 0, p);
539
	if (upperdvp)
549
	if (upperdvp)
540
		VOP_UNLOCK(upperdvp, 0, p);
550
		VOP_UNLOCK(upperdvp, 0, p);
541
551
/*
542
	error = union_allocvp(ap->a_vpp, dvp->v_mount, dvp, upperdvp, cnp,
552
printf("lookup_end: [%.*s] for %d\n",cnp->cn_namelen,cnp->cn_nameptr,cnp->cn_nameiop);
543
			      uppervp, lowervp, 1);
553
*/
554
	{
555
		struct vnode *tmp;
556
		tmp = (uppervp != NULL) ? uppervp : lowervp;
557
/*
558
printf("vnode = %p\ncnp->cn_nameiop = %d, cnp->cn_name = %.*s, type = %d\nv_usecount = %d\n",
559
	tmp,
560
        cnp->cn_nameiop, cnp->cn_namelen, cnp->cn_nameptr, tmp->v_type,
561
	tmp->v_usecount);
562
*/
563
		if( (cnp->cn_nameiop == LOOKUP &&
564
		     (
565
#if NOOPEN_LOWER
566
		     tmp->v_type != VREG &&
567
#endif
568
		     tmp->v_type != VDIR &&
569
		     tmp->v_type != VLNK)
570
                    )
571
#if NOOPEN_LOWER
572
		     ||
573
		    (tmp->v_type == VREG && (uppervp != NULL) && (
574
		     cnp->cn_nameiop == LOOKUP || cnp->cn_nameiop == CREATE))
575
#endif
576
		   ){
577
			*(ap->a_vpp) = tmp;
578
                        if(uppervp && lowervp) {
579
                                vput(lowervp);
580
                                lowervp = 0;
581
                        }
582
                        if (upperdvp) {
583
                                if (upperdvp == tmp) {
584
                                        vrele(upperdvp);
585
                                } else {
586
                                        vput(upperdvp);
587
                                }
588
                                upperdvp = NULL;
589
                        }
590
			error = 0;
591
		}else{
592
			error = union_allocvp(ap->a_vpp, dvp->v_mount,
593
				              dvp, upperdvp, cnp,
594
				              uppervp, lowervp, 1);
595
		}
596
	}
544
597
545
	UDEBUG(("Create %p = %p %p refs=%d\n", *ap->a_vpp, uppervp, lowervp, (*ap->a_vpp) ? ((*ap->a_vpp)->v_usecount) : -99));
598
	UDEBUG(("Create %p = %p %p refs=%d\n", *ap->a_vpp, uppervp, lowervp, (*ap->a_vpp) ? ((*ap->a_vpp)->v_usecount) : -99));
546
599
Lines 612-618 Link Here
612
	if (cnp->cn_namelen == 1 &&
665
	if (cnp->cn_namelen == 1 &&
613
	    cnp->cn_nameptr[0] == '.' &&
666
	    cnp->cn_nameptr[0] == '.' &&
614
	    *ap->a_vpp != dvp) {
667
	    *ap->a_vpp != dvp) {
615
		panic("union_lookup returning . (%p) not same as startdir (%p)", ap->a_vpp, dvp);
668
		/*panic("union_lookup returning . (%p) not same as startdir (%p)", *ap->a_vpp, dvp);*/
669
		printf("union_lookup returning . (%p) not same as startdir (%p). error = %d\n", *ap->a_vpp, dvp, error);
616
	}
670
	}
617
#endif
671
#endif
618
672
Lines 642-647 Link Here
642
	int error = EROFS;
696
	int error = EROFS;
643
697
644
	if ((dvp = union_lock_upper(dun, p)) != NULL) {
698
	if ((dvp = union_lock_upper(dun, p)) != NULL) {
699
#if	1
700
		error = VOP_CREATE(dvp, ap->a_vpp, cnp, ap->a_vap);
701
#else
645
		struct vnode *vp;
702
		struct vnode *vp;
646
		struct mount *mp;
703
		struct mount *mp;
647
704
Lines 654-659 Link Here
654
				cnp, vp, NULLVP, 1);
711
				cnp, vp, NULLVP, 1);
655
			UDEBUG(("ALLOCVP-2B FROM %p REFS %d\n", *ap->a_vpp, vp->v_usecount));
712
			UDEBUG(("ALLOCVP-2B FROM %p REFS %d\n", *ap->a_vpp, vp->v_usecount));
656
		}
713
		}
714
#endif
657
		union_unlock_upper(dvp, p);
715
		union_unlock_upper(dvp, p);
658
	}
716
	}
659
	return (error);
717
	return (error);
Lines 672-677 Link Here
672
	struct vnode *uppervp;
730
	struct vnode *uppervp;
673
	int error = EOPNOTSUPP;
731
	int error = EOPNOTSUPP;
674
732
733
	if (cnp == NULL) {
734
		return 0;
735
	}
736
675
	if ((uppervp = union_lock_upper(un, cnp->cn_proc)) != NULLVP) {
737
	if ((uppervp = union_lock_upper(un, cnp->cn_proc)) != NULLVP) {
676
		error = VOP_WHITEOUT(un->un_uppervp, cnp, ap->a_flags);
738
		error = VOP_WHITEOUT(un->un_uppervp, cnp, ap->a_flags);
677
		union_unlock_upper(uppervp, cnp->cn_proc);
739
		union_unlock_upper(uppervp, cnp->cn_proc);
Lines 1101-1108 Link Here
1101
	struct vnode *uppervp;
1163
	struct vnode *uppervp;
1102
	int error;
1164
	int error;
1103
1165
1104
	if ((uppervp = union_lock_upper(un, p)) == NULLVP)
1166
	if ((uppervp = union_lock_upper(un, p)) == NULLVP) {
1167
		printf("un_uppervp: %x\n", un->un_uppervp);
1105
		panic("union: missing upper layer in write");
1168
		panic("union: missing upper layer in write");
1169
	}
1106
1170
1107
	/*
1171
	/*
1108
	 * Since our VM pages are associated with our vnode rather then
1172
	 * Since our VM pages are associated with our vnode rather then
Lines 1318-1324 Link Here
1318
1382
1319
		if (tun->un_uppervp == NULLVP) {
1383
		if (tun->un_uppervp == NULLVP) {
1320
			vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p);
1384
			vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p);
1321
#if 0
1385
#if UPPERLOCK
1322
			if (dun->un_uppervp == tun->un_dirvp) {
1386
			if (dun->un_uppervp == tun->un_dirvp) {
1323
				if (dun->un_flags & UN_ULOCK) {
1387
				if (dun->un_flags & UN_ULOCK) {
1324
					dun->un_flags &= ~UN_ULOCK;
1388
					dun->un_flags &= ~UN_ULOCK;
Lines 1327-1333 Link Here
1327
			}
1391
			}
1328
#endif
1392
#endif
1329
			error = union_copyup(tun, 1, cnp->cn_cred, p);
1393
			error = union_copyup(tun, 1, cnp->cn_cred, p);
1330
#if 0
1394
#if UPPERLOCK
1331
			if (dun->un_uppervp == tun->un_dirvp) {
1395
			if (dun->un_uppervp == tun->un_dirvp) {
1332
				vn_lock(dun->un_uppervp,
1396
				vn_lock(dun->un_uppervp,
1333
					    LK_EXCLUSIVE | LK_RETRY, p);
1397
					    LK_EXCLUSIVE | LK_RETRY, p);
Lines 1647-1658 Link Here
1647
	struct proc *p = ap->a_uio->uio_procp;
1711
	struct proc *p = ap->a_uio->uio_procp;
1648
	struct vnode *uvp;
1712
	struct vnode *uvp;
1649
	int error = 0;
1713
	int error = 0;
1714
	int save_resid;
1650
1715
1651
	if ((uvp = union_lock_upper(un, p)) != NULLVP) {
1716
	if ((un->un_uppersz == VNOVAL || un->un_uppersz >= ap->a_uio->uio_offset) && (uvp = union_lock_upper(un, p)) != NULLVP) {
1717
/*uprintf("readdir un->un_uppersz = %d ap->a_uio->uio_offset = %d\n", un->un_uppersz, ap->a_uio->uio_offset);*/
1652
		ap->a_vp = uvp;
1718
		ap->a_vp = uvp;
1719
		save_resid = ap->a_uio->uio_resid;
1653
		error = VCALL(uvp, VOFFSET(vop_readdir), ap);
1720
		error = VCALL(uvp, VOFFSET(vop_readdir), ap);
1721
		if(error) {
1722
			return(error);
1723
		}
1654
		union_unlock_upper(uvp, p);
1724
		union_unlock_upper(uvp, p);
1725
		if(un->un_uppersz == VNOVAL || ap->a_uio->uio_offset > un->un_uppersz) {
1726
			un->un_uppersz = ap->a_uio->uio_offset;
1727
		}
1728
		if(ap->a_uio->uio_resid == save_resid) {
1729
			un->un_uppersz = ap->a_uio->uio_offset;
1730
		} else {
1731
			return(0);
1732
		}
1655
	}
1733
	}
1734
	if ((uvp = un->un_lowervp)) {
1735
		ap->a_uio->uio_offset -= un->un_uppersz;
1736
		ap->a_vp = uvp;
1737
		VREF(uvp);
1738
                vn_lock(uvp, LK_EXCLUSIVE | LK_CANRECURSE | LK_RETRY, p);
1739
                error = VCALL(uvp, VOFFSET(vop_readdir), ap);
1740
		vput(uvp);
1741
		ap->a_uio->uio_offset += un->un_uppersz;
1742
	}
1656
	return(error);
1743
	return(error);
1657
}
1744
}
1658
1745
Lines 1718-1724 Link Here
1718
		un->un_dircache = 0;
1805
		un->un_dircache = 0;
1719
	}
1806
	}
1720
1807
1721
#if 0
1808
#if UPPERLOCK
1722
	if ((un->un_flags & UN_ULOCK) && un->un_uppervp) {
1809
	if ((un->un_flags & UN_ULOCK) && un->un_uppervp) {
1723
		un->un_flags &= ~UN_ULOCK;
1810
		un->un_flags &= ~UN_ULOCK;
1724
		VOP_UNLOCK(un->un_uppervp, 0, p);
1811
		VOP_UNLOCK(un->un_uppervp, 0, p);
Lines 1748-1754 Link Here
1748
union_lock(ap)
1835
union_lock(ap)
1749
	struct vop_lock_args *ap;
1836
	struct vop_lock_args *ap;
1750
{
1837
{
1751
#if 0
1838
#if UPPERLOCK
1752
	struct vnode *vp = ap->a_vp;
1839
	struct vnode *vp = ap->a_vp;
1753
	struct proc *p = ap->a_p;
1840
	struct proc *p = ap->a_p;
1754
	int flags = ap->a_flags;
1841
	int flags = ap->a_flags;
Lines 1757-1763 Link Here
1757
	int error;
1844
	int error;
1758
1845
1759
	error = vop_stdlock(ap);
1846
	error = vop_stdlock(ap);
1760
#if 0
1847
#if UPPERLOCK
1761
	un = VTOUNION(vp);
1848
	un = VTOUNION(vp);
1762
1849
1763
	if (error == 0) {
1850
	if (error == 0) {
Lines 1800-1810 Link Here
1800
{
1887
{
1801
	struct union_node *un = VTOUNION(ap->a_vp);
1888
	struct union_node *un = VTOUNION(ap->a_vp);
1802
	int error;
1889
	int error;
1890
#if UPPERLOCK
1891
        struct proc *p = ap->a_p;
1892
#endif
1803
1893
1804
	KASSERT((un->un_uppervp == NULL || un->un_uppervp->v_usecount > 0), ("uppervp usecount is 0"));
1894
	KASSERT((un->un_uppervp == NULL || un->un_uppervp->v_usecount > 0), ("uppervp usecount is 0"));
1805
1895
1806
	error = vop_stdunlock(ap);
1896
	error = vop_stdunlock(ap);
1807
#if 0
1897
#if UPPERLOCK
1808
1898
1809
	/*
1899
	/*
1810
	 * If no exclusive locks remain and we are holding an uppervp lock,
1900
	 * If no exclusive locks remain and we are holding an uppervp lock,

Return to bug 27250