View | Details | Raw Unified | Return to bug 275871 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/fs/unionfs/union_vnops.c (-83 / +78 lines)
Lines 300-326 unionfs_lookup(struct vop_cachedlookup_args *ap) Link Here
300
			error = lerror;
300
			error = lerror;
301
		if (error != 0)
301
		if (error != 0)
302
			goto unionfs_lookup_cleanup;
302
			goto unionfs_lookup_cleanup;
303
		/*
303
		error = unionfs_nodeget(dvp->v_mount, uvp, lvp,
304
		 * get socket vnode.
304
		    dvp, &vp, cnp);
305
		 */
306
		if (uvp != NULLVP && uvp->v_type == VSOCK) {
307
			vp = uvp;
308
			vref(vp);
309
			if (cnp->cn_lkflags & LK_TYPE_MASK)
310
				vn_lock(vp, cnp->cn_lkflags | LK_RETRY);
311
		}
312
		else if (lvp != NULLVP && lvp->v_type == VSOCK) {
313
			vp = lvp;
314
			vref(vp);
315
			if (cnp->cn_lkflags & LK_TYPE_MASK)
316
				vn_lock(vp, cnp->cn_lkflags | LK_RETRY);
317
		}
318
		/*
319
		 * get unionfs vnode.
320
		 */
321
		else
322
			error = unionfs_nodeget(dvp->v_mount, uvp, lvp,
323
			    dvp, &vp, cnp);
324
		if (error != 0) {
305
		if (error != 0) {
325
			UNIONFSDEBUG(
306
			UNIONFSDEBUG(
326
			    "unionfs_lookup: Unable to create unionfs vnode.");
307
			    "unionfs_lookup: Unable to create unionfs vnode.");
Lines 333-339 unionfs_lookup(struct vop_cachedlookup_args *ap) Link Here
333
314
334
	*(ap->a_vpp) = vp;
315
	*(ap->a_vpp) = vp;
335
316
336
	if ((cnflags & MAKEENTRY) && vp->v_type != VSOCK)
317
	if (cnflags & MAKEENTRY)
337
		cache_enter(dvp, vp, cnp);
318
		cache_enter(dvp, vp, cnp);
338
319
339
unionfs_lookup_cleanup:
320
unionfs_lookup_cleanup:
Lines 375-388 unionfs_create(struct vop_create_args *ap) Link Here
375
		if (error != 0)
356
		if (error != 0)
376
			goto unionfs_create_abort;
357
			goto unionfs_create_abort;
377
358
378
		if (vp->v_type == VSOCK)
359
		VOP_UNLOCK(vp);
379
			*(ap->a_vpp) = vp;
360
		error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP,
380
		else {
361
		    ap->a_dvp, ap->a_vpp, cnp);
381
			VOP_UNLOCK(vp);
362
		vrele(vp);
382
			error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP,
383
			    ap->a_dvp, ap->a_vpp, cnp);
384
			vrele(vp);
385
		}
386
	}
363
	}
387
364
388
unionfs_create_abort:
365
unionfs_create_abort:
Lines 449-462 unionfs_mknod(struct vop_mknod_args *ap) Link Here
449
		if (error != 0)
426
		if (error != 0)
450
			goto unionfs_mknod_abort;
427
			goto unionfs_mknod_abort;
451
428
452
		if (vp->v_type == VSOCK)
429
		VOP_UNLOCK(vp);
453
			*(ap->a_vpp) = vp;
430
		error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP,
454
		else {
431
		    ap->a_dvp, ap->a_vpp, cnp);
455
			VOP_UNLOCK(vp);
432
		vrele(vp);
456
			error = unionfs_nodeget(ap->a_dvp->v_mount, vp, NULLVP,
457
			    ap->a_dvp, ap->a_vpp, cnp);
458
			vrele(vp);
459
		}
460
	}
433
	}
461
434
462
unionfs_mknod_abort:
435
unionfs_mknod_abort:
Lines 1024-1032 unionfs_remove(struct vop_remove_args *ap) Link Here
1024
	struct vnode   *udvp;
997
	struct vnode   *udvp;
1025
	struct vnode   *uvp;
998
	struct vnode   *uvp;
