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

(-)b/sys/fs/unionfs/union.h (+2 lines)
Lines 51-56 typedef enum _unionfs_whitemode { Link Here
51
} unionfs_whitemode;
51
} unionfs_whitemode;
52
52
53
struct unionfs_mount {
53
struct unionfs_mount {
54
	struct mount   *um_lowermp;     /* MNT_REFed lower mount object */
55
	struct mount   *um_uppermp;     /* MNT_REFed upper mount object */
54
	struct vnode   *um_lowervp;	/* VREFed once */
56
	struct vnode   *um_lowervp;	/* VREFed once */
55
	struct vnode   *um_uppervp;	/* VREFed once */
57
	struct vnode   *um_uppervp;	/* VREFed once */
56
	struct vnode   *um_rootvp;	/* ROOT vnode */
58
	struct vnode   *um_rootvp;	/* ROOT vnode */
(-)b/sys/fs/unionfs/union_vfsops.c (-21 / +18 lines)
Lines 71-77 static struct vfsops unionfs_vfsops; Link Here
71
static int
71
static int
72
unionfs_domount(struct mount *mp)
72
unionfs_domount(struct mount *mp)
73
{
73
{
74
	struct mount   *lowermp, *uppermp;
75
	struct vnode   *lowerrootvp;
74
	struct vnode   *lowerrootvp;
76
	struct vnode   *upperrootvp;
75
	struct vnode   *upperrootvp;
77
	struct unionfs_mount *ump;
76
	struct unionfs_mount *ump;
Lines 303-320 unionfs_domount(struct mount *mp) Link Here
303
	 * reused until that happens.  We assume the caller holds a reference
302
	 * reused until that happens.  We assume the caller holds a reference
304
	 * to lowerrootvp as it is the mount's covered vnode.
303
	 * to lowerrootvp as it is the mount's covered vnode.
305
	 */
304
	 */
306
	lowermp = vfs_register_upper_from_vp(ump->um_lowervp, mp,
305
	ump->um_lowermp = vfs_register_upper_from_vp(ump->um_lowervp, mp,
307
	    &ump->um_lower_link);
306
	    &ump->um_lower_link);
308
	uppermp = vfs_register_upper_from_vp(ump->um_uppervp, mp,
307
	ump->um_uppermp = vfs_register_upper_from_vp(ump->um_uppervp, mp,
309
	    &ump->um_upper_link);
308
	    &ump->um_upper_link);
310
309
311
	vrele(upperrootvp);
310
	vrele(upperrootvp);
312
311
313
	if (lowermp == NULL || uppermp == NULL) {
312
	if (ump->um_lowermp == NULL || ump->um_uppermp == NULL) {
314
		if (lowermp != NULL)
313
		if (ump->um_lowermp != NULL)
315
			vfs_unregister_upper(lowermp, &ump->um_lower_link);
314
			vfs_unregister_upper(ump->um_lowermp, &ump->um_lower_link);
316
		if (uppermp != NULL)
315
		if (ump->um_uppermp != NULL)
317
			vfs_unregister_upper(uppermp, &ump->um_upper_link);
316
			vfs_unregister_upper(ump->um_uppermp, &ump->um_upper_link);
318
		vflush(mp, 1, FORCECLOSE, curthread);
317
		vflush(mp, 1, FORCECLOSE, curthread);
319
		free(ump, M_UNIONFSMNT);
318
		free(ump, M_UNIONFSMNT);
320
		mp->mnt_data = NULL;
319
		mp->mnt_data = NULL;
Lines 346-353 unionfs_domount(struct mount *mp) Link Here
346
	}
345
	}
347
346
348
	MNT_ILOCK(mp);
347
	MNT_ILOCK(mp);
349
	if ((lowermp->mnt_flag & MNT_LOCAL) != 0 &&
348
	if ((ump->um_lowermp->mnt_flag & MNT_LOCAL) != 0 &&
350
	    (uppermp->mnt_flag & MNT_LOCAL) != 0)
349
	    (ump->um_uppermp->mnt_flag & MNT_LOCAL) != 0)
351
		mp->mnt_flag |= MNT_LOCAL;
350
		mp->mnt_flag |= MNT_LOCAL;
352
	mp->mnt_kern_flag |= MNTK_NOMSYNC | MNTK_UNIONFS;
351
	mp->mnt_kern_flag |= MNTK_NOMSYNC | MNTK_UNIONFS;
353
	MNT_IUNLOCK(mp);
352
	MNT_IUNLOCK(mp);
Lines 400-407 unionfs_unmount(struct mount *mp, int mntflags) Link Here
400
	vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
399
	vn_lock(mp->mnt_vnodecovered, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
401
	mp->mnt_vnodecovered->v_vflag &= ~VV_CROSSLOCK;
400
	mp->mnt_vnodecovered->v_vflag &= ~VV_CROSSLOCK;
402
	VOP_UNLOCK(mp->mnt_vnodecovered);
401
	VOP_UNLOCK(mp->mnt_vnodecovered);
403
	vfs_unregister_upper(ump->um_lowervp->v_mount, &ump->um_lower_link);
402
	vfs_unregister_upper(ump->um_lowermp, &ump->um_lower_link);
404
	vfs_unregister_upper(ump->um_uppervp->v_mount, &ump->um_upper_link);
403
	vfs_unregister_upper(ump->um_uppermp, &ump->um_upper_link);
405
	free(ump, M_UNIONFSMNT);
404
	free(ump, M_UNIONFSMNT);
406
	mp->mnt_data = NULL;
405
	mp->mnt_data = NULL;
407
406
Lines 433-445 static int Link Here
433
unionfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg,
432
unionfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg,
434
    bool *mp_busy)
433
    bool *mp_busy)
435
{
434
{
436
	struct mount *uppermp;
437
	struct unionfs_mount *ump;
435
	struct unionfs_mount *ump;
438
	int error;
436
	int error;
439
	bool unbusy;
437
	bool unbusy;
440
438
441
	ump = MOUNTTOUNIONFSMOUNT(mp);
439
	ump = MOUNTTOUNIONFSMOUNT(mp);
442
	uppermp = atomic_load_ptr(&ump->um_uppervp->v_mount);
443
	KASSERT(*mp_busy == true, ("upper mount not busy"));
440
	KASSERT(*mp_busy == true, ("upper mount not busy"));
444
	/*
441
	/*
445
	 * See comment in sys_quotactl() for an explanation of why the
442
	 * See comment in sys_quotactl() for an explanation of why the
Lines 452-465 unionfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg, Link Here
452
	vfs_unbusy(mp);
449
	vfs_unbusy(mp);
453
	*mp_busy = false;
450
	*mp_busy = false;
454
	unbusy = true;
451
	unbusy = true;
455
	error = vfs_busy(uppermp, 0);
452
	error = vfs_busy(ump->um_uppermp, 0);
456
	/*
453
	/*
457
	 * Writing is always performed to upper vnode.
454
	 * Writing is always performed to upper vnode.
458
	 */
455
	 */
459
	if (error == 0)
456
	if (error == 0)
460
		error = VFS_QUOTACTL(uppermp, cmd, uid, arg, &unbusy);
457
		error = VFS_QUOTACTL(ump->um_uppermp, cmd, uid, arg, &unbusy);
461
	if (unbusy)
458
	if (unbusy)
462
		vfs_unbusy(uppermp);
459
		vfs_unbusy(ump->um_uppermp);
463
460
464
	return (error);
461
	return (error);
465
}
462
}
Lines 479-485 unionfs_statfs(struct mount *mp, struct statfs *sbp) Link Here
479
476
480
	mstat = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK | M_ZERO);
477
	mstat = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK | M_ZERO);
481
478
482
	error = VFS_STATFS(ump->um_lowervp->v_mount, mstat);
479
	error = VFS_STATFS(ump->um_lowermp, mstat);
483
	if (error) {
480
	if (error) {
484
		free(mstat, M_STATFS);
481
		free(mstat, M_STATFS);
485
		return (error);
482
		return (error);
Lines 491-497 unionfs_statfs(struct mount *mp, struct statfs *sbp) Link Here
491
488
492
	lbsize = mstat->f_bsize;
489
	lbsize = mstat->f_bsize;
493
490
494
	error = VFS_STATFS(ump->um_uppervp->v_mount, mstat);
491
	error = VFS_STATFS(ump->um_uppermp, mstat);
495
	if (error) {
492
	if (error) {
496
		free(mstat, M_STATFS);
493
		free(mstat, M_STATFS);
497
		return (error);
494
		return (error);
Lines 558-567 unionfs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp, Link Here
558
	unp = VTOUNIONFS(filename_vp);
555
	unp = VTOUNIONFS(filename_vp);
559
556
560
	if (unp->un_uppervp != NULLVP) {
557
	if (unp->un_uppervp != NULLVP) {
561
		return (VFS_EXTATTRCTL(ump->um_uppervp->v_mount, cmd,
558
		return (VFS_EXTATTRCTL(ump->um_uppermp, cmd,
562
		    unp->un_uppervp, namespace, attrname));
559
		    unp->un_uppervp, namespace, attrname));
563
	} else {
560
	} else {
564
		return (VFS_EXTATTRCTL(ump->um_lowervp->v_mount, cmd,
561
		return (VFS_EXTATTRCTL(ump->um_lowermp, cmd,
565
		    unp->un_lowervp, namespace, attrname));
562
		    unp->un_lowervp, namespace, attrname));
566
	}
563
	}
567
}
564
}
(-)b/sys/fs/unionfs/union_vnops.c (-2 / +2 lines)
Lines 764-770 unionfs_access(struct vop_access_args *ap) Link Here
764
764
765
	if (lvp != NULLVP) {
765
	if (lvp != NULLVP) {
766
		if (accmode & VWRITE) {
766
		if (accmode & VWRITE) {
767
			if (ump->um_uppervp->v_mount->mnt_flag & MNT_RDONLY) {
767
			if (ump->um_uppermp->mnt_flag & MNT_RDONLY) {
768
				switch (ap->a_vp->v_type) {
768
				switch (ap->a_vp->v_type) {
769
				case VREG:
769
				case VREG:
770
				case VDIR:
770
				case VDIR:
Lines 835-841 unionfs_getattr(struct vop_getattr_args *ap) Link Here
835
835
836
	error = VOP_GETATTR(lvp, ap->a_vap, ap->a_cred);
836
	error = VOP_GETATTR(lvp, ap->a_vap, ap->a_cred);
837
837
838
	if (error == 0 && !(ump->um_uppervp->v_mount->mnt_flag & MNT_RDONLY)) {
838
	if (error == 0 && !(ump->um_uppermp->mnt_flag & MNT_RDONLY)) {
839
		/* correct the attr toward shadow file/dir. */
839
		/* correct the attr toward shadow file/dir. */
840
		if (ap->a_vp->v_type == VREG || ap->a_vp->v_type == VDIR) {
840
		if (ap->a_vp->v_type == VREG || ap->a_vp->v_type == VDIR) {
841
			unionfs_create_uppervattr_core(ump, ap->a_vap, &va, td);
841
			unionfs_create_uppervattr_core(ump, ap->a_vap, &va, td);

Return to bug 275870