1026
	struct vnode   *lvp;
999
	struct vnode   *lvp;
1027
	struct vnode   *vp;
1028
	struct componentname *cnp;
1000
	struct componentname *cnp;
1029
	struct componentname cn;
1030
	struct thread  *td;
1001
	struct thread  *td;
1031
	int		error;
1002
	int		error;
1032
	int		pathlen;
1003
	int		pathlen;
Lines 1041-1094 unionfs_remove(struct vop_remove_args *ap) Link Here
1041
	cnp = ap->a_cnp;
1012
	cnp = ap->a_cnp;
1042
	td = curthread;
1013
	td = curthread;
1043
1014
1044
	if (ap->a_vp->v_op != &unionfs_vnodeops) {
1015
	ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
1045
		if (ap->a_vp->v_type != VSOCK)
1016
	unp = VTOUNIONFS(ap->a_vp);
1046
			return (EINVAL);
1017
	uvp = unp->un_uppervp;
1047
		ump = NULL;
1018
	lvp = unp->un_lowervp;
1048
		vp = uvp = lvp = NULLVP;
1019
	path = unp->un_path;
1049
		/* search vnode */
1020
	pathlen = unp->un_pathlen;
1050
		VOP_UNLOCK(ap->a_vp);
1051
		error = unionfs_relookup(udvp, &vp, cnp, &cn, td,
1052
		    cnp->cn_nameptr, cnp->cn_namelen, DELETE);
1053
		if (error != 0 && error != ENOENT) {
1054
			vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
1055
			return (error);
1056
		}
1057
1058
		if (error == 0 && vp == ap->a_vp) {
1059
			/* target vnode in upper */
1060
			uvp = vp;
1061
			vrele(vp);
1062
		} else {
1063
			/* target vnode in lower */
1064
			if (vp != NULLVP) {
1065
				if (udvp == vp)
1066
					vrele(vp);
1067
				else
1068
					vput(vp);
1069
			}
1070
			vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
1071
			lvp = ap->a_vp;
1072
		}
1073
		path = cnp->cn_nameptr;
1074
		pathlen = cnp->cn_namelen;
1075
	} else {
1076
		ump = MOUNTTOUNIONFSMOUNT(ap->a_vp->v_mount);
1077
		unp = VTOUNIONFS(ap->a_vp);
1078
		uvp = unp->un_uppervp;
1079
		lvp = unp->un_lowervp;
1080
		path = unp->un_path;
1081
		pathlen = unp->un_pathlen;
1082
	}
1083
1021
1084
	if (udvp == NULLVP)
1022
	if (udvp == NULLVP)
1085
		return (EROFS);
1023
		return (EROFS);
1086
1024
1087
	if (uvp != NULLVP) {
1025
	if (uvp != NULLVP) {
1088
		/*
1089
		 * XXX: if the vnode type is VSOCK, it will create whiteout
1090
		 *      after remove.
1091
		 */
1092
		if (ump == NULL || ump->um_whitemode == UNIONFS_WHITE_ALWAYS ||
1026
		if (ump == NULL || ump->um_whitemode == UNIONFS_WHITE_ALWAYS ||
1093
		    lvp != NULLVP)
1027
		    lvp != NULLVP)
1094
			cnp->cn_flags |= DOWHITEOUT;
1028
			cnp->cn_flags |= DOWHITEOUT;
Lines 2777-2782 unionfs_unset_text(struct vop_unset_text_args *ap) Link Here
2777
	return (0);
2711
	return (0);
2778
}
2712
}
2779
2713
2714
static int
2715
unionfs_unp_bind(struct vop_unp_bind_args *ap)
2716
{
2717
	struct vnode *tvp;
2718
	struct unionfs_node *unp;
2719
2720
	ASSERT_VOP_LOCKED(ap->a_vp, __func__);
2721
	unp = VTOUNIONFS(ap->a_vp);
2722
	tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp;
2723
	VOP_UNP_BIND(tvp, ap->a_unpcb);
2724
	return (0);
2725
}
2726
2727
static int
2728
unionfs_unp_connect(struct vop_unp_connect_args *ap)
2729
{
2730
	struct vnode *tvp;
2731
	struct unionfs_node *unp;
2732
2733
	ASSERT_VOP_LOCKED(ap->a_vp, __func__);
2734
	unp = VTOUNIONFS(ap->a_vp);
2735
	tvp = unp->un_uppervp != NULL ? unp->un_uppervp : unp->un_lowervp;
2736
	VOP_UNP_CONNECT(tvp, ap->a_unpcb);
2737
	return (0);
2738
}
2739
2740
static int
2741
unionfs_unp_detach(struct vop_unp_detach_args *ap)
2742
{
2743
	struct vnode *tvp;
2744
	struct unionfs_node *unp;
2745
2746
	tvp = NULL;
2747
	/*
2748
	 * VOP_UNP_DETACH() is not guaranteed to be called with the unionfs
2749
	 * vnode locked, so we take the interlock to prevent a concurrent
2750
	 * unmount from freeing the unionfs private data.
2751
	 */
2752
	VI_LOCK(ap->a_vp);
2753
	unp = VTOUNIONFS(ap->a_vp);
2754
	if (unp != NULL) {
2755
		tvp = unp->un_uppervp != NULL ?
2756
		    unp->un_uppervp : unp->un_lowervp;
2757
		/*
2758
		 * Hold the target vnode to prevent a concurrent unionfs
2759
		 * unmount from causing it to be recycled once the interlock
2760
		 * is dropped.
2761
		 */
2762
		vholdnz(tvp);
2763
	}
2764
	VI_UNLOCK(ap->a_vp);
2765
	if (tvp != NULL) {
2766
		VOP_UNP_DETACH(tvp);
2767
		vdrop(tvp);
2768
	}
2769
	return (0);
2770
}
2771
2780
struct vop_vector unionfs_vnodeops = {
2772
struct vop_vector unionfs_vnodeops = {
2781
	.vop_default =		&default_vnodeops,
2773
	.vop_default =		&default_vnodeops,
2782
2774
Lines 2830-2834 struct vop_vector unionfs_vnodeops = { Link Here
2830
	.vop_vput_pair =	unionfs_vput_pair,
2822
	.vop_vput_pair =	unionfs_vput_pair,
2831
	.vop_set_text =		unionfs_set_text,
2823
	.vop_set_text =		unionfs_set_text,
2832
	.vop_unset_text = 	unionfs_unset_text,
2824
	.vop_unset_text = 	unionfs_unset_text,
2825
	.vop_unp_bind =		unionfs_unp_bind,
2826
	.vop_unp_connect =	unionfs_unp_connect,
2827
	.vop_unp_detach =	unionfs_unp_detach,
2833
};
2828
};
2834
VFS_VOP_VECTOR_REGISTER(unionfs_vnodeops);
2829
VFS_VOP_VECTOR_REGISTER(unionfs_vnodeops);
(-)b/sys/kern/uipc_usrreq.c (-1 / +12 lines)
Lines 622-629 uipc_bindat(int fd, struct socket *so, struct sockaddr *nam, struct thread *td) Link Here
622
	error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
622
	error = mac_vnode_check_create(td->td_ucred, nd.ni_dvp, &nd.ni_cnd,
623
	    &vattr);
623
	    &vattr);
624
#endif
624
#endif
625
	if (error == 0)
625
	if (error == 0) {
626
		/*
627
		 * The prior lookup may have left LK_SHARED in cn_lkflags,
628
		 * and VOP_CREATE technically only requires the new vnode to
629
		 * be locked shared. Most filesystems will return the new vnode
630
		 * locked exclusive regardless, but we should explicitly
631
		 * specify that here since we require it and assert to that
632
		 * effect below.
633
		 */
634
		nd.ni_cnd.cn_lkflags = (nd.ni_cnd.cn_lkflags & ~LK_TYPE_MASK) |
635
		    LK_EXCLUSIVE;
626
		error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
636
		error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
637
	}
627
	NDFREE_PNBUF(&nd);
638
	NDFREE_PNBUF(&nd);
628
	if (error) {
639
	if (error) {
629
		VOP_VPUT_PAIR(nd.ni_dvp, NULL, true);
640
		VOP_VPUT_PAIR(nd.ni_dvp, NULL, true);

Return to bug 275871